概念和问题排查

本页详细介绍了集成所需的特定配置,以及常见问题的排查方法。

电话网络要求

如果您的网络会过滤出站流量,则必须允许 SIP 信令的出站流量和媒体流的出站流量。

对于 SIP 信令,应允许通过端口 5672 (TCP) 的整个 IP 范围 74.125.88.128/25。如需设置限制性更高的防火墙规则集,您可以将 SIP 信令限制为仅发送给一个或多个区域化 GTP SIP 服务器:

  • 美国区域:us.telephony.goog (74.125.88.132)
  • 欧盟区域:eu.telephony.goog (74.125.88.133)
  • 亚太区域:ap.telephony.goog (74.125.88.134)
  • 南美洲区域:sa.telephony.goog (74.125.88.135)

对于 RTP 媒体,您必须配置防火墙规则,以允许流量到达 CIDR IP 范围 74.125.39.0/24。通常,媒体所需的端口仅为 16384-32767 (TCP+UDP),但此端口范围将来可能会扩大。

支持的 SBC 供应商或型号

下表列出了支持的 SBC 供应商或型号以及固件版本。每个供应商的详细集成说明都链接在固件版本中。

供应商和型号 固件版本
AudioCodes VE SBC v7.40A.500.786
Avaya Session Border Controller for Enterprise v8.1.3.2-38-22279v10.2.0.0-86-24077
Oracle E-SBC Acme Packet 3900 SCZ9.3.0 GA(Build 46)
Ribbon Swe Core SBC v11.01.01R005
Cisco Unified Border Element (CUBE) v17.15.03a

支持的 SBC 信令和媒体协议

信令协议 基于 TLS 的 SIP
媒体 SRTP
媒体加密 SDES
支持媒体加密套件 AES_CM_128_HMAC_SHA1_80、AEAD_AES_256_GCM
支持的媒体编解码器 G.711 µ-law (PCMU)、G.711 A-law (PCMA)、Opus

SIP 标头

当您设置对话配置文件和手机号码时,您创建了一个 CCAI 对话配置文件,并将 sipConfig.createConversationOnTheFly 设置为 true。对话 ID 应在 SIP INVITE 期间使用 Call-InfoUUI 的 SIP 标头值动态生成。

SIP 标头值通过定义Google Cloud 项目 ID 和对话 ID 指向 Dialogflow 端点:

  1. Google Cloud 项目 ID 是您在设置 Google Cloud 项目时使用的项目。
  2. 对话 ID 应由 SBC 动态生成。对话 ID 必须符合正则表达式公式 [a-zA-Z][a-zA-Z0-9_-]*,且字符长度介于 [3,64] 之间。如需动态生成对话 ID,一种常见做法是使用 SIP INVITE 中的 Call-ID 值,并在其前面添加字母,使其符合之前指定的正则表达式。例如,如果 Call-ID 值为 297363723_79131759_799783510,则在 Call-ID 值前添加 "CID-" 前缀可使其符合正则表达式 [a-zA-Z][a-zA-Z0-9_-]*

Call-Info SIP 标头

在 SIP INVITE 中插入名为 Call-Info 的自定义 SIP 标头,以唯一设置对话 ID:

Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/$PROJECT_ID/conversations/$CONVERSATION_ID>;purpose=Goog-ContactCenter-Conversation

示例:

Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/gcp-project-id-12345/conversations/CID-297363723_79131759_799783510>;purpose=Goog-ContactCenter-Conversation

UUI SIP 标头

如果不支持设置自定义 SIP 标头 Call-Info,您可以在 SIP INVITE 中配置 UUI (User-to-User) SIP 标头,以传入对话 ID。

使用 Call-Info 中请求的相同数据,但网址以十六进制编码,并将用途设置为 Goog-ContactCenter-Conversation。以下是一个示例标头,其中十六进制字符串在解码后为 http://dialogflow.googleapis.com/v2beta1/projects/gcp-project-id-12345/conversations/CID-297363723_79131759_799783510

User-to-User: 687474703a2f2f6469616c6f67666c6f772e676f6f676c65617069732e636f6d2f763262657461312f70726f6a656374732f6763702d70726f6a6563742d69642d31323334352f636f6e766572736174696f6e732f4349442d3239373336333732335f37393133313735395f373939373833353130;encoding=hex;purpose=Goog-ContactCenter-Conversation

如果需要将其他数据传递到对话式代理并将其设置为会话参数,您可以传递以分号分隔的键值对列表(采用十六进制编码),然后添加 ;encoding=hex;purpose=Goog-Session-Param。这样一来,系统会创建一个名为 uui-headers 的会话参数,其中包含解码后的载荷字符串列表。

例如,如果需要传入字符串 key1=value1;key2=value2,则会发送以下 UUI 标头,其中载荷是 key1=value1;key2=value2 的十六进制编码值。

User-to-User: 6B6579313D76616C7565313B6B6579323D76616C756532;encoding=hex;purpose=Goog-Session-Param

这会创建以下会话参数。

{
    "uui-headers": ["key1=value1;key2=value2"]
}

如果您的 SBC 支持发送多个 UUI 标头,则可以为每个 UUI 标头发送单独的键值字符串,这些字符串将作为单独的值在 uui-headers 会话参数中提供。

以下代码段会获取参数值,然后多次拆分参数,以访问字符串中 key2 变量的相应值。

$sys.func.GET($sys.func.SPLIT($sys.func.GET($sys.func.SPLIT($session.params.uui-headers,";"),1),"="),1)

以下示例展示了一个从 Playbook 的代码块中的触发器调用的函数,例如:@PlaybookStartHandler,在进入 playbook 时调用。其他函数会调用此函数,以从 uui-headers 参数获取值。

def _get_fromuui(attribute):
    try:
        uui_headers_src = history.playbook_input.action_parameters['uui-headers']
        # If uui_headers_src is a string, split by ';'
        if isinstance(uui_headers_src, str):
            headers = uui_headers_src.split(';')
        else:
            # If it's a list, join and split
            headers = ';'.join(uui_headers_src).split(';')
        for header in headers:
            header = header.strip()
            if header.lower().startswith(f"{attribute.lower()}="):
                return header[len(attribute) + 1:]
        return ""
    except Exception:
        return ""

可以使用具有不同“purpose”值的单独 UUI 标头发送其他数据。这些值会添加到 Conversation.telephonyConnectionInfo 对象。请注意,对话智能体 (Dialogflow CX) 代理在运行时无法访问此数据。

传入人工客服信息

如果您需要传递特定于人工客服的信息,可以将会话描述协议 (SDP) 媒体标签属性(针对人工客服)实时传输协议 (RTP) 流设置为所需的数据值。示例: none a=label:7382373482 此数据将填充到 sip_recording_media_label 字段中,并可在包含转写的 New message notification pubsub 主题中使用。在 pubsub Message.attributes 消息中查找 sip_recording_media_label 字段。

配置参与者角色和媒体流顺序

默认情况下,第一个媒体流与 END_USER 参与者角色相关联,后续媒体流与 HUMAN_AGENT 参与者角色相关联。

如果您需要其他行为(例如在出站呼叫系统中),则标头中传递的网址应附加 roles 参数。

例如:none http://dialogflow.googleapis.com/v2beta1/projects/gcp-project-id-12345/conversations/CID-297363723_79131759_799783510?roles=HUMAN_AGENT,END_USER

该网址指定第一个媒体流应具有 HUMAN_AGENT 角色,第二个媒体流应具有 END_USER 角色。您可以将 roles 参数与 Call-InfoUUI SIP 标头搭配使用。

为指定对话设置其他参数

如需为指定对话设置其他参数,请使用 MatchIntentRequest RPC 调用。您可以将 query_params.parameters 设置为所需的键值对,并将 query_input.text 设置为“设置参数”之类的字符串。

在初始 SIP INVITE 的 200 OK 响应之后进行 API 调用,此时对话已创建。MatchIntentRequest 的会话 ID 与 INVITE 中 Call-Info 标头内提供的对话 ID 相同。

使用 SIP REFER 将通话转接到 SIP 端点

如需将通话从虚拟客服转接到 SIP 端点,请使用 SIP REFER 方法。在 Live agent handoff 字段中添加载荷,并将 Telephony transfer call 字段设置为出站 SIP REFER Refer-To 字段中设置的数字。您的载荷应类似于以下代码示例。

{
    "sip-refer": true
}

如果需要将数据从 Conversational Agents (Dialogflow CX) 传递出去,可以使用 UUI 标头传递数据字符串。如果您想执行 SIP REFER 并传递 2 个键值对,可以使用类似于以下代码示例的载荷。

{
    "sip-refer": true,
    "uui-headers": [
        "key1=value1;key2=value2"
    ]
}

这会生成一个包含以下 UUI 标头的 SIP REFER。

User-to-User: <hex encoded "key1=value1;key2=value2">;encoding=hex;purpose=Goog-Session-Param

问题排查

Google 团队可能会要求您提供以下制品,以帮助排查 SIP OPTIONS ping 和进行的测试通话的问题:

  1. 网络数据包捕获
  2. 显示完整标头和 SIP SDP 的 SIP 调试轨迹:
    • Call-ID 值
    • Call-Info 值(如果存在)

网络数据包捕获

网络数据包捕获应显示以下内容:

  1. 您的 SBC 与 GTP SIP 服务器之间通过 TCP 端口 5672 进行通信,并完成完整的 3 向 TCP 握手(SYN、SYN-ACK、ACK)。如果 TCP 连接无法建立,可能存在以下问题:

    • 您的网络正在阻止出站流量。
    • 通信未发送到区域化 GTP SIP 服务器之一。 请参阅电话连接网络要求
    • 通信不是通过 TCP 端口 5672 发送的。
  2. 完整的 TLS 连接握手,包含以下内容:

    • 由 SBC 发起的 TLS v1.2 或更高版本。
    • 您的 SBC 发起“Client Hello”,而 GTP 以“Server Hello”响应。
    • 双向 TLS 身份验证流程。
      • GTP 会使用自己的服务器 TLS 证书进行响应,该证书由您的 SBC 进行身份验证。
      • SBC 会发送自己的客户端 TLS 证书,该证书由 GTP 进行身份验证。
    • 已建立加密通道,如“加密握手消息”所示。
    • 通过 TLS 通道传输“应用数据”的证据。

    如果 TLS 连接无法建立,可能存在以下问题:

    • GTP 端尚未创建 SIP 中继。
    • 配置的 SIP 中继 FQDN 与 SBC 的 TLS 证书(CN 或 SAN 属性)中显示的 FQDN 不匹配。
    • 不支持的 TLS 版本,仅支持 TLS 1.2 或更高版本。
    • 所请求的加密套件不受支持,请参阅 SBC 的 TLS 配置
    • 不受信任的 TLS 证书提供商,请参阅 SBC 的 TLS 配置
  3. SIP 调试轨迹应显示以下内容:

    • 以以下格式插入客户 Call-Info SIP 标头: none Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/$PROJECT_ID/conversations/$CONVERSATION_ID>;purpose=Goog-ContactCenter-Conversation

      例如:none Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/gcp-project-id-12345/conversations/CID-297363723_79131759_799783510>;purpose=Goog-ContactCenter-Conversation

    • SIP 标头以 E.164 格式 (+16501234567) 显示手机号码。

    • SIP 标头显示了在请求 URI 和其他 SIP 标头字段(例如 To、From、Via)中使用的公共 IP 地址。系统会拒绝专用 IP 地址。

    • SIP SDP 连接信息 (c= ... ) 是使用公共 IP 地址指定的。系统会拒绝不公开的 IP 地址。

    • 确保媒体优先级先发送最终用户的媒体流,然后发送人工客服的媒体流,因为 GTP 默认将第一个媒体流视为最终用户的媒体流。

    如果您收到 SIP 错误响应代码:

    • SIP 400 的错误(例如,488 Not Acceptable Here)响应代码可能表示 GTP 拒绝了 SIP 标头或 SIP 媒体 SDP 配置。
    • SIP 600 错误(SIP 603 拒绝错误)响应代码可能表示存在配额相关问题。如需详细了解如何申请增加配额,请参阅“配额和限制”页面

在远程调用方挂断电话时触发操作

新的 BiDi API(ConversationProfile 中的 use_bidi_streaming=True)支持在远程调用方挂断电话时,触发 playbook 中的工具调用或流程中的 webhook 调用。

当远程通话者挂断电话,并且 Conversational Agents (Dialogflow CX) 收到 SIP BYE 消息时,系统会触发自定义事件 sys.remote-call-disconnected。如果您创建了具有此特定事件名称的处理程序,则可以使用它在流程中通过 playbook 或 webhook 调用来触发工具调用。