跳转至

Discord

概述

Discord Channel通过Bot Token方式接入Discord API v10,支持发送富文本嵌入(Embed)消息和文件上传。

官方文档: https://discord.com/developers/docs
接入方式: Bot Token
API版本: Discord API v10
支持消息类型: 文本、Markdown、Embed、文件、表情回应


配置参数

Config 结构体

type Config struct {
    BotToken         string        // Bot Token
    ApplicationID    string        // 应用ID
    PublicKey        string        // 公钥
    DefaultChannelID string        // 默认频道ID
    HTTPTimeout      time.Duration // HTTP超时时间
}

参数详细说明

参数名 类型 必填 默认值 说明
bot_token string - Bot Token,格式 MTAx...
application_id string "" Discord应用ID
public_key string "" 公钥,用于验证Webhook请求
default_channel_id string "" 默认发送频道ID
http_timeout duration 30s HTTP请求超时时间

bot_token

  • 数据类型: string
  • 格式: Base64编码字符串,如 MTAxMDE4MDE4MDE4MDE4MDE4.GF8jKx.xxx
  • 获取方式:
  • 访问 https://discord.com/developers/applications
  • 创建新应用或选择已有应用
  • 进入"Bot"标签页
  • 点击"Reset Token"获取Token(只显示一次)

application_id

  • 数据类型: string
  • 格式: 数字字符串
  • 获取方式: 应用设置 → General Information → Application ID
  • 用途: 用于Slash Commands等API

public_key

  • 数据类型: string
  • 格式: 64位十六进制字符串
  • 获取方式: 应用设置 → General Information → Public Key
  • 用途: 验证Interaction Webhook请求

defaultchannelid

  • 数据类型: string
  • 格式: 数字字符串,如 1234567890123456789
  • 用途: 当消息未指定目标频道时使用

完整配置示例

YAML配置

channels:
  - name: discord-bot
    type: discord
    config:
      bot_token: "XXXXXXXXXXXXXXXXXXXXXXXX"
      application_id: "1010180180180180180"
      public_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      default_channel_id: "1234567890123456789"
      http_timeout: 30s

Go代码配置

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

config := discord.Config{
    BotToken:         "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    ApplicationID:    "1010180180180180180",
    PublicKey:        "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    DefaultChannelID: "1234567890123456789",
    HTTPTimeout:      30 * time.Second,
}

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

所需权限 (Permissions)

必需权限

权限 说明
Send Messages 0x800 发送消息
Read Message History 0x10000 读取历史消息

可选权限

权限 说明
Embed Links 0x4000 发送嵌入内容
Attach Files 0x8000 上传文件
Add Reactions 0x40 添加表情回应
Use Slash Commands 0x80000000 使用斜杠命令

功能支持

消息类型

消息类型 支持状态 说明
文本消息 支持Markdown
Embed 富文本嵌入
文件上传 附件上传
表情回应 添加reaction
消息编辑 编辑已发送消息
消息删除 删除消息

能力矩阵

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

邀请Bot到服务器

生成邀请链接

  1. 在Discord开发者控制台中
  2. 进入 OAuth2 → URL Generator
  3. 选择 bot scope
  4. 选择需要的权限
  5. 复制生成的URL
  6. 在浏览器中访问并选择服务器

示例邀请URL

https://discord.com/api/oauth2/authorize?client_id=1010180180180180180&permissions=76800&scope=bot

常见配置问题

问题1: Token无效

现象: API返回401 Unauthorized

原因: - Token格式错误 - Token已重置

解决:

// 确保使用Bot Token
config := discord.Config{
    BotToken: "MTAx...",  // 必须以MTAx开头
}

// 在开发者控制台重新生成Token

问题2: 权限不足

现象: 返回403 Forbidden

原因: Bot缺少必要权限

解决: 1. 检查Bot在频道的权限 2. 重新生成邀请链接并添加所需权限 3. 重新邀请Bot到服务器

问题3: 频道不存在

现象: 返回"Unknown Channel"

原因: - 频道ID错误 - Bot不在该服务器

解决:

// 确认频道ID正确(18位数字)
msg := &message.Message{
    To: message.UserInfo{ID: "1234567890123456789"},
}


发送消息示例

发送文本消息

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

err := ch.SendMessage(ctx, msg)

发送Embed消息

msg := &message.Message{
    ID:        "msg-2",
    ChannelID: "discord-bot",
    Direction: message.DirectionOutbound,
    To:        message.UserInfo{ID: "1234567890123456789"},
    Content:   "Embed message",
    Type:      message.MessageTypeText,
}

embed := discord.BuildEmbed(
    "Title",
    "Description with **markdown**",
    "https://example.com",
    0x5865F2,  // Discord Blurple color
)
msg.SetMetadata("embeds", []map[string]interface{}{embed})

err := ch.SendMessage(ctx, msg)

发送带字段的Embed

embed := map[string]interface{}{
    "title":       "Gort Bot",
    "description": "A powerful messaging gateway",
    "color":       0x00ff00,
    "fields": []map[string]interface{}{
        discord.BuildEmbedField("Version", "1.0.0", true),
        discord.BuildEmbedField("Status", "Online", true),
    },
    "footer": discord.BuildEmbedFooter("Powered by Gort", ""),
}

msg.SetMetadata("embeds", []map[string]interface{}{embed})

回复消息

msg := &message.Message{
    ID:        "msg-3",
    ChannelID: "discord-bot",
    Direction: message.DirectionOutbound,
    To:        message.UserInfo{ID: "1234567890123456789"},
    Content:   "Reply message",
    Type:      message.MessageTypeText,
}
msg.SetMetadata("reply_to_message_id", "original-message-id")

err := ch.SendMessage(ctx, msg)

安全建议

  1. Token保护: Bot Token具有服务器管理权限,请妥善保管
  2. 权限最小化: 只授予Bot必要的权限
  3. Webhook验证: 使用PublicKey验证Interaction请求
  4. 定期轮换: 定期重置Bot Token

错误代码参考

错误 说明
ErrTokenRequired 缺少Bot Token
ErrInvalidToken Token无效
ErrChannelNotFound 频道不存在
ErrForbidden 权限不足
ErrRateLimited 触发Discord限流