Conceitos e solução de problemas

Nesta página, detalhamos as configurações específicas necessárias para a integração, além da solução de problemas comuns.

Requisitos de rede de telefonia

Se a rede filtrar o tráfego de saída, ela precisará permitir o tráfego de saída para sinalização SIP e streaming de mídia.

Para sinalização SIP, todo o intervalo de IP 74.125.88.128/25 (TCP) na porta 5672 precisa ser permitido. Para um conjunto de regras de firewall mais restritivo, é possível restringir a sinalização SIP a apenas um ou mais servidores SIP GTP regionalizados:

  • Região dos EUA: us.telephony.goog (74.125.88.132)
  • Região da UE: eu.telephony.goog (74.125.88.133)
  • Região da Ásia-Pacífico: ap.telephony.goog (74.125.88.134)
  • Região da América do Sul: sa.telephony.goog (74.125.88.135)

Para mídia RTP, configure regras de firewall para permitir o tráfego destinado ao intervalo de IP CIDR 74.125.39.0/24. Normalmente, as portas necessárias para mídia são apenas 16384-32767 (TCP+UDP), mas esse intervalo pode ser expandido no futuro.

Fornecedores ou modelos de SBC compatíveis

A tabela a seguir lista os fornecedores ou modelos de SBC e as versões de firmware compatíveis. Instruções detalhadas de integração para cada fornecedor estão vinculadas na versão do firmware.

Fornecedores e modelos Versões de firmware
Controlador de Borda de Sessão (SBC) AudioCodes VE v7.40A.500.786
Controlador de borda de sessão da Avaya para empresas v8.1.3.2-38-22279, v10.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

Protocolos de mídia e sinalização SBC compatíveis

Protocolo de sinalização SIP sobre TLS
Mídia SRTP
Criptografia de mídia SDES
Pacote de criptografia de mídia compatível AES_CM_128_HMAC_SHA1_80, AEAD_AES_256_GCM
Codecs de mídia compatíveis G.711 µ-law (PCMU), G.711 A-law (PCMA), Opus

Cabeçalhos SIP

Ao configurar um perfil de conversa e um número de telefone, você criou um perfil de conversa da CCAI com o sipConfig.createConversationOnTheFly definido como true. O ID da conversa precisa ser gerado dinamicamente durante o SIP INVITE usando o valor do cabeçalho SIP de Call-Info ou UUI.

O valor do cabeçalho SIP aponta para o endpoint do Dialogflow definindo o ID do projetoGoogle Cloud e o ID da conversa:

  1. O ID do projeto Google Cloud é o projeto que você usou ao configurar um projeto do Google Cloud .
  2. O ID da conversa precisa ser gerado dinamicamente pelo SBC. O ID da conversa precisa estar em conformidade com a fórmula de expressão regular [a-zA-Z][a-zA-Z0-9_-]*, com o comprimento dos caracteres no intervalo de [3,64]. Para gerar dinamicamente o ID da conversa, um padrão comum é usar o valor Call-ID no SIP INVITE e adicionar um prefixo com letras para que ele esteja em conformidade com a expressão regular, conforme especificado anteriormente. Por exemplo, se o valor de Call-ID for 297363723_79131759_799783510, prefixar o valor de Call-ID com "CID-" o tornaria compatível com a expressão regular [a-zA-Z][a-zA-Z0-9_-]*.

Cabeçalho SIP Call-Info

Insira um cabeçalho SIP personalizado chamado Call-Info no SIP INVITE para definir exclusivamente o ID da conversa:

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

Exemplo:

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

Cabeçalho SIP UUI

Se a definição do cabeçalho SIP personalizado Call-Info não for compatível, configure o cabeçalho SIP UUI (usuário para usuário) no SIP INVITE para transmitir o ID da conversa.

Use os mesmos dados solicitados em Call-Info com o URL codificado em hexadecimal e a finalidade definida como Goog-ContactCenter-Conversation. Confira a seguir um exemplo de cabeçalho, em que a string hexadecimal decodificada é 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

Se outros dados precisarem ser transmitidos para o agente de conversa e definidos como um parâmetro de sessão, passe uma lista separada por ponto e vírgula de pares de chave-valor codificados em hexadecimal, seguidos por ;encoding=hex;purpose=Goog-Session-Param. Isso vai resultar em um parâmetro de sessão criado com o nome uui-headers que contém uma lista de strings de payload decodificadas.

Por exemplo, se a string key1=value1;key2=value2 precisasse ser transmitida, o cabeçalho UUI a seguir seria enviado, em que o payload é o valor codificado em hexadecimal de key1=value1;key2=value2.

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

que resultaria na criação do seguinte parâmetro de sessão.

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

Se o SBC aceitar o envio de vários cabeçalhos UUI, você poderá enviar strings de valor-chave individuais por cabeçalho UUI, e elas estarão disponíveis como valores individuais no parâmetro de sessão uui-headers.

O snippet a seguir usa o valor do parâmetro e o divide várias vezes para acessar o valor apropriado da variável key2 na string.

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

O exemplo a seguir mostra uma função que é chamada por um gatilho nos blocos de código do Playbook, por exemplo: @PlaybookStartHandler, que é chamado ao entrar no playbook. Outras funções chamam essa função para receber valores do parâmetro 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 ""

Outros dados podem ser enviados usando cabeçalhos UUI separados com valores de "finalidade" diferentes. Esses valores são adicionados ao objeto Conversation.telephonyConnectionInfo. Esses dados não estão disponíveis para o agente de conversação (Dialogflow CX) durante a execução.

Transmitir informações do agente humano

Se você precisar transmitir informações específicas para agentes humanos, defina o atributo de rótulo de mídia do Protocolo de descrição de sessão (SDP), para o agente humano, o fluxo do Protocolo de transporte em tempo real (RTP) para o valor de dados necessário. Exemplo: none a=label:7382373482 Esses dados serão preenchidos no campo sip_recording_media_label e estarão disponíveis no tópico New message notification do Pub/Sub que contém as transcrições. Procure o campo sip_recording_media_label na mensagem Message.attributes do pubsub.

Configurar funções de participantes e ordem de stream de mídia

Por padrão, o primeiro fluxo de mídia é associado à função de participante END_USER, e os fluxos de mídia subsequentes são associados à função de participante HUMAN_AGENT.

Se você precisar de um comportamento diferente (por exemplo, em um sistema de chamadas externas), o URL transmitido no cabeçalho precisará ter o parâmetro "roles" anexado.

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

O URL especifica que o primeiro fluxo de mídia deve ter a função HUMAN_AGENT e o segundo, a função END_USER. É possível aplicar o parâmetro "roles" com o cabeçalho SIP Call-Info ou UUI.

Definir parâmetros adicionais em uma conversa específica

Para definir outros parâmetros em uma conversa específica, use a chamada de RPC MatchIntentRequest. Você pode definir query_params.parameters como os pares de valores-chave necessários e query_input.text como algo como "Definir parâmetros".

Faça a chamada de API após a resposta "200 OK" do SIP INVITE inicial, quando a conversa tiver sido criada. O ID da sessão para o MatchIntentRequest é o mesmo ID de conversa fornecido no cabeçalho Call-Info no INVITE.

Usar SIP REFER para transferir uma chamada para um endpoint SIP

Para transferir uma chamada de um agente virtual para um endpoint SIP, use o método SIP REFER. Inclua uma carga útil no campo Live agent handoff e defina o campo Telephony transfer call como o número definido no campo SIP REFER Refer-To de saída. O payload deve ser semelhante ao exemplo de código a seguir.

{
    "sip-refer": true
}

Se for necessário transmitir dados dos agentes de conversação (Dialogflow CX), os cabeçalhos da UUI poderão ser usados para transmitir strings de dados. Se você quiser fazer um SIP REFER e transmitir dois pares de chave-valor, use uma carga útil semelhante ao exemplo de código a seguir.

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

Isso geraria um SIP REFER com o seguinte cabeçalho UUI.

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

Solução de problemas

A equipe do Google pode pedir que você forneça os seguintes artefatos para ajudar na solução de problemas do ping de OPTIONS do SIP e das chamadas de teste realizadas:

  1. Captura de pacote de rede
  2. Rastreamento de depuração do SIP mostrando o cabeçalho completo e o SDP do SIP:
    • Valor do ID da chamada
    • Valor Call-Info (se existir)

Captura de pacote de rede

A captura de pacote de rede precisa mostrar o seguinte:

  1. Um handshake TCP completo de três vias (SYN, SYN-ACK, ACK) entre o SBC e os servidores SIP GTP comunicados pela porta TCP 5672. Se a conexão TCP não for estabelecida, os possíveis problemas são:

    • Sua rede está bloqueando o tráfego de saída.
    • A comunicação não está sendo enviada para um dos servidores SIP GTP regionalizados. Consulte Requisito de rede para conectividade de telefonia.
    • A comunicação não está sendo enviada pela porta TCP 5672.
  2. Um handshake de conexão TLS completo com o seguinte:

    • TLS v1.2 ou mais recente iniciado pelo SBC.
    • Seu SBC iniciar um "Client Hello" e o GTP responder com "Server Hello".
    • Processo de autenticação TLS mútua.
      • O GTP responde com o próprio certificado TLS do servidor, que é autenticado pelo seu SBC.
      • O SBC envia o próprio certificado TLS do cliente, que é autenticado pelo GTP.
    • Canal criptografado estabelecido, conforme evidenciado pela "Mensagem de handshake criptografada".
    • Evidências de que os "Dados de aplicativo" estão sendo transmitidos pelo canal TLS.

    Se a conexão TLS não foi estabelecida, os possíveis problemas são:

    • O entroncamento SIP não foi criado no lado do GTP.
    • O FQDN configurado do tronco SIP não corresponde ao FQDN apresentado no certificado TLS (atributo CN ou SAN) do SBC.
    • A versão do TLS não é compatível. Apenas a versão 1.2 ou posterior é compatível.
    • O pacote de criptografia solicitado não é compatível. Consulte Configuração de TLS do SBC.
    • Provedores de certificados TLS não confiáveis. Consulte Configuração de TLS do SBC.
  3. O rastreamento de depuração do SIP deve mostrar o seguinte:

    • Cabeçalho SIP do cliente Call-Info inserido neste formato: none Call-Info: <http://dialogflow.googleapis.com/v2beta1/projects/$PROJECT_ID/conversations/$CONVERSATION_ID>;purpose=Goog-ContactCenter-Conversation

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

    • Os cabeçalhos SIP mostram o número de telefone no formato E.164 (+16501234567).

    • Os cabeçalhos SIP mostram os endereços IP públicos usados no URI da solicitação e em outros campos de cabeçalho SIP (por exemplo, "Para", "De", "Via"). Endereços IP particulares seriam rejeitados.

    • As informações de conexão SDP SIP (c= ... ) são especificadas com um endereço IP público. Endereços IP particulares seriam rejeitados.

    • Verifique se a priorização de mídia envia primeiro o fluxo dos usuários finais e depois o fluxo de mídia do agente humano, porque o GTP trata o primeiro fluxo de mídia como o dos usuários finais por padrão.

    Se você receber um código de resposta de erro SIP:

    • O código de resposta de erro SIP 400 (por exemplo, 488 Not Acceptable Here) provavelmente indica que o GTP rejeitou um cabeçalho SIP ou uma configuração SDP de mídia SIP.
    • Um código de resposta de erro SIP 600 (erro recusado SIP 603) provavelmente indica um problema relacionado à cota. Consulte a página Cotas e limites para saber como solicitar um aumento.

Acionar uma ação quando o autor da chamada remota desliga

A nova API BiDi (use_bidi_streaming=True em ConversationProfile) permite acionar uma chamada de ferramenta em um playbook ou uma chamada de webhook em um fluxo quando o autor da chamada remota desliga.

Quando o usuário remoto desliga e os agentes de conversação (Dialogflow CX) recebem uma mensagem SIP BYE, o evento personalizado sys.remote-call-disconnected é acionado. Se você criar um manipulador com esse nome de evento específico, poderá usá-lo para acionar uma chamada de ferramenta com um playbook ou uma chamada de webhook em um fluxo.