Slack
Bot token 模式可解鎖完整的 Slack Web API(流式傳輸、文件、表情、臨時消息、定時消息)。Webhook 模式是單 URL 備選方案,支持純文本、Block Kit 塊和線程回覆。
🟢 運行時就緒,根據已設置的環境變量自動選擇兩種模式。推薦使用 bot token 模式處理非簡單場景;webhook 模式作為單 URL 備選,支持文本、Block Kit 塊和線程回覆,但不支持流式傳輸、附件、表情、臨時消息、定時消息或
metadata字段。
選擇模式
| 模式 | 環境變量 | 流式傳輸 | 附件 | 線程 | 表情 | Block Kit | 臨時/定時/Metadata | 入站 | 適用場景 |
|---|---|---|---|---|---|---|---|---|---|
| Bot token (推薦) | SLACK_BOT_TOKEN + SLACK_CHANNEL_ID | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 全功能集成、多頻道路由、入站監聽 |
| Webhook (無 Slack 應用備選) | SLACK_WEBHOOK_URL | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | 純文本、Block Kit、線程回覆,無需 Slack 應用審批 |
Webhook 模式的能力邊界: 根據 Slack 的 Incoming Webhooks 文檔,webhook URL 在 JSON 請求體中接受 text、blocks、thread_ts、mrkdwn、unfurl_links 和 unfurl_media。不支持編輯端點(無流式傳輸)、files.upload(無附件)、reactions.add、chat.postEphemeral、chat.scheduleMessage 以及 metadata,這些均為僅限 bot token 的 Slack Web API 方法。這不是 Minara 的限制,任何 Slack SDK 都無法繞過此約束。
兩組環境變量同時存在時的優先級: Minara 優先選擇 bot 模式(SLACK_BOT_TOKEN + SLACK_CHANNEL_ID)。僅當 bot 憑據缺失或不完整時才使用 webhook。移除任一 bot 環境變量即可回退至 webhook 模式。
配置:Bot token 模式(推薦)
1. 創建 bot
- 打開 api.slack.com/apps → Create New App → From scratch → 命名為 "Minara" → 選擇你的工作區
- 在 OAuth & Permissions 下,添加以下 Bot Token Scopes:
chat:write,chat.postMessage/chat.postEphemeral/chat.scheduleMessage必需chat:write.public,向 bot 未受邀的頻道發送消息必需files:write,通過files.v2上傳附件必需reactions:write,add_reaction工具必需
- 點擊頂部的 Install to Workspace,複製 Bot User OAuth Token(以
xoxb-開頭)
2. 獲取頻道 ID
在 Slack 客戶端中:點擊頻道名稱 → 滾動到底部 → 複製 Channel ID(如 C0123ABC)。
3. 配置 Minara
確保項目根目錄的 .env 文件中 SLACK_WEBHOOK_URL 未設置(保留也可以,bot 模式優先級更高,但移除後更清晰)。然後:
SLACK_BOT_TOKEN=xoxb-...
SLACK_CHANNEL_ID=C0123ABC4. 測試
minara auth messaging test slack配置:Webhook 模式(備選)
優先使用 bot token 模式。僅在無法通過 Slack 應用審批(個人工作區或受限企業方案),或需要最簡單的一次性文本告警頻道時才使用 webhook。
1. 創建 Incoming Webhook
- api.slack.com/apps → Create New App → From scratch → 命名為 "Minara" → 選擇你的工作區
- 左側導航 → Incoming Webhooks → 將功能切換為 On
- Add New Webhook to Workspace → 選擇頻道 → Allow
- 複製 webhook URL(
https://hooks.slack.com/services/T00/B00/xxx)
2. 配置 Minara
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T00/B00/xxx頻道已編碼在 URL 中,SLACK_CHANNEL_ID 會被忽略;在 send_message 上覆蓋 channel 會返回明確的錯誤。Webhook 模式支持線程、Block Kit 塊、mrkdwn 和 unfurl 開關;不支持附件、臨時消息、定時消息或 metadata。
流式傳輸行為(僅限 bot 模式)
Slack 的 chat.update 受 Tier-3 速率限制(約 50 次/分鐘)。Minara 將編輯節流至 1200 毫秒,既不超出上限,響應也足夠及時。消息最大長度為 40000 個字符,實際使用中幾乎不會觸達。
富文本消息:Block Kit、臨時消息、定時消息、metadata(bot 模式)
bot 模式下,send_message 接受 provider_options.slack 對象,直接映射到對應的 Slack Web API 字段或端點。核心字段 text / channel / thread 可與 provider_options.slack 在同一次調用中組合使用。
attachments 是例外。 附件通過 Slack 的 Files v2 流程處理(files.getUploadURLExternal → files.completeUploadExternal),該流程僅接受 initial_comment(由 text 填充)和 thread_ts。在使用 attachments 的同時傳入 blocks / mrkdwn / unfurl_* / metadata / ephemeral_user / schedule_at 會在工具邊界處被拒絕。解決方案:先發送富文本消息(獲取 messageId),再將文件作為後續消息上傳到該線程。
Block Kit 富文本格式
Slack 的 Block Kit 是標準富消息格式,支持標題、分區、分隔線、上下文、字段和圖片。blocks 是塊對象數組,直接傳入 chat.postMessage 的 blocks 參數。text 作為純文本回退內容,用於移動通知、屏幕閱讀器和無障礙工具。
send_message({
provider: "slack",
text: "BTC -5.1% on 1h", // fallback — shown when blocks can't render
provider_options: {
slack: {
blocks: [
{ type: "header", text: { type: "plain_text", text: "Price alert" } },
{ type: "section", text: { type: "mrkdwn", text: "*BTC* dropped *5.1%* in the last hour" } },
{ type: "divider" },
{
type: "context",
elements: [
{ type: "mrkdwn", text: "_Source: Minara · 1h · $68,450_" },
],
},
],
},
},
})在 Slack Block Kit Builder 中迭代塊佈局,將生成的 JSON 直接粘貼到 blocks 中。
臨時消息:僅對單個用戶可見
將 ephemeral_user 設置為 Slack 用戶 ID(如 U012ABC),消息將通過 chat.postEphemeral 發送。該消息僅對該用戶可見,用戶重新加載 Slack 後消失。適用於面向單個用戶的確認提示,或頻道內斜槓命令的響應。
send_message({
provider: "slack",
text: "Your position is under 1% of portfolio — auto-trade skipped.",
provider_options: { slack: { ephemeral_user: "U012ABC" } },
})chat.postEphemeral 支持的參數是 chat.postMessage 的嚴格子集。 根據 Slack 文檔,臨時端點不接受 mrkdwn、unfurl_links、unfurl_media 或 metadata,僅支持 text / blocks / thread_ts / attachments 及標準認證參數。在 ephemeral_user 之外傳入上述不支持的字段會在工具邊界處返回明確錯誤,不會靜默丟棄。臨時消息也與 Minara 的 attachments(Slack files.v2 流程沒有臨時鉤子)以及 schedule_at(無法定時發送臨時消息)不兼容。
定時消息
將 schedule_at 設置為 Unix 秒級時間戳,消息將通過 chat.scheduleMessage 發送。Slack 定時上限為 120 天,Minara 在工具邊界處執行同樣的約束。
send_message({
provider: "slack",
text: "Weekly review — check the dashboard before stand-up",
provider_options: {
slack: { schedule_at: Math.floor(Date.now() / 1000) + 7 * 24 * 60 * 60 },
},
})返回的 message_id 是 Slack 的 scheduled_message_id。如需取消,可在後續工具中將其傳入 chat.deleteScheduledMessage。與 ephemeral_user 互斥。
定時消息不支持 metadata。 Slack 的 chat.scheduleMessage 文檔說明,帶有 metadata 參數的定時消息"不會發送"。Minara 在工具邊界處拒絕此組合,避免返回一個永遠不會實際投遞的 scheduled_message_id。
mrkdwn / unfurl_links / unfurl_media
按消息控制 Slack 的默認解析行為:
mrkdwn: false:禁用text上的 Markdown 展開(發送字面量*not-bold*)。unfurl_links: false:禁止消息內鏈接預覽(適用於高頻告警,避免每條都生成大型預覽卡片)。unfurl_media: false:禁止富媒體預覽。
metadata:機器可讀上下文
將結構化 JSON 隨消息一同發送(Slack 上限 8KB)。界面中不顯示;適合入站處理器需要 LLM 推理所用的原始數據,而非僅需渲染後文本的場景。
send_message({
provider: "slack",
text: "BTC dropped 5%",
provider_options: {
slack: {
metadata: {
event_type: "price_alert",
event_payload: { symbol: "BTC", pct: -5.1, ts: Date.now() },
},
},
},
})覆蓋頻道(僅限 bot 模式)
send_message({
provider: "slack",
channel: "C9876XYZ",
text: "Critical: position liquidation imminent",
})bot 必須是目標頻道的成員,或擁有 chat:write.public 權限範圍。
故障排查
"Webhook URL is disabled"
- Slack 禁用了該 webhook,原因是應用已從工作區移除,或在應用設置中手動撤銷了該 webhook
- 重新創建 webhook 並替換
SLACK_WEBHOOK_URL
"channel_not_found"(bot 模式)
- bot 不是該頻道的成員。在目標頻道中執行
/invite @your-bot,或添加chat:write.public權限範圍
"not_authed" / "invalid_auth"
SLACK_BOT_TOKEN缺失或錯誤。bot token 以xoxb-開頭;用戶 token(xoxp-)不可用,Slack API 會在chat.postMessage時拒絕
"Streaming not working"
- 當前可能處於 webhook 模式。檢查
SLACK_BOT_TOKEN和SLACK_CHANNEL_ID是否均已設置
"invalid_blocks" / "missing_scope"(使用 Block Kit 時)
- Slack API 會根據自身 JSON schema 校驗 Block Kit,Minara 不復制該 schema 檢查。使用 Block Kit Builder 迭代,找出具體有問題的塊
missing_scope通常意味著缺少files:write(附件)或reactions:write(add_reaction)。添加權限範圍後重新安裝應用
參考資料
- 環境變量:
SLACK_WEBHOOK_URL、SLACK_BOT_TOKEN、SLACK_CHANNEL_ID - 源碼:
apps/agent/src/messaging/slack.ts - Slack Web API 索引:api.slack.com/methods
- Block Kit 參考:api.slack.com/block-kit
- Incoming Webhooks:api.slack.com/messaging/webhooks