Skip to main content

功能简介

YCloud 的 WhatsApp Calling API 用于管理 WhatsApp 用户与商业电话号码之间的语音通话信令。您的应用程序通过 YCloud 交换 SDP,而由您的 WebRTC 实现来处理音频连接。 通话可以从任一方向发起:
  • 用户发起: WhatsApp 用户致电您的企业。您的应用程序接收提议(offer)并接听或拒绝该通话。
  • 企业发起: 您的应用程序创建一个提议(offer)并请求 YCloud 致电 WhatsApp 用户。
Calling API 仅处理通话信令,不处理 WebRTC 媒体堆栈。您的应用程序负责对等连接建立、音频采集与播放、SDP 生成以及 WebRTC 资源清理。

API 全景

Calling API 和 Webhook 事件遵循相同的生命周期,但并不构成适用于每个通话的单一固定序列。完成通用设置后,按照用户发起或企业发起的流程进行操作。使用通话 ID(wacid)来关联每个操作和事件。

通用设置

用户发起的通话

企业发起的通话

通用通话结束处理

可选媒体处理

这些表格描述了应用程序的工作流。它们并不保证 Webhook 的传送顺序会与表格行完全一致。请通过 wacid 关联事件并以幂等方式处理重新推送。

准备工作

在发起 Calling 请求之前,请准备好以下内容:
  1. YCloud 账户 API 密钥。在 X-API-Key 标头中发送它。参见身份验证。
  2. 在 YCloud 注册的 WhatsApp 商业账户和商业电话号码。
  3. 已为该电话号码启用 Calling 功能。
  4. 能够创建和应用 SDP offer 及 answer 的 WebRTC 音频实现。
  5. 订阅了您集成所需的 Calling 事件的 YCloud Webhook 端点。参见配置 Webhook。
  6. 当企业发起的通话需要用户通话权限时,需具备该权限。
联系您的 YCloud 客户代表以开通 Calling API 访问权限。有关外呼资格,请遵循当前的 Calling 要求,包括商业资产(Business Portfolio)的 2,000 名客户消息层级以及受支持的商业号码国家/地区。原先的 1,000 次会话门槛已被当前要求取代。 以下示例使用这些环境变量:
请将 API 密钥保存在服务器上。切勿将其放入浏览器或移动应用程序代码中。

工作原理

首先配置商业电话号码。然后根据通话方向交换 SDP。API 响应会确认单个信令操作,而 Webhook 事件则报告状态更改和最终结果。如果启用了捕获功能,单独的事件会指示录音或转录何时可供下载。

请求

配置商业电话号码

通话和捕获设置归属于特定的 WhatsApp 商业电话号码。处理通话前请先对其进行配置。

读取 Calling 设置

使用 GET /whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/settings 检查 Calling 是否已启用以及 Calling 图标是否可见:
如果省略 type,YCloud 会返回 Calling 设置响应。

启用 Calling

在开始接听或拨打通话前,使用 POST /whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/settings 保存 Calling 设置:
响应包含已保存的 calling 对象。在处理实时通话之前,请完成 Webhook 和 WebRTC 会话的配置。

配置录音和转录

捕获设置适用于源自 API 的新通话。您可以启用录音、转录或两者均启用。
若要读取捕获设置,请使用 type=capture:
您可以在同一个 POST 请求中包含 calling 和 capture。验证电话号码的访问权限后,YCloud 会尝试分别保存每个部分。如果任一部分保存失败,另一部分可能已经存储。发生错误后请读取两项设置,然后仅重试仍需更新的部分。

处理用户发起的通话

用户发起的 Calling 流程 在用户发起的通话中,WhatsApp 会发送 SDP offer。您的应用程序应答该 offer,然后接听或拒绝该通话。

1. 接收 connect 事件

订阅 whatsapp.call.connect。用户发起的事件会将 direction 设置为 USER_INITIATED,并包含 SDP offer。
将 callingConnect.wacid 和 callingConnect.phoneId 一同存储。将收到的 SDP offer 应用到您的 WebRTC 对等连接,并创建 SDP answer。

2. 预接听通话

创建 SDP answer 之后、坐席接听通话之前调用 pre-accept(预接听)。这会准备好媒体路径,并能减少接听通话时的音频卡顿或截断。 端点: POST /whatsapp/calls/preAccept
预接听成功后,请让通话保持在振铃或就绪状态。预接听并不会为用户接通通话。

3. 接听通话

当坐席接听时,向接听端点发送相同的 phoneId、wacid、SDP 类型和 SDP 应答 (answer)。 端点: POST /whatsapp/calls/accept
请求字段和响应结构与预接听相同。响应成功后,根据 WebRTC 连接状态判断媒体是否就绪,并等待 whatsapp.call.terminate 获取最终通话结果。 文档记录的呼入接听窗口期约为收到 connect Webhook 后的 30–60 秒。请及时接听;未接听的通话将在用户端以 未接听 通知结束,并触发 terminate Webhook。 即使 WebRTC 连接已建立,也仅在接听请求返回 HTTP 200 后才开始发送音频。过早开始可能会导致前几个字被截断;过晚开始则会导致静音。

拒接而非接听

如果坐席无法接听呼入电话,请将其拒接,而不是创建活跃会话。 端点: POST /whatsapp/calls/reject
响应使用标准通话响应格式。请求完成后释放本地对等连接(peer connection),如果后续收到该 wacid 的终止事件,仍应正常接收处理。

发起企业呼叫

在企业呼叫中,您的应用程序创建 SDP 提议 (offer) 并将其发送给 YCloud。

获取呼叫权限

在发起呼叫之前,请先获取用户的呼叫权限。在有效的客户服务窗口期内,可以发送交互式权限请求:
将此请求体发送至 POST /v2/whatsapp/messages/sendDirectly 或使用 POST /v2/whatsapp/messages 加入队列。 您也可以创建呼叫权限模板。例如,将此请求体提交至 POST /v2/whatsapp/templates,然后等待审批:
发送包含请求体参数的已审批模板:
当电话号码的呼叫设置中启用了 callback_permission_status 时,用户发起的呼叫可以授予回拨权限。用户也可以通过商业资料授予永久呼叫权限。 权限回复以 whatsapp.inbound_message.received 事件的形式送达。请检查 interactive.call_permission_reply 对象,而不仅仅是确认权限请求消息是否送达:
被拒绝或权限过期后请勿发起呼叫。Meta 错误 138006 表示商业号码缺少所需的呼叫权限。有关服务商错误的详细信息,请参阅 Meta 的呼叫错误。

1. 创建 SDP 提议 (offer)

创建本地 WebRTC 对等连接并附加音频轨道。生成 SDP 提议 (offer),将其设置为本地描述 (local description),并在该操作完成后再将提议发送至 YCloud。

2. 发起通话连接

端点: POST /whatsapp/calls/connect 请提供 to 或 recipient 中的至少一项。如果两者均提供,YCloud 将使用 to 并忽略 recipient。
请立即存储返回的 wacid。success: true 表示连接操作已被接受,并不代表用户已接听。

3. 应用应答并跟踪呼叫尝试

YCloud 会为该通话发送 whatsapp.call.connect。对于企业发起的通话,该事件包含 direction: BUSINESS_INITIATED 并携带远端 SDP answer。将该应答作为同一对等连接的远端描述应用。 订阅 whatsapp.call.status.updated 以跟踪该尝试:
确保事件处理具备幂等性,以便重新投递时不会重复执行客服操作、计费或清理。

终止进行中的通话

当您的应用程序需要结束进行中的呼入或呼出通话时,调用 terminate。 端点: POST /whatsapp/calls/terminate
请求字段与拒接请求一致。成功的响应确认 YCloud 已处理该终止操作。请保持通话记录开启,直到收到最终的终止事件或由您自己的恢复策略将其关闭。

响应

所有五个信令端点都返回相同的响应结构:
wacid 标识与该操作关联的通话。success: true 确认信令操作成功;并不确认另一方参与者已接听或通话已完成。请使用 WebRTC 状态和呼叫 Webhook 事件来获取这些结果。

处理最终通话事件

whatsapp.call.terminate 是通话的生命周期终止事件。
收到此事件时,请完成通话记录并释放所有剩余的 WebRTC 资源。早前的 API 响应并不确认通话已完成。

接收录音与转录

启用捕获后,媒体处理会在通话生命周期结束后继续进行。录音和转录具有各自独立的终止事件: 以下示例显示了一个可用的录音:
两个有效载荷属性使用相同的字段:

下载可用资产

仅在相应事件报告 AVAILABLE 之后,再调用媒体端点。 端点: GET /whatsapp/calls/media/{mediaAssetId}
该端点以附件形式返回完整文件,不支持字节范围下载。录音使用 .ogg;转录使用 .json。 只有所属的 YCloud 租户才能下载资产。资产自创建之日起保留 30 天可用。缺失、不可用、过期或非所属资产将返回 HTTP 404。

构建可靠的 Webhook 接收器

让您的端点订阅集成所需的事件:
对于每个请求:
  1. 保留原始请求体,并在信任该事件之前验证 YCloud-Signature。
  2. 持久化存储该事件或将持久任务加入队列。
  3. 及时返回成功的 2xx 响应。
  4. 按顶级事件 id 进行去重。
  5. 通过 wacid 关联通话数据;并保留 phoneId 以供后续操作使用。
  6. 妥善处理时间间隔极短的相关事件,并容忍重复投递。
有关端点创建、签名验证和投递行为,请参阅配置 Webhook。Webhook 有效负载示例页面包含完整的生成示例。

处理错误与恢复

通话端点使用 YCloud 的标准 API 错误响应。有关响应结构和重试指引,请参阅处理错误。 排查常见通话故障时,请参考以下检查项: 请求超时并不代表信令操作失败。在重试之前,请结合 Webhook 事件和当前本地通话状态进行对账核对。该操作可能已经送达 WhatsApp。

集成核对清单

  • 在正确的商业电话号码上启用通话功能。
  • 配置并测试所有必需的通话 Webhook 订阅。
  • 验证 Webhook 签名并对事件进行去重。
  • 将 wacid、phoneId、呼叫方向和当前状态一并存储。
  • 将 API success 视为操作已受理,而非最终通话结果。
  • 仅将 preAccept 用作准备阶段;调用 accept 进行接听。
  • 在收到 whatsapp.call.terminate 后完成通话结束处理。
  • 仅在收到 AVAILABLE 事件后且在 30 天内下载录制的媒体文件。
  • 在拒绝、挂断、失败以及本地超时情况下释放 WebRTC 资源。
  • 避免在常规应用程序日志中记录 API 密钥、完整 SDP 或参与者标识符。

Calling API 参考

查看每个 Calling 端点的具体请求和响应结构规范。

Webhook 有效负载示例

查看基于 Webhook 规范生成的完整通话事件示例。