Conversation Hub 统一会话
Conversation Hub 是网站客服、Telegram 作者/客服和后续 IM 渠道共用的会话协议。
P0/P1 接入步骤
- 以业务系统的外部会话 ID 创建或更新会话。
- 由服务端签发短期 Widget Session。
- 绑定 Widget 渠道和 Telegram 作者/客服渠道。
- 注册事件 Webhook,先验 HMAC、按
event_id去重,再写入业务 outbox。 - 统一回复接口使用稳定的
client_message_id,需要引用时传reply_to_message_id。
API Key 和 Connected Account 只能保存在服务端,浏览器只能拿 Widget Session Token。
主要接口
| 方法 | 接口 | 用途 |
|---|---|---|
POST | /v1/conversations | 按外部 ID 创建或更新会话 |
POST | /v1/conversations/{id}/widget-session | 签发 15–60 分钟 Widget Session |
POST | /v1/conversations/{id}/channels | 绑定 Widget 或 Telegram 渠道 |
POST | /v1/conversations/{id}/messages | 发送公开消息或内部备注 |
GET | /v1/conversations/{id}/messages | 分页查询历史消息 |
GET | /v1/conversations/events | 租户级增量事件读取 |
POST | /v1/conversations/webhooks | 注册签名事件 Webhook |
POST | /v1/conversations/telegram/identities/bind | 创建一次性 Telegram 绑定链接 |
GET | /v1/conversations/credentials/status | 在不暴露密钥的情况下验证 API Key 策略 |
GET | /v1/conversations/inbox | 查询租户客服工作队列 |
PATCH | /v1/conversations/{id} | 更新状态、优先级或语言 |
POST | /v1/conversations/{id}/assignments | 分配或转接作者/客服 |
POST | /v1/conversations/{id}/presence | 上线、输入中、离开、离线状态 |
POST | /v1/conversations/{id}/messages/{messageId}/receipts | 写入送达/已读回执 |
POST | /v1/conversations/deliveries/{deliveryId}/retry | 重试死信投递 |
GET | /v1/conversations/{id}/deliveries | 查询渠道投递状态和错误 |
POST | /v1/conversations/attachments/{attachmentId}/scan-result | 写入租户病毒扫描结果 |
API Key 按需使用 conversation:read、conversation:write、conversation:events:write。
Telegram 双向闭环
Knoveria 创建绑定链接,作者或客服打开 Bot 后,Open4X 产生 telegram.identity.started。Knoveria 再把该 Telegram Chat 绑定到目标会话。Telegram 入站消息只写入一次,投递时跳过来源渠道并实时推送到 Widget;反向也一样。
Telegram 私聊必须由用户先启动 Bot。Bot Token 保存在加密的 telegram-bot Connected Account 中,不进入浏览器。
telegram.identity.started 事件包含 binding_id、identity_id、 external_user_id、external_chat_id、telegram_user_id、 participant_id,以及事件信封中的 event_id 和会话内递增的 sequence。
运营与附件
分配使用 Knoveria 自有的作者或客服 ID,并且只在当前租户会话内生效。传入 replace_active_role: true 时,会先结束同角色的其他活动分配。在线/离开状态最长 120 秒,输入中最长 15 秒,建议由前端定时心跳。回执只允许 sent → delivered → read 单向推进。
附件只能传租户自己的 storage_key 或公开 HTTPS 下载地址,同时提供文件名、MIME 和大小。Open4X 不会主动抓取任意 URL。附件初始为 pending,由租户扫描服务调用 scan-result 标记为 clean 后,才允许渠道适配器暴露文件;当前文本投递链路不宣称所有渠道的二进制文件都已完整支持。
幂等和 Webhook
使用 client_message_id 处理网络重试:相同内容返回原消息,内容变化返回 409。内部备注必须使用 visibility: internal,永远不会投递给用户或作者。
Webhook 签名原文为 <unix_timestamp>.<raw_body>,请求头为 X-Open4X-Event-Signature: sha256=<hex>。最多重试 8 次,最终失败进入 dead_letter,可通过事件重放接口恢复。
所有渠道投递结果还会明确返回 environment 和 dry_run。当 dry_run=true 时只是模拟结果,不能视为 Telegram 已真实送达。
完整协议见 OpenAPI 和仓库中的 Conversation Hub 文档。