Skip to content

Conversation Hub 统一会话 ​

Conversation Hub 是网站客服、Telegram 作者/客服和后续 IM 渠道共用的会话协议。

首次接入请从客服接入指南开始。本页是接口概览,不代表生产验收完成。

联调 API 使用 https://staging-api.open4x.com,生产 API https://api.open4x.com 需单独验收开通。开始前应验证 API、Console 和 Widget 的自定义域名均可访问。

P0/P1 接入步骤 ​

  1. 以业务系统的外部会话 ID 创建或更新会话。
  2. 由服务端签发短期 Widget Session。
  3. 绑定 Widget 渠道和 Telegram 作者/客服渠道。
  4. 注册事件 Webhook,先验 HMAC、按 event_id 去重,再持久化到事件 inbox 并记录去重标记。
  5. 统一回复接口使用稳定的 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}/participants增加或恢复会话参与者
PATCH/v1/conversations/{id}/participants/{participantId}更新参与者状态或显示信息
DELETE/v1/conversations/{id}/participants/{participantId}移除参与者并停用其渠道
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>,时间戳头为 X-Open4X-Event-Timestamp。使用独立 Webhook Secret,不使用 Bridge API Key;SDK 默认接受 300 秒时间偏差。

总共最多投递 8 次,包含首次投递。七次重试分别在上次失败后至少等待 30、60、120、240、480、960、1920 秒;定时任务实际执行可能更晚,不承诺精确到秒。单次请求超时为 10 秒,仅 HTTP 2xx 视为成功。最终失败进入 dead_letter,使用 POST /v1/conversations/events/{eventId}/replay 重放,保持原 event_id。

所有渠道投递结果还会明确返回 environment 和 dry_run。当 dry_run=true 时只是模拟结果,不能视为 Telegram 已真实送达。

完整协议见 OpenAPI 和仓库中的 Conversation Hub 文档。

定向投递 ​

公开消息支持三种范围:

模式含义
all投递给会话中的所有活动渠道,兼容旧版本默认行为
direct只投递给 recipient_participant_ids 中的参与者
relay由客服中继给指定参与者,必须提供 relay_from_message_id

订单会话建议使用 A(客户)→B(客服)、C(作者)→B 的路由。B 再明确 选择回复 A、C 或双方。Widget Session 可以携带 participant_id 和默认接收人, 浏览器不需要也不能自行选择其他参与者。

渠道绑定时应注明它代表的参与者:

json
{
  "channel_type": "telegram",
  "provider": "telegram",
  "external_channel_id": "123456789",
  "connected_account_id": "ca_...",
  "participant_id": "part_creator_1"
}

低代码 SDK ​

仓库 sdk/ 提供:

  • open4x-conversation-client.ts:服务端客户端;
  • open4x-widget.ts:不暴露 API Key 的 Widget 挂载器;
  • react/Open4XSupportWidget.tsx:React 组件封装;
  • open4x-web-component.ts:适用于原生 HTML、Vue、Svelte 等框架的 <open4x-support-widget> 自定义元素。

客户只需要提供一个服务端 Session 接口。该接口验证登录用户和订单权限, 使用 Bridge Key 调用 Open4X,再返回短期 session_token。前端随后使用 sessionUrl 或正式 Widget Loader。

SDK 还提供 createWidgetSessionForContext,可以在一次服务端调用中完成会话 upsert 和 Session 签发。客户原有的订单或工单数据库不需要为 Open4X 增加专用 表,但仍应由客户自己完成业务授权和外部 ID 映射。

接入层级可以按项目选择:零构建页面使用托管 Loader;需要自定义按钮或界面时 使用浏览器 Controller;Vue、Svelte 或普通 HTML 使用自定义元素;React 项目使用 React 组件。它们共用同一套短期 Session 协议。

同一个 Conversation Hub 支持多方会话。可以加入 customer、creator 和 support_agent,把各自的 Widget 或 Telegram 渠道绑定到 participant_id, 再用 audience_mode: direct 实现 A/B、C/B 的定向消息。需要客服中继时,使用 relay 和 relay_from_message_id,由客服明确选择消息接收人。