Files

7.4 KiB
Raw Blame History

OneTalk 结构化消息信息采集分类

Goal

在 OneTalk 已有文本、图片和文件消息采集之外,增加名片、询盘和订单三种已观察到的业务卡片类别;每个类别只能产生经批准的白名单化信息,不能让原始 SDK 对象、正文、签名或未批准字段跨越 MAIN-world 边界。

Confirmed Facts

  • 2026-09-11 的 Chromium CDP 只读 SDK 观察确认三种历史消息必须用联合条件识别:名片 messageType=rec/type=1/viewType=0/msgType=10010/subType=57/cardType=1;询盘为 subType=50/cardType=6;订单为 subType=59/cardType=9msgType=10010 本身不是充分条件,附件也属于该卡片族。
  • 当前 MAIN-world 内容归一化只支持 text、image 和 cardType=12 的 file;其余业务卡片会返回 unsupported_skipped,随后在批处理中只计数而不会跨层传递。
  • 名片样本的 contact 含显示名、公司、国家/地区代码及头像 URL 候选;运行态复核确认这些字段对应登录人/发送者资料,而不是与当前会话关联的客户资料,不能作为名片内容来源。未验证独立邮箱字段或可复用的正文格式。
  • window.__conversationListData__ / 联系人资料采集与消息历史采集可能异步到达;不能在消息观察时把两者拼成一条名片消息。客户资料必须沿独立 profile ledger 按 [channelAccountId, conversationId] 保存。
  • 询盘样本的 params 只观察到加密的询盘/贸易关联标识和若干来源字段;商品标题、数量、需求和图片仅存在于当前可见 DOM,不能成为稳定消息合同。
  • 订单样本有可解码的 Base64-UTF-8-JSON 摘要,包含订单/实付金额与币种、状态键、动作和部分付款阶段;只有 D3 列出的订单关联字段可跨边界,签名、参与方标识和完整 payload 仍不可跨边界。

Requirements

  • R1:为名片、询盘和订单定义互斥、可验证的信息采集类别;类别判断必须要求完整的 SDK 联合判别条件,不能通过 msgType=10010 或 UI 文本猜测。
  • R2:继续在 MAIN world 内完成卡片识别、受控解码与白名单投影;名片在页面桥、Service Worker、持久化和 Bright 消息事实中只能传递 { version: 1, kind: "business_card" } marker。客户资料走独立 profile ledger,Mind 读取时才按同账号同会话关联并以内存方式扩展 view;任何边界都不能传递原始 messagecontentoriginalData.paramscontact 整体、sign、加密标识、令牌或序列化原始对象。
  • R3:未知或不匹配 schema 的业务卡片必须保持显式、可观测的 unsupported / anomaly 结果;不得伪装为文本、文件、空订单或空询盘。
  • R4:保留已有文本、图片、文件和 cardType=12 附件识别语义;新类别不得扩大 D2 以外的联系人资料、媒体 URL 或业务详情采集范围。
  • R5:为每一种纳入 MVP 的类别覆盖:完整匹配、相同 msgType 的相邻类别不误判、异常解码或 schema、白名单边界及跨层合同。

Product Direction

  • D1:本期目标是尽可能采集对业务有用的原始消息信息;用户要求先共同确认逐类采集边界。
  • D2:名片消息事实只纳入 { version: 1, kind: "business_card" } marker。contact.namecontact.companyNamecontact.complianceCountryCodecontact.fullPortrait 不从历史条目的 item.contact 采集,也不写入 message content;对外读取时,服务端可从同一 channelAccountId + conversationId 的当前 profile ledger 以内存方式补出 contactNamecompanyNamecountryCodeavatarUrl 四项。没有 profile 返回 markerprofile 单字段缺失返回 null,不回退到登录人资料。
  • D3:订单卡片纳入订单金额及币种、实付金额及币种、statusMessageKey、动作列表的名称/状态键和可用 payStep,以及 orderIdcontractIdbizCodeidtenant 订单关联字段。嵌套 Base64 摘要仍只在 MAIN world 解码;跨层只传其白名单投影。
  • D4:询盘本期只归类,暂不纳入专有业务字段;既有 unsupported / anomaly 路径须保持可观测,不能伪造为空询盘内容。
  • D5:所有已接纳类别继续使用现有通用消息事实:messageIdconversationIdsenderIddirectionsentAtMsparticipantIdsreadStatusmessageStatusunreadCountchannelAccountId 是插件帧/耐久键的账号作用域,而非消息内容字段。分类扩展不得删改这些字段的身份、时间和去重语义。
  • D6(约束):这不授权透传原始 SDK 对象或序列化原始 payload。任何跨 MAIN-world 的字段必须逐字段白名单投影;sign、令牌、完整 contact、完整 params 和原始正文仍默认禁止。头像 URL 只允许作为独立 profile ledger 的批准字段,并在读取 view 中按既有 URL 校验与 null 语义返回,不得写入消息事实。
  • D7:业务卡原始消息的 content 不在本期采集范围:不得解析、持久化、跨层传递或据此推断结构化字段。此限制只作用于本期新业务卡;既有纯文本消息的 content.kind = "text" 归一化和传递语义保持不变。
  • D8:名片、询盘和订单只从已观察到完整联合判别条件的 SDK 历史扁平消息采集。WebSocket raw 路径本期不改动,继续使用既有 text/image/file 归一化和 unsupported 结果;不得以 custom.type=10010cardType 或 UI 文本猜测新类别。
  • D9:名片 content 只保存 marker;既有 contact.profile.observed / onetalk_contact_profile 是会话当前客户资料的唯一 owner。读取服务按账号+会话以内存组合 marker 与 profile view,绝不把 view 写回消息事实,也不把消息观察到的登录人/发送者资料写入 profile ledger。

Out of Scope

  • 从卡片 DOM、普通字符串 content 或页面按钮反推商品标题、数量、需求、详情链接、地址、邮箱或人类可读状态。
  • 采集或持久化加密 ID、sign、聊天令牌、完整联系人对象、完整订单/询盘 payload、原始 URL 或正文。
  • 改动 WebSocket raw 卡片的识别、采集或实时投递;此路径需要独立运行态观察后再设计。
  • 声称三个单样本观察构成 OneTalk 的全局消息类型枚举或上游 API 合同。
  • 改动既有 buyer-facts 的 DOM 采集语义,除非后续确认需要且单独设计兼容边界。

Acceptance Criteria

  • 三类业务卡各有精确、测试覆盖的历史 SDK 联合判别条件,且不会把附件或其它 msgType=10010 卡片误归类;WebSocket raw 行为不变。
  • 名片 marker、读取时客户资料 view、订单白名单字段和仅分类的询盘各有明确的跨层合同与来源语义;敏感字段与未验证字段不能通过桥、持久化或服务端输入验证。
  • 名片消息落库只含 kind/version;读取时无客户资料仍返回 marker,部分资料只返回对应 null 字段,且不会使用登录人 contact 或异步页面 map 作为 fallback。
  • Base64 订单摘要的大小、编码、JSON 和 schema 失败均得到显式可观测结果,绝不静默变为“无订单”。
  • 已有 text/image/file 与 unsupported 行为回归通过;不需要新类别的信息仍保持原样。
  • 任务规划在实现前明确 MVP 字段范围、兼容策略、测试边界及未覆盖的运行态变体。