← 所有文章
教程

用 account.profile.updated 同步 WhatsApp 自身账号名称

要在应用中同步已连接 WhatsApp 账号自己的名称,应处理 UnifyPort 的 account.profile.updated 事件,读取 data.profile.display_name。该名称优先取业务名称,再回退到推送名称。更新的是账号资料展示,不是客户联系人、内部账号标签或连接状态。文档描述的触发来源是 WhatsApp 名称事件,不能将它当作所有渠道通用的资料变更通知。

要点

  • 用工作空间、provider 和 account_id 定位账号,不用显示名称作为标识。
  • 账号配置的 name 与渠道公开名称分别保存。
  • full_sync 表示资料来源,不代表消息历史恢复完成。
  • 收到资料事件不能证明授权有效或连接正在运行。

先确定界面显示的是哪个名称

跨境客服的账号选择器可以同时展示团队内部标签和渠道公开名称。一次改名不应悄悄改变负责人、路由或权限。

值或事件含义建议展示位置
账号配置 name通过账号配置维护的标签内部账号选择器
data.profile.display_name根据渠道资料生成的公开名称独立的渠道名称行
data.profile.business_name / push_name事件文档中的名称组成部分可选的资料详情
contact.updated联系人通讯录名称客户联系人视图
account.status.updated授权或运行时状态连接健康视图

联系人名称同步教程处理的是客户一侧的数据,不能直接复用为自身账号资料处理器。客户消息中的发送者名称也不能作为自身账号改名的证据。

获取账号文档分别返回账号配置与 provider_profile,可作为界面的初始读取。公开名称缺失时显示“暂不可用”,不要把内部标签伪装成已观测到的公开名称。

正确理解 account.profile.updated

以下载荷取自事件参考的示例结构,数值和名称是文档示例,不是真实客户记录:

{
  "id": "evt_profile_7e91d2c4",
  "type": "account.profile.updated",
  "provider": "whatsapp",
  "account_id": "acc_8c21d0",
  "occurred_at": "2026-08-28T09:51:51Z",
  "data": {
    "account": { "provider_account_ref": "provider_account_example" },
    "profile": {
      "display_name": "Example Business",
      "business_name": "Example Business",
      "push_name": "Example Account"
    },
    "event": {
      "kind": "account_profile_updated",
      "source": "self_rename"
    }
  }
}

优先使用已提供的 display_name,不要另外实现一套冲突的名称优先级。业务名称优先时,即使 push_name 变化,显示名称也可能不变。

data.event.source 的两个文档值分别表示:

  • self_rename:已连接账号修改了自己的名称。
  • full_sync:资料来自完整同步快照。

它们均不能确定是哪位人员操作,不应据此生成虚构的操作人审计记录。full_sync 也不意味着全部消息、联系人、头像或其他账号数据都已同步。

单独构建账号资料视图

建议按以下顺序实施:

  1. 先订阅,再依赖更新。 在所需事件集合中加入 account.profile.updated,保留已有订阅和签名配置。事件过滤指南解释了显式列表与通配符的区别。
  2. 验签并持久化。 按投递约定,用 signing_secret 校验 X-Device-Timestamp、句点和原始请求体构成的十六进制 HMAC-SHA256,并检查时间戳新鲜度。可靠保存已认证事件后再返回 2xx。
  3. 定位现有账号。 使用接收器的工作空间上下文,以及信封中的 provider 和 account_id。新名称不能创建第二个账号,也不能让会话迁移到另一个账号。
  4. 只更新资料展示。 不改内部标签、客户名称、授权或运行时状态。将名称作为文本渲染,而非 HTML。
  5. 本地记录来源。 在视图旁保存事件 ID、发生时间和来源。这些是应用侧记录设计,不是新增 API 字段。

下面的 JavaScript 仅从已验签事件中提取名称,不包含存储、排序或完整接收服务:

function profileNameCandidate(event) {
  if (event.type !== 'account.profile.updated' ||
      event.provider !== 'whatsapp') return null;
  if (typeof event.account_id !== 'string' || !event.account_id) {
    throw new Error('Missing account identity');
  }
  const name = event.data?.profile?.display_name;
  if (typeof name !== 'string') {
    throw new Error('Profile display name needs review');
  }
  return { accountId: event.account_id, displayName: name };
}

返回对象的键是应用变量。名称缺失或类型错误时,保留事件供排查,不要用默认值替换整个资料对象。空字符串可按明确的本地策略展示为“名称暂不可用”;不要把联系人事件的字段清空规则套到此契约。

处理旧事件与初始化读取

普通事件重试按事件 ID 去重。投递顺序没有保证:应用资料事件时按 occurred_at 排序,同时间用事件 ID 确定顺序,并将去重记录与视图修改一并提交。

这里没有文档保证 REST 读取和 Webhook 共享同一资料版本号。若初始化读取尚未返回时已应用新事件,不要让迟到的读取覆盖它。可以串行协调初始化与事件处理,或把读取作为基线,再应用缓冲事件。观测冲突时标记为待核对,而不是声称已还原上游的绝对顺序。

UnifyPort 提供非官方接口。此事件不是修改原生资料的指令,不是完整资料档案,也不保证遗漏事件可重放。LINE、Zalo、Telegram 或 whatsapp-protocol 使用相似信封,不代表支持此事件。

常见问题

为什么 push_name 改了,display_name 没变?

文档规定优先使用 BusinessName,再回退到 PushName。先检查提供的名称组成部分,不要直接判定同步失败。

full_sync 是否表示消息历史完整?

不是。它只标识本次资料事件的来源,不说明消息历史完整性或恢复结果。

收到事件后,要用 PATCH 修改账号 name 吗?

不应作为自动同步步骤。这样会修改账号配置,而不是仅展示渠道名称。内部标签修改应由明确、独立的操作触发。

下一步与参考资料

根据账号资料事件参考实现账号卡片。建议测试两种来源、不同业务与推送名称、重复和旧事件、缺失或空名称,以及迟到的初始化读取;确认联系人、内部标签和连接状态不变。这些是待执行检查,不是已报告的测试结果。

资料核对日期:2026-11-05。

UnifyPort API

让消息接入变成一条稳定的产品管线。

先用统一 API 跑通发送,再用标准事件把所有入站消息接回业务系统。