消息类型与发送
- 00-inbox/product-bot-answers/2026-09-20-P0-API鉴权-Q3回答.md(产品管家Q3:消息收发核心模型)
- 00-inbox/product-bot-answers/2026-09-22-P1-round1-Q1-Speech语音深度回答.md(Q1:语音type=4/Bot/Web不能发)
- 00-inbox/product-bot-answers/2026-09-22-P1-round2-Q6-Drive网盘深度回答.md(Q6:文件type=8 Tika抽取+chat/前缀+大小限制)
- 00-inbox/product-bot-answers/2026-09-22-P1-r2-Q9-BotAPI与消息类型全景回答.md(Q9 BA-01:消息类型枚举/卡片白名单/发送API 源码确认级)
- 06-api-integration/Bot-API概览.md v0.4(sendMessage端点/payload.type枚举/mention字段源码确认)
- 06-api-integration/OCTO-Bot-API接入快速上手指南-v0.1.md(raw card四必填字段/sendMessage骨架)
- source-repos/octo-server/modules/bot_api/bot_api.go(路由注册)
- source-repos/octo-server/pkg/cardmsg/(卡片payload校验:profiles.go/whitelist.go/cardmsg.go)
- source-repos/octo-web/packages/dmworkbase/src/Service/Const.ts:52(MessageContentTypeConst 完整枚举)
- source-repos/openclaw-channel-octo/src/api-fetch.ts(sendMessage调用骨架)
消息类型与发送 v1.0(源码确认升级)
状态:review / v1.0 源码确认升级。confidence: medium-high。
本文档基于 Q9 BA-01(源码确认级回答)对 v0.1 框架进行全面回填升级。
消息类型枚举、卡片 type=17 白名单/限制/动态改卡、发送端点、Bot 管理能力均已由源码确认。
已确认事实标注 ✅;仍未确认的细节标注 ⚠️ 待后续轮次补充。
本文不替代官方 API 文档,不作为客户交付集成手册。
🔴 售前/集成关键纠偏(必须醒目)
🔴 Bot Token 前缀是 `bf_`,不是 `bt_`,不是 `sk_`。
三类 Token 前缀:User Bot `bf_` / App Bot `app_` / User API Key `uk_`。
`bf_` 格式:`bf_` + 16 随机字节 hex(共 32 个 hex 字符),由 crypto/rand 生成。
写错前缀会导致 401 鉴权失败。集成代码中必须使用 `bf_` 开头的 Token。
1. 消息模型概述
1.1 消息信封结构
| 字段 | 类型 | 必填 | 说明 | 确认状态 |
|---|---|---|---|---|
channel_id |
string | ✅ | 目标会话 ID(群号/DM UID/Thread ID) | ✅ Q3/Q9 确认 |
channel_type |
uint8 | ✅ | 会话类型:DM(Person)=1 / 群=2 / 子区(Thread)=5 | ✅ Q3/Q9 确认 |
payload |
object | ✅ | 消息体,含 type 字段区分消息类型 |
✅ Q3/Q9 确认 |
client_msg_no |
string | 建议 | 客户端消息唯一编号,用于幂等去重 | ⚠️ 字段存在,去重语义待后续确认 |
on_behalf_of |
string | ❌ | OBO 代发用户 UID(需授权+grant+scope) | ✅ Q3/Q9 确认存在,三重防循环 |
stream_no |
string | ❌ | 流式消息编号(打字机效果) | ⚠️ Q3 提到,完整机制待确认 |
来源:产品管家 Q3/Q9;octo-server modules/bot_api 路由。
1.2 payload 统一结构
{
"type": <消息类型数字>,
// ... 该类型专属字段
}
1.3 Bot 发消息的权限边界(✅ 源码确认)
- Bot 只能在自己被添加的群/对话中发消息——不能跨群任意发送。非成员群返回 `ErrBotAPINotGroupMember`。(Q2/Q3/Q9)
- Bot 不能发送语音消息(type=4)——详见 §4.4。(Q1 源码级确认,全仓无 TTS)
- Bot 可以发卡片消息(type=17),普通用户 API 绝对拒绝卡片 payload(`IsCardPayload→ErrMessageCardSendForbidden`)。(Q3 + 快速上手指南 046)
- Bot 默认以自己 robotID 身份发消息;OBO 模式需用户显式 grant+scope,三重防循环机制。(Q3/Q9)
- Bot 只能编辑自己发的消息,不能编辑/撤回人类消息。(Q3/Q9)
- Bot 可 @群成员 / @所有人。(Q9 BA-04 确认)
- Bot 可发私信(Person 频道,channel_type=1)。App Bot 仅 DM(filterAppBotEvents 过滤非 Person 频道)。(Q9 BA-02/BA-04 确认)
- Bot 可编辑消息(动态改卡)——`POST /v1/bot/message/edit` + `octo_message_card_revision` 表 + `card_seq` CAS 并发控制。(Q9 BA-01 确认)
2. 消息类型总表(✅ Q9 源码确认完整枚举)
来源:octo-web `packages/dmworkbase/src/Service/Const.ts:52` `MessageContentTypeConst`;octo-server `pkg/cardmsg/cardmsg.go:42`(InteractiveCard=17)。
| type 值 | 消息类型 | Bot 可发送 | 客户端可发送 | 说明 | 确认状态 |
|---|---|---|---|---|---|
| 1 | 文本 | ✅ 可 | ✅ 可 | 基础文本消息,含 @mention/reply | ✅ Q3/Q9 |
| 2 | 图片 | ✅ 可 | ✅ 可 | 图片消息(存储在 MinIO) | ✅ Q9 枚举确认 |
| 3 | GIF | ✅ 可 | ✅ 可 | GIF 动图 | ✅ Q9 枚举确认 |
| 4 | 语音 | ❌ 不可 | ✅ 移动端可(Web 不可) | 仅 ASR 接收方向,Bot/Web 无发送路由 | ✅ Q1/Q9 |
| 5 | 小视频 | ✅ 可 | ✅ 可 | 短视频消息 | ✅ Q9 枚举确认 |
| 6 | 位置 | ⚠️ 待确认 payload | ✅ 可 | 地理位置共享 | ✅ Q9 枚举确认 type=6,payload 字段待补 |
| 7 | 名片 | ⚠️ 待确认 payload | ✅ 可 | 用户/群名片分享 | ✅ Q9 枚举确认 type=7,payload 字段待补 |
| 8 | 文件/附件 | ✅ 可 | ✅ 可 | 文档/压缩包等(Tika 抽取+chat/前缀) | ✅ Q3/Q6/Q9 |
| 11 | 合并转发 | ⚠️ 待确认 payload | ✅ 可 | 多条消息合并转发 | ✅ Q9 枚举确认 type=11 |
| 12 | Lottie 贴图 | ⚠️ 待确认 | ✅ 可 | Lottie 动画贴纸 | ✅ Q9 枚举确认 type=12 |
| 13 | Emoji 贴图 | ⚠️ 待确认 | ✅ 可 | Emoji/自定义表情贴图 | ✅ Q9 枚举确认 type=13 |
| 14 | 富文本图文混排 | ⚠️ 待确认 payload | ✅ 可 | 图文混排消息 | ✅ Q9 枚举确认 type=14 |
| 17 | 互动卡片(Adaptive Cards) | ✅ 可(专属) | ❌ 普通用户不可 | Adaptive Cards,Bot 专属能力 | ✅ Q3/Q9 详 §3.5 |
| 18 | 文档转发卡片 | ⚠️ 待确认 | ✅ 可 | 文档分享卡片 | ✅ Q9 枚举确认 type=18 |
| 20 | 截屏 | ⚠️ 待确认 | ✅ 可 | 截屏消息 | ✅ Q9 枚举确认 type=20 |
| 1002+ | 群系统消息 | ❌ 不可 | ❌ 仅系统 | 入群/退群/改名等系统通知 | ✅ Q9 枚举确认 |
Q9 v0.1 待确认项 Q9-01~Q9-04(消息类型枚举)全部关闭 ✅。
3. 各消息类型详情
3.1 文本消息(type=1)✅
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type |
int | ✅ | 固定值 1 |
content |
string | ✅ | 文本内容 |
{
"channel_id": "",
"channel_type": 2,
"payload": {
"type": 1,
"content": "你好,这是一条来自 Bot 的文本消息"
}
}
- Q3 确认:"content支持富文本/Markdown,由客户端渲染"
- ⚠️ 具体支持的 Markdown 子集待后续轮次确认
- 内联格式:
@[uid:displayName]——在 content 文本中以此格式标记 @提及用户 - 配合 payload 级
mention字段使用 mention.all = 1表示 @所有人
Q9-24(@内联格式)关闭 ✅。
3.2 图片消息(type=2)✅ type确认
- type 值 = 2(Q9 源码枚举确认,不复用 type=8)
- 图片存储在 MinIO 对象存储(Q3 + Q6 交叉确认)
- 上传通过文件 API(
POST /v1/bot/file/upload或 presigned PUT),key 前缀chat/ - 图片不走 Tika 正文抽取(Tika 黑名单排除 .jpg 等媒体文件,Q6 确认)
- ⚠️ payload 字段(width/height/thumbnail/format/url)待后续确认
- ⚠️ 图片大小/格式限制待后续确认
Q9-02(图片 type 值)关闭 ✅:独立 type=2。
3.3 GIF 消息(type=3)✅ type确认
- type = 3,GIF 动图消息
- payload 字段结构待补充
- Bot 可发送(Q9 枚举表未限制)
3.4 文件/附件消息(type=8)✅
| 字段 | 类型 | 必填 | 说明 | 确认状态 |
|---|---|---|---|---|
type |
int | ✅ | 固定值 8 |
✅ Q3/Q9 |
url |
string | ✅ | 文件在 MinIO 的 URL(presigned 或 bucket 路径) | ✅ Q3/Q6 |
name |
string | ✅ | 文件名(含扩展名) | ✅ Q3 |
size |
int64 | ✅ | 文件大小(字节) | ✅ Q3 |
- 上传:`POST /v1/bot/file/upload`(中转)或 `GET /v1/bot/upload/presigned` 获取预签名 URL 直传 MinIO
- Key 前缀:硬编码 `chat/`——Bot 上传的文件只进聊天附件命名空间,不进入用户 Drive 网盘(P0 安全硬结论)
- 正文抽取:octo-search-indexer 消费 Kafka topic `octo.message.v1`,payload.type=8 时:
- 下载文件 → Apache Tika(
apache/tika:3.3.0.0)抽取文本 - Tika 黑名单排除 .mp4/.zip/.jpg 等媒体/压缩/图片
- 正文截断 256KB → 写入 OpenSearch
payload.file.content供全文搜索
- 权限隔离:扩展名白/黑名单 + MaxUploadSize + `chat/` 前缀三重隔离
{
"channel_id": "",
"channel_type": 2,
"payload": {
"type": 8,
"url": "https:///botfile/chat/2026-09-22/abc123.pdf",
"name": "项目方案.pdf",
"size": 2048576
}
}
1. POST /v1/bot/file/upload (multipart/form-data,文件本体)
↓ 返回 { url, path, name, size }
2. POST /v1/bot/sendMessage (payload.type=8,url 用步骤1返回的)
1. GET /v1/bot/upload/presigned?filename=xxx&size=yyy
↓ 返回 { upload_url, method, headers, file_url }
2. PUT (直接 PUT 到 MinIO,SigV4 签名)
3. POST /v1/bot/sendMessage (payload.type=8,url 用 file_url)
3.5 语音消息(type=4)🔴 Bot/Web 不可发送
| 限制项 | 事实 | 来源 |
|---|---|---|
| Bot 不能发语音 | octo-speech 纯 STT/ASR,全仓无 TTS;MessageContentTypeVoice 在 Web 端=0,无 Bot 发送 type=4 路由 |
Q1 全仓 code search = 0 命中 |
| Web 端不能发语音 | Web 端只做"录音→转文字填入输入框"(VoiceService.transcribe()),不是发语音消息 | Q1 octo-web 源码 |
| 语音不存 MinIO | 音频只落本地 ASR 日志目录(ASR_LOG_DIR),不进对象存储;默认保留7天 | Q1 octo-speech |
🔴 Bot 不能发送语音消息(type=4)。 Bot 如需"语音输出"能力,当前无 TTS 支持,只能发送文本。Web 端同样不支持发送语音消息,仅支持语音输入转文字。
3.6 小视频消息(type=5)✅ type确认
- type = 5,短视频消息
- Q6 确认视频走文件类(Tika 黑名单排除 .mp4)
- payload 字段结构(url/duration/thumbnail/width/height)待补充
- Bot 可发送
Q9-03(视频 type 值)关闭 ✅:type=5(小视频)。
3.7 位置消息(type=6)✅ type确认
- type = 6,地理位置共享
- payload 字段(lat/lng/title/address/poi)待补充
- Bot 发送能力待确认
3.8 名片消息(type=7)✅ type确认
- type = 7,用户/群名片分享
- payload 字段(uid/name/avatar 或 group_no/group_name)待补充
- Bot 发送能力待确认
3.9 合并转发(type=11)✅ type确认
- type = 11,多条消息合并转发
- payload 字段(转发消息列表结构)待补充
- Bot 发送能力待确认
3.10 Lottie/Emoji 贴图(type=12/13)✅ type确认
- type = 12:Lottie 动画贴纸
- type = 13:Emoji/自定义表情贴图
- Q4 确认贴纸单文件 1MB / 512×512 像素
- Bot 发送能力待确认
3.11 富文本图文混排(type=14)✅ type确认
- type = 14,图文混排消息
- payload 字段结构待补充
- Bot 发送能力待确认
3.12 互动卡片(type=17)✅ 完整规格确认
来源:octo-server `pkg/cardmsg/profiles.go`(两档profile)、`whitelist.go`(元素白名单)、`cardmsg.go:42`(InteractiveCard=17)。
3.12.1 顶层信封字段(✅ 硬校验确认)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type |
int | ✅ | 固定值 17 |
card |
object | ✅ | Adaptive Card JSON 内容 |
profile |
string | ✅ | 渲染 profile:"octo/v1"(展示) / "octo/v2"(交互);服务端最终覆盖写入 |
card_version |
int | ✅ | 卡片版本号(当前为 1) |
3.12.2 两档 Profile(✅ Q9 源码确认)
| Profile | 能力 | 交互 |
|---|---|---|
| octo/v1 | 展示型卡片 | 仅本地动作(OpenUrl/ToggleVisibility/CopyToClipboard) |
| octo/v2 | 交互型卡片 | v1 全部 + 输入元素 + Action.Submit(回调服务端) |
来源:`profiles.go`。
3.12.3 展示元素白名单(v1/v2 通用,✅ whitelist.go 确认)
| 元素 | 说明 |
|---|---|
TextBlock |
文本块 |
RichTextBlock |
富文本块 |
Image |
图片 |
ImageSet |
图片集 |
Container |
容器 |
ColumnSet |
列布局 |
FactSet |
事实键值对列表 |
Table |
表格 |
ActionSet |
动作按钮组 |
3.12.4 输入元素(v2 专属,✅ Q9 确认)
| 输入元素 | 说明 |
|---|---|
Input.Text |
文本输入框 |
Input.Toggle |
开关/复选 |
Input.ChoiceSet |
下拉/单选/多选 |
Input.Number |
数字输入 |
Input.Date |
日期选择 |
Input.Time |
时间选择 |
3.12.5 动作支持(✅ Q9 确认)
| 动作 | v1 | v2 | 说明 |
|---|---|---|---|
Action.OpenUrl |
✅ | ✅ | 本地打开 URL |
Action.ToggleVisibility |
✅ | ✅ | 本地切换元素可见性 |
Action.CopyToClipboard |
✅ | ✅ | 本地复制文本到剪贴板 |
Action.Submit |
❌ | ✅ | 提交表单/按钮回调到 Bot 服务端 |
Action.Execute(不支持)- auto-refresh(不支持自动刷新)
3.12.6 卡片限制(✅ Q9 源码确认)
| 限制项 | 值 |
|---|---|
| payload 大小 | ≤ 512 KiB |
| body 大小 | ≤ 2 MiB |
| 节点数量 | ≤ 200 |
| 嵌套深度 | ≤ 16 |
3.12.7 动态改卡(✅ Q9 确认)
- 端点:
POST /v1/bot/message/edit - 并发控制:
octo_message_card_revision表 +card_seqCAS(Compare-And-Swap)乐观锁 - 多次并发编辑不会产生冲突,card_seq 保证最终一致
3.12.8 硬校验规则(✅ 快速上手指南 A1 事实)
- 四必填字段缺一不可,缺失返回 4xx
- 其他未知顶层字段:服务端宽容前向兼容
- 禁止伪造 `catalog_provenance`:入站显式拒绝(loud 4xx)
- 禁止同时传 `template` + `card`(raw+template XOR,双传 400)
- 普通用户 API 绝对拒绝卡片 payload
{
"channel_id": "",
"channel_type": 2,
"payload": {
"type": 17,
"profile": "octo/v2",
"card_version": 1,
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "审批请求",
"size": "medium",
"weight": "bolder"
},
{
"type": "FactSet",
"facts": [
{ "title": "申请人", "value": "张三" },
{ "title": "金额", "value": "¥10,000" },
{ "title": "事由", "value": "设备采购" }
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "✅ 批准",
"data": { "action": "approve", "request_id": "REQ-001" }
},
{
"type": "Action.Submit",
"title": "❌ 拒绝",
"data": { "action": "reject", "request_id": "REQ-001" }
}
]
}
}
}
- 发送前建议先调用
GET /v1/bot/card/profile查询当前 Bot 可用的 profiles/limits/card_version - 返回 manifest 是运行时能力的权威依据
Q9-11(卡片元素清单)关闭 ✅:TextBlock/RichTextBlock/Image/ImageSet/Container/ColumnSet/FactSet/Table/ActionSet + Input.*(v2)。
Q9-13(卡片动态更新)关闭 ✅:POST /v1/bot/message/edit + card_seq CAS。
Q9-30(卡片大小限制)关闭 ✅:payload≤512KiB / body≤2MiB / 节点≤200 / 深度≤16。
3.13 文档转发卡片(type=18)✅ type确认
- type = 18,文档分享/转发卡片
- payload 字段待补充
- Bot 发送能力待确认
3.14 截屏消息(type=20)✅ type确认
- type = 20,截屏消息
- payload 字段待补充
- Bot 发送能力待确认
3.15 群系统消息(type=1002+)✅
- type ≥ 1002,群系统通知(入群/退群/改名等)
- Bot 不可发送,仅系统产生
- 🔴 Q9 负向结论:Bot 目前收不到群成员变动/加入退出事件(源码未找到向 Bot 事件队列投递这些事件的写入点)
4. 发送消息 API
4.1 sendMessage 端点(✅ Q9 确认)
{
"channel_id": "",
"channel_type": "",
"payload": {
"type": "",
"...": "该类型的其他字段"
},
"client_msg_no": "",
"on_behalf_of": "",
"stream_no": ""
}
- 单目标单条:一次只能向一个会话发一条消息
- 同步发送:请求返回即消息已入 IM 队列
- payload
type字段决定消息内容类型 - ⚠️ 具体响应体字段(message_id/timestamp/seq)待后续确认
Q9-15(端点确认)关闭 ✅:POST /v1/bot/sendMessage,payload.type 决定内容。
4.2 其他消息操作端点(✅ 路由确认)
| 端点 | 方法 | 用途 | 确认状态 |
|---|---|---|---|
/v1/bot/sendMessage |
POST | 发送消息 | ✅ 完全确认 |
/v1/bot/message/edit |
POST | 编辑已发消息(只能改自己发的;支持动态改卡 + card_seq CAS) | ✅ 路由+用途+并发控制确认;请求体字段细节待补 |
/v1/bot/typing |
POST | 发送打字指示器 | ✅ 路由确认;格式待补 |
/v1/bot/readReceipt |
POST | 上报已读回执 | ✅ 路由确认;格式待补 |
/v1/bot/messages/sync |
POST | 历史消息拉取(分页+方向控制,v1.1.2 #50) | ✅ 路由确认;分页参数/响应待补 |
/v1/bot/message/card/revisions/clear |
POST | 清除卡片修订墓碑 | ✅ 路由确认 |
| 撤回消息 | — | ❓ 路由表未见独立 recall 端点 | ⚠️ 待确认是否支持 |
4.3 Bot 管理能力(消息发送相关,✅ Q9 BA-04 确认)
| 能力 | 说明 | 确认状态 |
|---|---|---|
| @群成员 | 在文本消息中通过 @[uid:displayName] @特定群成员 |
✅ Q9 |
| @所有人 | mention.all = 1 @群内所有人 |
✅ Q9 |
| 发私信(DM) | 向 Person 频道(channel_type=1)发送私信 | ✅ Q9 |
| 编辑消息 | 编辑自己发送的消息,包括动态改卡 | ✅ Q9 |
| 文件上传下载 | 通过 file/upload 和 presigned URL 上传/下载文件 | ✅ Q3/Q6 |
| 打字指示器 | POST /v1/bot/typing | ✅ 路由 |
| 已读回执 | POST /v1/bot/readReceipt | ✅ 路由 |
4.4 消息接收(Bot 侧,与发送相关)
- 主通道:
POST /v1/bot/events(HTTP 长轮询 long-poll,不是 WebSocket,不是 Webhook) - wait 字段,单次 hold 上限 30s
- 底层:Redis sorted-set + doorbell BLPOP
- 事件队列写入源:①普通消息(DM/@) ②card_action(按钮/表单回调) ③文档评论@Bot ④bot_setting卡片事件
- ACK 机制:
POST /v1/bot/events/:event_id/ack——逐条确认,at-least-once 投递 - 补拉:
POST /v1/bot/messages/sync——历史消息补拉 - 🔴 Bot 收不到 reaction/群成员变动/加入退出/被移除事件(Q9 负向硬结论:源码未找到投递点,Reactions 字段被注释)
- ⚠️ 无独立 in_reply_to 字段,回复上下文在 payload 内(WuKongIM reply),Bot 自行解析
5. 消息大小/格式限制
5.1 已确认的限制(✅ Q9+前期确认)
| 限制项 | 值 | 来源 | 确认状态 |
|---|---|---|---|
| 卡片 payload | ≤ 512 KiB | Q9 pkg/cardmsg | ✅ 源码确认 |
| 卡片 body | ≤ 2 MiB | Q9 pkg/cardmsg | ✅ 源码确认 |
| 卡片节点数 | ≤ 200 | Q9 pkg/cardmsg | ✅ 源码确认 |
| 卡片嵌套深度 | ≤ 16 | Q9 pkg/cardmsg | ✅ 源码确认 |
| 文件默认上限 | 100 MB(DefaultFileMaxSizeKB=100*1024) |
Q4 + Q6 源码 | ✅ 已确认 |
| 贴纸(Sticker) | 单文件 1MB / 512×512 像素 | Q4 回答 | ✅ 已确认 |
| 文件类型校验 | 扩展名白/黑名单双重门 + 魔数校验 | Q4 | ✅ 已确认 |
| Tika 抽取正文截断 | 256KB | Q6 octo-search-indexer | ✅ 已确认 |
| 文件上传前缀 | 硬编码 chat/,仅聊天附件命名空间 |
Q6 | ✅ P0安全 |
5.2 仍待确认的限制
| 待确认项 | 说明 |
|---|---|
| 文本消息最大长度 | 字符数/字节数上限 |
| 图片消息限制 | 单图大小/格式/分辨率 |
| 视频消息限制 | 大小/时长/格式 |
| business 桶具体 RPS | 动态配置无硬编码,待运行时 config |
| 文件大小运维硬顶 | 512MB 配置方式和默认值 |
| presigned URL 有效期 | 待确认 |
| 消息历史保留策略 | 保留期/是否可配 |
6. @Mention 机制(✅ 格式确认)
6.1 已确认部分(Q3+Q9)
- @提及在 content 文本中的内联格式:
@[uid:displayName](Q9 确认) - payload 级
mention字段包含 uids 数组(指定 @某些用户) mention.all = 1表示 @所有人- Bot 可 @群成员,可 @所有人(Q9 BA-04 确认)
- legacy
@all文本不再触发 bot(需用结构化 mention.all) - 群级免@偏好:
GET /v1/bot/groups/:group_no/mention_pref
6.2 @Mention 示例
{
"channel_id": "",
"channel_type": 2,
"payload": {
"type": 1,
"content": "@[uid_zhangsan:张三] 请查看一下这个问题",
"mention": {
"uids": ["uid_zhangsan"],
"all": 0
}
}
}
{
"channel_id": "",
"channel_type": 2,
"payload": {
"type": 1,
"content": "@所有人 请注意,系统将于今晚维护。",
"mention": {
"uids": [],
"all": 1
}
}
}
7. 回复消息(in_reply_to / reply)
已确认部分(Q9)
- 无独立
in_reply_to顶层字段 - 回复上下文在 payload 内(WuKongIM reply 结构),Bot 需自行解析
- Thread(子区)是独立 channel(channel_type=5),不是通过 reply 字段实现
待确认
- payload 内 reply 字段的精确结构(原消息 message_id/seq/摘要)
- 引用回复展示形式
- 多层引用链处理
Q9-26(reply 字段)部分关闭:确认无独立 in_reply_to 顶层字段,reply 在 payload 内。
8. 代码示例
8.1 发送文本消息(✅)
curl -X POST "https:///v1/bot/sendMessage" \
-H "Authorization: Bearer bf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"channel_id": "grp123456",
"channel_type": 2,
"payload": {
"type": 1,
"content": "Hello OCTO! 这是一条来自 Bot 的文本消息。"
},
"client_msg_no": "msg-'"$(uuidgen)"'"
}'
🔴 注意 Token 前缀必须是 `bf_`(不是 `bt_`/`sk_`)。
8.2 发送文件消息(✅ 流程确认)
# Step 1: 上传文件
UPLOAD_RESP=$(curl -s -X POST "https:///v1/bot/file/upload" \
-H "Authorization: Bearer bf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "file=@/path/to/document.pdf")
FILE_URL=$(echo "$UPLOAD_RESP" | jq -r '.url')
FILE_NAME=$(echo "$UPLOAD_RESP" | jq -r '.name')
FILE_SIZE=$(echo "$UPLOAD_RESP" | jq -r '.size')
# Step 2: 发送文件消息
curl -X POST "https:///v1/bot/sendMessage" \
-H "Authorization: Bearer bf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d "{
\"channel_id\": \"grp123456\",
\"channel_type\": 2,
\"payload\": {
\"type\": 8,
\"url\": \"$FILE_URL\",
\"name\": \"$FILE_NAME\",
\"size\": $FILE_SIZE
},
\"client_msg_no\": \"msg-$(uuidgen)\"
}"
8.3 发送交互卡片(✅ v2 交互卡,Q9 白名单确认)
curl -X POST "https:///v1/bot/sendMessage" \
-H "Authorization: Bearer bf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"channel_id": "grp123456",
"channel_type": 2,
"payload": {
"type": 17,
"profile": "octo/v2",
"card_version": 1,
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "审批请求",
"size": "medium",
"weight": "bolder"
},
{
"type": "FactSet",
"facts": [
{ "title": "申请人", "value": "张三" },
{ "title": "金额", "value": "¥10,000" }
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "✅ 批准",
"data": { "action": "approve", "request_id": "REQ-001" }
},
{
"type": "Action.Submit",
"title": "❌ 拒绝",
"data": { "action": "reject", "request_id": "REQ-001" }
}
]
}
},
"client_msg_no": "msg-card-001"
}'
8.4 @Mention 示例(✅ 内联格式确认)
curl -X POST "https:///v1/bot/sendMessage" \
-H "Authorization: Bearer bf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"channel_id": "grp123456",
"channel_type": 2,
"payload": {
"type": 1,
"content": "@[uid001:张三] @[uid002:李四] 请查看",
"mention": {
"uids": ["uid001", "uid002"],
"all": 0
}
},
"client_msg_no": "msg-mention-001"
}'
9. 发送消息注意事项与常见陷阱
9.1 已确认陷阱(✅)
| 陷阱 | 说明 | 来源 |
|---|---|---|
| ❌ Token 前缀写错 | 必须是 bf_,不是 bt_/sk_ |
Q9 🔴纠偏 |
| ❌ Bot 不能发语音 type=4 | 无 TTS、无发送路由 | Q1/Q9 |
| ❌ 普通用户 token 不能发卡片 type=17 | IsCardPayload→ErrMessageCardSendForbidden | Q3/Q9 |
| ❌ 不能跨群发消息 | Bot 必须是目标群成员 | Q2/Q3 |
| ❌ 不能同时传 card+template | raw+template XOR,双传 400 | A1 硬校验 |
| ❌ 不能伪造 catalog_provenance | 入站显式拒绝(loud 4xx) | 044C/046 |
| ❌ Bot 不能编辑/撤回他人消息 | 只能编辑自己发的 | Q3/Q9 |
| ❌ 文件上传不进 Drive | key 前缀硬编码 chat/,Bot 对网盘零面 |
Q6 P0 |
| ❌ 不是 WebSocket | Bot 收事件用 HTTP 长轮询 POST /v1/bot/events,不是 WS/Webhook | Q9 🔴纠偏 |
| ❌ Bot 收不到 reaction/群成员变动事件 | 源码未找到投递点,Reactions 字段被注释 | Q9 负向结论 |
| ❌ v1 卡片不支持 Action.Submit | 只有 v2 profile 支持 Submit 回调 | Q9 profiles.go |
| ❌ 不支持 Action.Execute/auto-refresh | 卡片白名单拒绝 | Q9 whitelist.go |
10. 相关文档
- [Bot API 概览](../04-api-integration/Bot-API概览.md) — Bot API 端点分组导航
- [OCTO Bot API 接入快速上手指南](../04-api-integration/OCTO-Bot-API接入快速上手指南-v0.1.md) — 快速上手
- [语音Speech模块](../01-product/模块说明/语音Speech模块.md) — 语音 ASR 模块详情
- [安全权限与鉴权](../99-archive/2026-09-22-v0x清零/安全权限与鉴权-v0.1.md) — Token/鉴权/限流详情
- 卡片API详解(待建设)
- 事件接收与长轮询(待建设)
11. 待确认项清单(v1.0 剩余项)
11.1 各类型 payload 字段(非Bot发送强相关类型优先级较低)
- [ ] 图片(type=2) 完整 payload 字段(url/width/height/thumbnail/format)
- [ ] GIF(type=3) payload 字段
- [ ] 小视频(type=5) payload 字段(url/duration/thumbnail/width/height)
- [ ] 位置(type=6) payload 字段(lat/lng/title/address)
- [ ] 名片(type=7) payload 字段
- [ ] 合并转发(type=11) payload 结构
- [ ] 贴图(type=12/13) payload 字段
- [ ] 富文本图文混排(type=14) payload 结构
- [ ] 文档转发卡片(type=18) payload 字段
- [ ] 截屏(type=20) payload 字段
- [ ] 文件(type=8) 除 url/name/size 外的额外字段(content_type/hash/ext)
- [ ] 文本(type=1) content 支持的 Markdown 子集
- [ ] 文本消息最大长度
11.2 发送 API 请求/响应格式
- [ ] sendMessage 成功响应体格式(message_id/seq/timestamp 字段名)
- [ ] sendMessage 错误码表
- [ ] message/edit 完整请求体格式
- [ ] 是否支持撤回消息及端点
- [ ] messages/sync 分页参数和响应格式
- [ ] client_msg_no 幂等去重语义
- [ ] stream_no 流式消息完整机制
11.3 @Mention 和回复
- [ ] mention 字段完整嵌套结构(字段名确认)
- [ ] @所有人是否需要特殊权限
- [ ] payload 内 reply 字段精确结构
11.4 限制与约束
- [ ] 图片/视频消息大小/格式/分辨率限制
- [ ] business 桶具体 RPS/Burst 值(动态配置,待运行时确认)
- [ ] 文件大小运维硬顶 512MB 配置方式
- [ ] presigned URL 有效期
- [ ] 消息历史保留策略
11.5 已关闭的 Q9 v0.1 待确认项 ✅
- ✅ Q9-01~Q9-04:完整消息类型枚举(16 个类型族全部确认)
- ✅ Q9-11:卡片支持元素白名单(8 展示元素 + 6 输入元素 + 4 动作)
- ✅ Q9-13:卡片动态改卡机制(POST /v1/bot/message/edit + card_seq CAS)
- ✅ Q9-15:发送端点确认为 POST /v1/bot/sendMessage
- ✅ Q9-24:@mention 内联格式
@[uid:displayName] - ✅ Q9-26:reply 在 payload 内,无独立 in_reply_to 顶层字段
- ✅ Q9-30:卡片限制(payload≤512KiB / body≤2MiB / 节点≤200 / 深度≤16)
版本记录
- v1.0(2026-09-22):Q9 BA-01 源码确认级升级。
- ✅ 关闭 7 项核心待确认:完整消息类型枚举(16类)、卡片白名单/限制/动态改卡、发送端点、@内联格式、reply位置
- ✅ 补充卡片 type=17 完整规格:两档profile(octo/v1, octo/v2)、8展示元素、6输入元素(v2)、4动作、4项硬性限制、动态改卡CAS机制
- ✅ 补充 Bot 管理能力:@群成员/@所有人/发私信/编辑消息
- ✅ 确认事件接收为 HTTP 长轮询(非WebSocket/Webhook)
- ✅ 确认 Bot 收不到 reaction/群成员变动事件(负向结论)
- 🔴 添加 Token 前缀 bf_ 纠偏标注
- confidence 从 low-medium 提升至 medium-high
- 剩余待确认项:payload 字段细节/响应格式/限制参数(非阻塞集成)
- v0.1(2026-09-22):框架初版。基于 P0 Q1-Q4 + P1 Q1/Q6 构建。
下一步:剩余待确认项(payload 字段/响应格式/限制参数)在后续 Bot API 使用过程中逐步补充。本文档已可作为集成开发的核心参考。