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)。添加权限范围后重新安装应用

参考资料

本页目录