This adapter integrates OpsOrch with Slack, enabling rich message delivery to Slack channels using Block Kit.
This adapter provides one capability:
- Messaging Provider: Send rich messages to Slack channels
- Rich Messaging: Supports Headers, Sections (including field sets), and Dividers via OpsOrch's generic Block model
- Markdown Support: Automatically converts standard Markdown links (
[text](url)) to Slack's format (<url|text>) - Block Kit Integration: Maps OpsOrch blocks to the subset of Slack Block Kit elements used by the adapter
- Channel Targeting: Send messages to specific channels by ID (public, private, or IM)
- Plugin Architecture: Runs as a standalone binary communicating via JSON-RPC
- Adapter Version: 0.1.0
- Requires OpsOrch Core: >=0.1.0
- Slack API: Web API
- Go Version: 1.21+
The messaging adapter requires the following configuration:
| Field | Type | Required | Description | Default |
|---|---|---|---|---|
token |
string | Yes | Slack Bot User OAuth Token (starts with xoxb-) |
- |
- Go to api.slack.com/apps
- Click Create New App
- Choose From scratch
- Give your app a name (e.g.,
OpsOrch Bot) - Select your workspace
- Click Create App
- In your app settings, go to OAuth & Permissions
- Scroll down to Scopes → Bot Token Scopes
- Click Add an OAuth Scope
- Add the following scope:
chat:write- Send messages as the bot
- In your app settings, go to OAuth & Permissions
- Click Install to Workspace
- Review the permissions and click Allow
- Copy the Bot User OAuth Token (starts with
xoxb-)
Before the bot can send messages to a channel, you must invite it:
- In Slack, go to the channel where you want to send messages
- Type
/invite @YourAppName(replace with your app name) - The bot will join the channel and can now send messages
Messages must be addressed by channel ID. To find the channel ID:
- Right-click on the channel name in Slack
- Select Copy link
- The channel ID is in the URL:
https://yourworkspace.slack.com/archives/C1234567890 - The ID is
C1234567890
JSON format:
{
"token": "xoxb-your-bot-token-here"
}Environment variables:
export OPSORCH_MESSAGING_PLUGIN=/path/to/bin/messagingplugin
export OPSORCH_MESSAGING_CONFIG='{"token":"xoxb-..."}'OpsOrch's generic Block model maps to Slack's Block Kit:
| OpsOrch Block Type | Slack Block Type | Transformation | Notes |
|---|---|---|---|
header |
header |
Direct mapping | Text limited to 150 characters |
section |
section |
Direct mapping | Supports text and fields |
divider |
divider |
Direct mapping | Visual separator |
section (with fields map) |
section with fields |
Converted to section block | Key-value pairs displayed in columns |
The adapter automatically converts standard Markdown links to Slack's format:
| Standard Markdown | Slack Format | Example |
|---|---|---|
[text](url) |
<url|text> |
[Dashboard](https://example.com) → <https://example.com|Dashboard> |
The provider returns the standard OpsOrch schema.MessageResult fields:
| Field | Type | Description |
|---|---|---|
id |
string | Slack message timestamp returned by the API |
channel |
string | Channel ID where message was sent |
sentAt |
string (RFC3339) | Timestamp recorded by the adapter when the send completed |
metadata |
object | Optional additional fields (unused by the current implementation) |
Import the adapter for side effects to register it with OpsOrch Core:
import _ "github.com/opsorch/opsorch-slack-adapter/messaging"Configure via environment variables:
export OPSORCH_MESSAGING_PROVIDER=slack
export OPSORCH_MESSAGING_CONFIG='{"token":"xoxb-..."}'Build the plugin binary:
make pluginConfigure OpsOrch Core to use the plugin:
export OPSORCH_MESSAGING_PLUGIN=/path/to/bin/messagingplugin
export OPSORCH_MESSAGING_CONFIG='{"token":"xoxb-..."}'Download pre-built plugin binaries from GitHub Releases:
FROM ghcr.io/opsorch/opsorch-core:latest
WORKDIR /opt/opsorch
# Download plugin binary
ADD https://github.com/opsorch/opsorch-slack-adapter/releases/download/v0.1.0/messagingplugin-linux-amd64 ./plugins/messagingplugin
RUN chmod +x ./plugins/messagingplugin
# Configure plugin
ENV OPSORCH_MESSAGING_PLUGIN=/opt/opsorch/plugins/messagingplugin- Go 1.21 or later
- Slack workspace with admin access
- Slack Bot User OAuth Token
# Download dependencies
go mod download
# Run unit tests
make test
# Build all packages
make build
# Build plugin binary
make plugin
# Run integration tests (requires SLACK_TOKEN and SLACK_CHANNEL)
make integUnit Tests:
make testIntegration Tests:
Integration tests send real messages to a Slack channel.
Prerequisites:
- A Slack workspace with a bot installed
- A Slack Bot User OAuth Token (
xoxb-...) - A channel ID where the bot has been invited
Setup:
# Set required environment variables
export SLACK_TOKEN="xoxb-your-bot-token"
export SLACK_CHANNEL="C1234567890" # Your channel ID
# Run integration tests
make integ
# Or run specific messaging tests
make integ-messageWhat the tests do:
- Send a test message with headers, sections, and fields to the specified channel
- Verify the message was sent successfully
- Capture message metadata (timestamp, channel ID)
Expected behavior:
- A test message will appear in your Slack channel
- The message will contain formatted blocks (header, sections, divider)
- Tests verify the Slack API returns success
Note: Integration tests send real messages to your Slack channel. Use a test channel to avoid cluttering production channels.
opsorch-slack-adapter/
├── messaging/ # Messaging provider implementation
│ ├── slack_provider.go # Core provider logic
│ └── slack_provider_test.go # Unit tests
├── cmd/
│ └── messagingplugin/ # Plugin entrypoint
│ └── main.go
├── integ/ # Integration tests
│ └── messaging.go
├── Makefile
└── README.md
Key Components:
- messaging/slack_provider.go: Implements messaging.Provider interface, handles Slack Block Kit conversion and API calls
- cmd/messagingplugin: JSON-RPC plugin wrapper for messaging provider
- integ/messaging.go: End-to-end integration tests against live Slack workspace
The repository includes GitHub Actions workflows:
- CI (
ci.yml): Runs tests and linting on every push/PR to main - Release (
release.yml): Manual workflow that:- Runs tests and linting
- Creates version tags (patch/minor/major)
- Builds multi-arch binaries (linux-amd64, linux-arm64, darwin-amd64, darwin-arm64)
- Publishes binaries as GitHub release assets
Pre-built plugin binaries are available from GitHub Releases.
Supported platforms:
- Linux (amd64, arm64)
- macOS (amd64, arm64)
OpsOrch Core communicates with the plugin over stdin/stdout using JSON-RPC.
Request:
{
"method": "messaging.send",
"config": { /* decrypted configuration */ },
"payload": { /* method-specific request body */ }
}Response:
{
"result": { /* method-specific result */ },
"error": "optional error message"
}The config field contains the decrypted configuration map from OPSORCH_MESSAGING_CONFIG. The plugin receives this on every request, so it never stores secrets on disk.
Send a message to a Slack channel.
Request:
{
"method": "messaging.send",
"config": {"token": "xoxb-..."},
"payload": {
"channel": "C1234567890",
"blocks": [
{
"type": "header",
"text": "Incident Alert"
},
{
"type": "section",
"text": "Database connection timeout detected"
},
{
"type": "section",
"fields": {
"Severity": "Critical",
"Service": "api-backend",
"Environment": "production"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": "[View Dashboard](https://dashboard.example.com)"
}
]
}
}Response:
{
"result": {
"id": "1234567890.123456",
"channel": "C1234567890",
"sentAt": "2024-01-01T12:00:00Z"
}
}{
"channel": "C1234567890",
"blocks": [
{
"type": "section",
"text": "Deployment completed successfully"
}
]
}{
"channel": "C1234567890",
"blocks": [
{
"type": "header",
"text": "🚨 Critical Incident"
},
{
"type": "section",
"text": "High error rate detected in payment service"
},
{
"type": "section",
"fields": {
"Severity": "Critical",
"Service": "payment-api",
"Error Rate": "15%",
"Started": "2024-01-01 10:00 UTC"
}
},
{
"type": "divider"
},
{
"type": "section",
"text": "[View Incident](https://incidents.example.com/123) | [View Logs](https://logs.example.com)"
}
]
}- Never log the bot token: Avoid logging the config or token in application logs
- Rotate tokens regularly: Rotate the bot token at the cadence required by your organization's security policy
- Use environment variables: Store the
OPSORCH_MESSAGING_CONFIGin a secure environment variable or secrets management system - Restrict file permissions: If storing config in files, ensure proper file permissions (e.g., 0600)
- Limit bot permissions: Only grant the
chat:writescope; avoid unnecessary permissions - Use private channels: For sensitive alerts, use private channels and carefully manage membership
Apache 2.0
See LICENSE file for details.