跳转至

Slack

概述

Slack Channel通过Bot Token方式接入,支持完整的Slack API功能,包括Block Kit消息和交互式组件。

官方文档: https://api.slack.com/
接入方式: Bot User OAuth Token
支持消息类型: 文本、Markdown、Block Kit、文件、表情回应


配置参数

Config 结构体

type Config struct {
    BotToken       string        // Bot Token
    SigningSecret  string        // 签名密钥
    AppToken       string        // App Token(Socket Mode用)
    DefaultChannel string        // 默认频道
    HTTPTimeout    time.Duration // HTTP超时时间
}

参数详细说明

参数名 类型 必填 默认值 说明
bot_token string - Bot User OAuth Token,格式 xoxb-...
signing_secret string "" 用于验证Webhook请求签名
app_token string "" App-Level Token,用于Socket Mode
default_channel string "" 默认发送频道ID或名称
http_timeout duration 30s HTTP请求超时时间

bot_token

  • 数据类型: string
  • 格式: xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx
  • 获取方式:
  • 访问 https://api.slack.com/apps
  • 创建新应用或选择已有应用
  • 进入"OAuth & Permissions"
  • 安装应用到工作区
  • 复制"Bot User OAuth Token"

signing_secret

  • 数据类型: string
  • 格式: 32位十六进制字符串
  • 获取方式: 应用设置 → Basic Information → Signing Secret
  • 用途: 验证Webhook请求来自Slack(HMAC-SHA256)

app_token

  • 数据类型: string
  • 格式: xapp-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx
  • 获取方式: 应用设置 → Basic Information → App-Level Tokens
  • 用途: 用于Socket Mode连接

default_channel

  • 数据类型: string
  • 格式: 频道ID(如 C1234567890)或名称(如 #general
  • 用途: 当消息未指定目标频道时使用

完整配置示例

YAML配置

channels:
  - name: slack-bot
    type: slack
    config:
      bot_token: "xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"
      signing_secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      app_token: "xapp-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"
      default_channel: "#general"
      http_timeout: 30s

Go代码配置

import (
    "time"
    "github.com/example/gort/pkg/channel/slack"
)

config := slack.Config{
    BotToken:       "xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx",
    SigningSecret:  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    AppToken:       "xapp-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx",
    DefaultChannel: "#general",
    HTTPTimeout:    30 * time.Second,
}

ch, err := slack.NewChannel("slack-bot", config)
if err != nil {
    log.Fatal(err)
}

所需权限 (Scopes)

必需权限

Scope 说明
chat:write 发送消息
chat:write.public 发送到公共频道

可选权限

Scope 说明
files:write 上传文件
reactions:write 添加表情回应
channels:read 读取频道信息
groups:read 读取私有频道信息
im:read 读取私信信息

功能支持

消息类型

消息类型 支持状态 说明
文本消息 普通文本
Markdown Mrkdwn格式
Block Kit 富文本块
图片消息 图片附件
文件消息 文件上传
表情回应 添加reaction
线程回复 线程内回复

能力矩阵

GetCapabilities() 返回:
- TextMessages:     true
- MarkdownMessages: true
- ImageMessages:    true
- FileMessages:     true
- BlockKit:         true
- ReactionMessages: true
- Threads:          true
- Interactive:      true
- MessageEditing:   true
- MessageDeletion:  true
- LocationMessages: false
- ReadReceipts:     false
- TypingIndicators: false

常见配置问题

问题1: Token无效

现象: API返回"invalid_auth"

原因: - Token格式错误 - Token已撤销

解决:

// 确保使用Bot Token而非User Token
config := slack.Config{
    BotToken: "xoxb-...",  // 必须以xoxb-开头
}

问题2: 频道不存在

现象: 返回"channelnotfound"

原因: - 频道ID错误 - Bot未加入频道

解决: 1. 确认频道ID正确(以C开头) 2. 将Bot邀请到目标频道 3. 或申请 chat:write.public 权限

问题3: Webhook签名验证失败

现象: 返回"invalid signature"

原因: Signing Secret配置错误

解决:

// 确保Signing Secret正确
config := slack.Config{
    SigningSecret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
}


发送消息示例

发送文本消息

msg := &message.Message{
    ID:        "msg-1",
    ChannelID: "slack-bot",
    Direction: message.DirectionOutbound,
    To:        message.UserInfo{ID: "C1234567890"},  // 频道ID
    Content:   "Hello Slack!",
    Type:      message.MessageTypeText,
}

err := ch.SendMessage(ctx, msg)

发送Block Kit消息

msg := &message.Message{
    ID:        "msg-2",
    ChannelID: "slack-bot",
    Direction: message.DirectionOutbound,
    To:        message.UserInfo{ID: "C1234567890"},
    Content:   "Block Kit message",
    Type:      message.MessageTypeText,
}

blocks := []map[string]interface{}{
    slack.BuildSectionBlock("Hello from *Gort*!"),
    slack.BuildDividerBlock(),
    slack.BuildActionBlock("actions-1", []map[string]interface{}{
        slack.BuildButton("Click me", "button-1", "primary"),
    }),
}
msg.SetMetadata("blocks", blocks)

err := ch.SendMessage(ctx, msg)

发送线程回复

msg := &message.Message{
    ID:        "msg-3",
    ChannelID: "slack-bot",
    Direction: message.DirectionOutbound,
    To:        message.UserInfo{ID: "C1234567890"},
    Content:   "Thread reply",
    Type:      message.MessageTypeText,
}
msg.SetMetadata("thread_ts", "1234567890.123456")  // 父消息时间戳

err := ch.SendMessage(ctx, msg)

安全建议

  1. Token保护: Bot Token具有广泛权限,请妥善保管
  2. 签名验证: 启用Webhook签名验证
  3. 权限最小化: 只申请必要的Scopes
  4. 定期轮换: 定期重新安装应用获取新Token

错误代码参考

错误 说明
ErrTokenRequired 缺少Bot Token
ErrSigningSecretRequired 需要Signing Secret
ErrChannelNotFound 频道不存在
ErrRateLimited 触发Slack限流