事件模型
事件信封(schema 2.0)
大多数事件(含 im.message.receive_v1)使用 schema 2.0 信封:公共字段与业务字段平铺在同一层,没有 data 包裹层。
{
"schema": "2.0",
"eventId": "evt_5f3a1c9e8b2d4a6f0c1e7d9b3a5f2c48",
"eventType": "im.message.receive_v1",
"occurredAt": 1789452760862,
"appId": "app_43e19f98e5584c51925d08fc",
"tenantId": 88,
"installationId": 1024,
"message": { }
}
| 字段 | 类型 | 说明 |
|---|---|---|
schema | string | 信封版本,当前为 "2.0" |
eventId | string | 事件唯一 ID,前缀 evt_,用于幂等 |
eventType | string | 事件类型,如 im.message.receive_v1 |
occurredAt | long | 事件发生时间,Unix 毫秒(不是 ISO 字符串) |
appId | string | 接收事件的应用 ID |
| 其余字段 | — | 各事件类型自己的业务字段,平铺写入 |
另有部分事件(如
card.interaction)仍使用 schema 1.0 信封:{"schema":"1.0","header":{"event_id","event_type","app_id","create_time"},"event":{...}}。处理时先读schema字段再决定从哪里取业务数据。
事件类型
eventType | 用途 | 所需 Scope | 信封 |
|---|---|---|---|
im.message.receive_v1 | 机器人收到单聊消息,或群内 @机器人 | event.bot.message | 2.0 |
card.interaction | 用户与机器人卡片交互 | 无(按卡片归属投递) | 1.0 |
customer.message | 客服会话产生新消息 | event.customer.message | 由平台投递时带 schema |
customer.session | 客服会话创建、关闭或转交 | event.customer.session | 同上 |
customer.agent | 客服在线状态变化 | event.customer.agent | 同上 |
im.message.receive_v1 字段清单
2.0 信封下,业务字段为 tenantId、installationId 和 message:
message 字段 | 类型 | 说明 |
|---|---|---|
messageId | string | 入站消息 ID,即回复接口 POST /api/open/v2/bot/messages/{messageId}/reply 的 {messageId} |
fingerprint | string | 消息指纹 |
chatType | string | single(单聊)或 group(群聊) |
chatId | string | 回复时的 receiveId:单聊为用户账号,群聊为群 ID |
senderId | string | 发送者账号 |
senderType | string | user 或 bot |
msgType | string | text / post / card / image / file |
content | object | 内容,结构随 msgType 变化,见下 |
mentions | array | 被 @ 的成员,元素为 {"userId":"<账号>"} |
parentMessageId | long | null | 引用的父消息 ID |
createdAt | long | 消息时间,Unix 毫秒 |
botUserId | string | 收到消息的机器人账号 |
content 按 msgType 取值:
msgType | content 结构 |
|---|---|
text | {"text":"内容"} |
post | 发送方 content 对象的键被平铺复制进来(不会多包一层 post);无法解析为 JSON 时退化为 {"text":"<原始内容>"} |
card | {"card":{...},"cardId":"...","cardVersion":1}(cardId/cardVersion 仅在按模板发送时出现) |
image / file | {"fileName":"a.png","url":"https://...","size":12345,"mimeType":"image/png"} |
text、card、image、file的content由平台按上表写入;只有post的内容完全来自发送方,服务端不校验、原样带出。发送卡片时的结构约束(schema、组件白名单等)见卡片消息。
完整报文示例:
{
"schema": "2.0",
"eventId": "evt_5f3a1c9e8b2d4a6f0c1e7d9b3a5f2c48",
"eventType": "im.message.receive_v1",
"occurredAt": 1789452760862,
"appId": "app_43e19f98e5584c51925d08fc",
"tenantId": 88,
"installationId": 1024,
"message": {
"messageId": "8229",
"fingerprint": "open_2099743187475107840",
"chatType": "group",
"chatId": "1024",
"senderId": "zhangsan",
"senderType": "user",
"msgType": "text",
"content": {"text": "@机器人 构建完成了吗"},
"mentions": [{"userId": "appbot_7f3a91"}],
"parentMessageId": null,
"createdAt": 1789452760900,
"botUserId": "appbot_7f3a91"
}
}
事件处理必须允许字段向后兼容扩展,未知字段不得导致整个事件失败。