MINARA
使用 Minara客戶端與界面消息平臺

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 請求體中接受 textblocksthread_tsmrkdwnunfurl_linksunfurl_media。不支持編輯端點(無流式傳輸)、files.upload(無附件)、reactions.addchat.postEphemeralchat.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

  1. 打開 api.slack.com/appsCreate New AppFrom scratch → 命名為 "Minara" → 選擇你的工作區
  2. OAuth & Permissions 下,添加以下 Bot Token Scopes
    • chat:writechat.postMessage / chat.postEphemeral / chat.scheduleMessage 必需
    • chat:write.public,向 bot 未受邀的頻道發送消息必需
    • files:write,通過 files.v2 上傳附件必需
    • reactions:writeadd_reaction 工具必需
  3. 點擊頂部的 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=C0123ABC

4. 測試

minara auth messaging test slack

配置:Webhook 模式(備選)

優先使用 bot token 模式。僅在無法通過 Slack 應用審批(個人工作區或受限企業方案),或需要最簡單的一次性文本告警頻道時才使用 webhook。

1. 創建 Incoming Webhook

  1. api.slack.com/appsCreate New AppFrom scratch → 命名為 "Minara" → 選擇你的工作區
  2. 左側導航 → Incoming Webhooks → 將功能切換為 On
  3. Add New Webhook to Workspace → 選擇頻道 → Allow
  4. 複製 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.getUploadURLExternalfiles.completeUploadExternal),該流程僅接受 initial_comment(由 text 填充)和 thread_ts。在使用 attachments 的同時傳入 blocks / mrkdwn / unfurl_* / metadata / ephemeral_user / schedule_at 會在工具邊界處被拒絕。解決方案:先發送富文本消息(獲取 messageId),再將文件作為後續消息上傳到該線程。

Block Kit 富文本格式

Slack 的 Block Kit 是標準富消息格式,支持標題、分區、分隔線、上下文、字段和圖片。blocks 是塊對象數組,直接傳入 chat.postMessageblocks 參數。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 文檔,臨時端點不接受 mrkdwnunfurl_linksunfurl_mediametadata,僅支持 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

按消息控制 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_TOKENSLACK_CHANNEL_ID 是否均已設置

"invalid_blocks" / "missing_scope"(使用 Block Kit 時)

  • Slack API 會根據自身 JSON schema 校驗 Block Kit,Minara 不復制該 schema 檢查。使用 Block Kit Builder 迭代,找出具體有問題的塊
  • missing_scope 通常意味著缺少 files:write(附件)或 reactions:writeadd_reaction)。添加權限範圍後重新安裝應用

參考資料

本頁目錄