Slack component
The
slackcomponent posts messages to Slack channels (incoming webhook or thechat.postMessageWeb API) and reads new channel messages by pollingconversations.history.
Scheme: slack: · Crate: cameleer-saas · Cargo feature: saas ·
Consumer: yes · Producer: yes · Apache Camel: Slack
When to use it
- Post alerts, deployment notices or daily reports to a channel.
- Let an AI agent publish its summaries or answers to a team channel.
- React to messages people write in a channel (a support bot, a "deploy" keyword, a triage queue).
- Mirror a channel into another system (a ticket tracker, a database, a search index).
URI format
slack:#channel[?options]
slack://channel[?options]The channel is a name (#ops, general) or a channel id (C0123456). The producer needs
either webhookUrl or token; the consumer always needs token.
Example
Post a message with an incoming webhook. A text body becomes the message text; username
and iconEmoji are added to the webhook payload.
- route:
id: deploy-notice
from:
uri: "timer:deploy-notice?repeatCount=1"
steps:
- setBody:
constant: "Deployment of checkout v42 finished"
- to: "slack:#ops?webhookUrl={{env:SLACK_WEBHOOK_URL}}&username=cameleer&iconEmoji=:rocket:"An AI agent that summarises an incident report with an LLM and posts the summary through the
Web API (chat.postMessage with a bot token). The Web API response is kept in the
CamelSlackResponse header.
- route:
id: incident-summary-to-slack
from:
uri: "direct:incident-report"
steps:
- to: "openai:chat-completion?model={{env:OPENAI_MODEL:gpt-4o-mini}}&baseUrl={{env:OPENAI_BASE_URL:https://api.openai.com/v1}}&apiKey={{env:OPENAI_API_KEY}}&temperature=0&systemMessage=Summarise this incident report in two sentences for the on-call channel."
- setBody:
simple: ":memo: ${body}"
- to: "slack:#general?token={{env:SLACK_TOKEN}}&serverUrl={{env:SLACK_API_URL:https://slack.com}}"
- log: "posted to Slack at ts ${header.CamelSlackResponse[ts]}"Read new messages from #general. Each message becomes one exchange whose body is the Slack
message object (text, user, ts, ...). The first poll delivers the latest maxResults
messages; later polls deliver only newer ones.
- route:
id: read-general
from:
uri: "slack://general?token={{env:SLACK_TOKEN}}&serverUrl={{env:SLACK_API_URL:https://slack.com}}&maxResults=20&naturalOrder=true&delay=5000"
steps:
- filter:
simple: "${body[text]} contains 'deploy'"
steps:
- setBody:
simple: "${body[user]} asked: ${body[text]}"
- to: "log:slack-deploy-requests"Rust DSL
ctx.add_routes(|b| {
b.from("timer:deploy-notice?repeatCount=1")
.set_body(constant("Deployment of checkout v42 finished"))
.to("slack:#ops?webhookUrl={{env:SLACK_WEBHOOK_URL}}&username=cameleer&iconEmoji=:rocket:");
})?;Options
| option | default | description |
|---|---|---|
webhookUrl | Incoming webhook URL. When set, the producer posts to the webhook. | |
token | Bot or user token (xoxb-...). Producer: chat.postMessage. Required by the consumer. | |
username | Display name added to webhook payloads. | |
iconUrl | Icon URL added to webhook payloads (icon_url). | |
iconEmoji | Icon emoji added to webhook payloads (icon_emoji), e.g. :rocket:. | |
maxResults | 10 | Consumer: messages fetched per poll (limit). |
naturalOrder | false | Consumer: deliver the oldest message first (Slack returns newest first). |
conversationType | PUBLIC_CHANNEL | Consumer: channel type used to resolve the name: PUBLIC_CHANNEL, PRIVATE_CHANNEL, MPIM, IM. |
serverUrl | https://slack.com | Web API base URL (Cameleer extension: a proxy, a gateway or a test server). |
delay, initialDelay, ... | delay=10000 | Consumer: the standard scheduled-poll options. |
Message headers
| header | direction | description |
|---|---|---|
CamelSlackResponse | out (producer) | The Web API response of chat.postMessage (ok, channel, ts). Not set for webhooks. |
The message body decides the payload: a text body is the message text; a map body is sent as
the whole payload (blocks, attachments, thread_ts, ...; channel is added when missing).
Run it with Docker
export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
docker run --rm -e SLACK_WEBHOOK_URL -v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/deploy-notice.camel.yamlCommon questions
Webhook or token: which one should I use?
A webhook is the simplest: one URL, one channel, no scopes. Use a bot token (chat:write
scope, plus channels:history and channels:read for the consumer) when you need to post to
several channels, read messages, or get the message ts back for threads.
How do I send blocks or reply in a thread?
Make the body a map, for example with unmarshal: json on a JSON string such as
{"text":"fallback","thread_ts":"1700000001.000100","blocks":[...]}. Map bodies are sent as the
payload unchanged.
What happens when Slack rejects the message?
With a token, a response with "ok": false fails the exchange with an ApiException whose
message is the Slack error (Slack: channel_not_found). With a webhook, a non-2xx response fails
with HttpOperationFailedException. Use onException or errorHandler to retry.
Is Slack's Socket Mode or Events API supported?
No. The consumer polls conversations.history. For push delivery, expose an HTTP endpoint with
platform-http and point a Slack event subscription at it.
Related
- openai for LLM summaries before posting, and the AI components guide
- jira, github, telegram
- Filter EIP
- Apache Camel Slack component
Found a problem?
If something on this page doesn't match what Cameleer does, or you hit a bug while building
with it, please help fix it, whether you are a person or a coding agent:
open an issue that describes what you saw,
then fork the repository, fix it, add or update a test, run cargo test --workspace, and open
a pull request. CONTRIBUTING.md
explains the ground rules.