概念和问题排查

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

电话网络要求

如果您的网络会过滤出站流量,则必须允许 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.60A.100.022(SIPRECSIP
Avaya Session Border Controller for Enterprise v10.2.1.1-104-25336(SIPRECSIP
Oracle E-SBC Acme Packet 4600 SCZ9.3.0 GA(Build 46)(SIPRECSIP
Ribbon Swe Core SBC v11.01.01R005
Cisco Unified Border Element (CUBE) v17.15.4(SIPRECSIP

支持的 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 标头

当您设置对话配置文件和电话号码时,您创建了一个将 sipConfig.createConversationOnTheFly 设置为 true 的 CCAI 对话配置文件。对话 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 ""

可以使用具有不同“用途”值的单独 UUI 标头发送其他数据。这些值会添加到 Conversation.telephonyConnectionInfo 对象中。请注意,Dialogflow CX 代理在运行时无法获取此数据。

SIP x-headers

x- 开头的 SIP 标头可以传递给代理并设置为会话参数。SIP 标头可在 x-headers 会话参数中找到。从会话参数中的标头名称移除了 x- 前缀。

例如,如果 SIP INVITE 包含以下标头:

x-billing-id: 12345

会话参数 x-headers 将包含:

{
    "x-headers": {
        "billing-id": "12345"
    }
}

如需访问该值,请执行以下操作:

$session.params.x-headers.billing-id

传入人工客服信息

如果您需要传递特定于人工客服的信息,可以将会话描述协议 (SDP) 媒体标签属性(针对人工客服)实时传输协议 (RTP) 流设置为所需的数据值。示例: none a=label:7382373482 此数据将填充到 sip_recording_media_label 字段中,并可在包含转写的 New message notification pubsub 主题中获取。在 Pub/Sub 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 角色。您可以使用 Call-InfoUUI SIP 标头应用 roles 参数。

针对指定对话设置其他参数

如需针对指定对话设置其他参数,请使用 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 字段中设置的数字。您的 Live agent handoff 载荷应类似于以下代码示例。

{
    "sip-refer": true
}

如果需要将数据传递出 Dialogflow CX,可以使用 UUI 标头和 x-header 传递数据字符串。如果您想执行 SIP REFER 并在 UUI 标头和 2 个 x-header 中传递 2 个键值对,可以使用类似于以下代码示例的 Live agent handoff 载荷。

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

这将生成一个具有以下 UUI 和 x-header 的 SIP REFER。

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

使用 SIP INVITE 与其他 SIP 端点进行电话会议

如需将最终客户的通话会议转接给可通过 SIP 端点访问的人工客服,请使用 SIP INVITE 方法。这样可让 Google 始终处于媒体路径中,并允许使用 Agent Assist 功能。将 Telephony transfer call 字段设置为出站 SIP INVITE To 字段中设置的数字。

如果需要将数据传递出 Dialogflow CX,可以使用 UUI 标头和 x-header 传递数据字符串。如果您想执行 SIP INVITE 并在 UUI 标头和 2 个 x-header 中传递 2 个键值对,可以使用类似于以下代码示例的 Live agent handoff 载荷。

{
    "uui-headers": [
        "key1=value1;key2=value2"
    ],
    "x-headers": {
        "header1": "value1",
        "header2": "value2"
    }
}

这会生成一个包含以下 UUI 和 x-header 的 SIP INVITE。

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

在 SIP BYE 中传递数据

导航到 End Session 会触发 SIP BYE。如果您想将数据从 Dialogflow CX 传递出去,可以使用 UUI 标头或 x-header 传递数据字符串。您可以在过渡到 End Session 之前,将调用路由到定义了 Live agent handoff 载荷的网页(类似于以下代码示例)。

{
    "uui-headers": [
        "key1=value1;key2=value2"
    ],
    "x-headers": {
        "header1": "value1",
        "header2": "value2"
    }
}

这将生成一个具有以下 UUI 和 x-header 的 SIP BYE。

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

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

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

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

问题排查

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 拒绝错误)响应代码可能表示存在配额相关问题。如需详细了解如何申请增加配额,请参阅“配额和限制”页面