机器人快速接入
机器人是开放平台应用身份,不是固定系统账号。推荐按以下顺序实现:
- 创建
BOT类型应用并保存凭证(appId、credentialId、appSecret)。 - 在控制台「机器人」页配置机器人资料(
displayName、avatar等),并申请最小 Scope:bot.installation.read、bot.message.send、bot.message.reply、event.bot.message。 - 订阅
im.message.receive_v1事件并填写 Webhook 地址,保存时会一次性返回 Webhook Secret。 - 提交应用,等待审核通过进入
ACTIVE。 - 将机器人安装到目标会话(群或用户)。安装后调用
GET /api/open/v2/bot/installations取得receiveId。 - 使用
POST /api/open/v2/bot/messages主动发送,或用POST /api/open/v2/bot/messages/{messageId}/reply响应 Webhook 中的入站消息。
第 5 步:安装机器人并取得 receiveId
receiveId 不是应用自有的标识,而是目标会话的 ID,必须由安装关系推导:
- 用户在蓝答客户端安装机器人到群或个人会话(与普通机器人一致);或
- 开发者在控制台「机器人 → 安装范围」中,为指定企业成员安装。
控制台这批接口使用开发者登录态而不是应用签名:基地址 https://imo.lanchr.com/api/open/console/v1,请求头带 Authorization: Bearer <accessToken> 与 X-Open-Tenant-Id: <租户ID>(见鉴权与签名 → 控制台 API)。
| 接口 | 方法 | 说明 |
|---|---|---|
/apps/{appId}/bot-installations | POST | 安装给某个成员,请求体 {"username":"<成员账号>"} |
/apps/{appId}/bot-installations | GET | 查询安装关系,可选 targetType、status、page(默认 1)、pageSize(默认 20,最大 100) |
/apps/{appId}/bot-installation-members | GET | 列出尚未安装该机器人的在职成员(username、name),用于选择安装对象 |
username 是企业成员账号(不是手机号、不是昵称),可以先用 bot-installation-members 查出可用账号。
安装成功后,用应用凭证调用安装关系接口(需要 Scope bot.installation.read):
GET /api/open/v2/bot/installations?targetType=GROUP&status=ACTIVE
返回的 items[].targetId 就是发消息要用的 receiveId,items[].targetType 决定 receiveIdType(GROUP→group_id,USER→user_id)。未安装或已卸载的目标发送时返回 403 + 400008。
第 6 步:响应消息与幂等
订阅 im.message.receive_v1 后,用户给机器人发消息或群内 @机器人会投递事件。事件内 message.messageId 就是回复接口路径里的 {messageId},message.chatId 就是回复时的 receiveId。
- 发送幂等:主动发送时设置业务侧
clientMessageId(最长 64)。相同clientMessageId重发不会产生新消息,也不会报错——响应中duplicate: true并返回原messageId。 - 接收幂等:Webhook 至少按
eventId去重,消息业务逻辑再按message.messageId去重。Webhook 可能因为网络超时被重复投递。 - 回复约束:
reply只能回复已投递给本应用的入站消息(否则403+400008「消息未投递给此应用」),且请求中的receiveIdType/receiveId必须与父消息的目标一致(否则403「回复目标与父消息不匹配」)。
@ 提醒(mentions)
content.mentions 用于在消息里 @ 指定成员,取值为账号数组。两种写法都支持,可混用:
{"mentions": ["user_account_1", "user_account_2"]}
{"mentions": [{"userId": "user_account_1"}, {"userId": "user_account_2"}]}
- 它不限于
text消息,post/card/image/file同样有效; - 重复账号会自动去重,空值被忽略;
- 对象形式只读取
userId字段,其余字段会被忽略。
文件消息
图片和文件先调用 POST /api/open/v2/bot/files(multipart/form-data,表单字段名固定为 file)上传,获得 fileKey,再把 fileKey 放进消息内容:
- 图片:
{"msgType":"image","content":{"fileKey":"file_xxx","width":100,"height":100}} - 文件:
{"msgType":"file","content":{"fileKey":"file_xxx"}}
fileKey 有效期 10 分钟、仅限上传它的应用使用,单文件最大 20 MiB(超出返回 400);上传接口整体请求体上限约 22 MiB(超出返回 413)。过期或跨应用使用会在发送时返回 403 + 400008「fileKey无效或已过期」。
消息类型
机器人 V2 支持 5 种 msgType:text、post、card、image、file,content 结构各不相同,详见 机器人 API V2。传入其他值会返回 400 + 400006「不支持的msgType」。
msgType | content |
|---|---|
text | {"text": "文本内容"} |
post | 富文本对象,整个 content 原样透传 |
card | {"card": {...}} 或 {"cardId": "<控制台卡片模板ID>"} |
image | {"fileKey": "file_xxx", "width": 100, "height": 100} |
file | {"fileKey": "file_xxx"} |
post 服务端不校验结构,整份 content 会被透传给客户端(按 CUSTOM 类型存储)。其内部结构由你与客户端约定,平台不提供 schema 校验或字段白名单。
card 的结构有明确约束(schema 必须为 "2.0"、组件 tag 有白名单、体积与嵌套有上限),并且发送后可以原地更新或撤回,完整规则见卡片消息。