https://a.storyblok.com/f/270183/59833/156fc08121/human-machine-detection.png

Otimizando chamadas de voz com a API da Vonage para detecção de voz humana/máquina e o Flask

Publicado em December 7, 2023

Tempo de leitura: 13 minutos

Introdução

Em determinados cenários de negócios, surge a necessidade de estabelecer comunicação por Voice com os clientes, em que as restrições de tempo se tornam um fator crítico para a entrega eficiente de mensagens de Voice, especialmente quando a equipe disponível é limitada. Quando um agente inicia uma ligação discando um número de telefone, ele precisa ter paciência até que a ligação seja atendida pelo destinatário, que pode ser uma pessoa ou um sistema de correio de voz. Essas interações consomem tempo e recursos valiosos.

Ao aproveitar a Voice API da Vonage e seus recursos aprimorados, que abrangem a detecção de voz humana, correio de voz e sinal sonoro, é possível automatizar todo o processo de comunicação com uma implementação mínima de código. Além disso, o sofisticado recurso de detecção automática garante a entrega completa da mensagem pretendida. O tutorial a seguir orienta você a iniciar a automação de chamadas de voz, incluindo a identificação de entidades humanas ou de correio de voz. O código-fonte desta aplicação pode ser encontrado no Github.

1. Pré-requisitos

Há pré-requisitos específicos que devem ser cumpridos antes de usar a Voice API da Vonage. Isso inclui criar uma conta de desenvolvedor da Vonage, obter um número virtual, configurar um ambiente Python, bem como o aplicativo Flask e o aplicativo ngrok Ingress. As seções a seguir descrevem esses pré-requisitos em detalhes.

Criar um account de desenvolvedor da Vonage

A Vonage é uma provedora líder no setor de comunicações que oferece aos desenvolvedores acesso a APIs para enviar chamadas de voz, vídeo e mensagens. Ao se cadastrar para um Account gratuito, você terá acesso a crédito gratuito e a uma documentação para usar as APIs da Vonage. Depois de obter a chave e o segredo da API, siga a documentação para criar um aplicativo de voz usando o Dashboard e gerar um JWT , que será necessário nas próximas etapas. Você pode ler mais sobre como gerar um JWT aqui.

Obter um número de telefone virtual

Assim que o cadastro estiver concluído, obtenha um número de telefone virtual no site da Vonage. Em alguns países, é necessário ter um número de telefone para fazer uma ligação, e o identificador de chamadas “Desconhecido” não permite que a ligação seja realizada. Portanto, é altamente recomendável obter um número de telefone virtual por um preço acessível.

Configurar o servidor Flask e o aplicativo Ingress do ngrok

É necessário um servidor web capaz de se comunicar com um endpoint publicado para receber eventos relacionados ao andamento da chamada e, posteriormente, emitir ações. O Flask é uma estrutura de aplicativos web de baixo consumo de recursos que utiliza Python para criar aplicativos baseados na web. Configure o servidor Flask em seu ambiente usando a documentação oficial.

Para acessar um aplicativo Flask executado localmente, você precisa de uma URL pública acessível pela Internet. Aqui está o conjunto mínimo de instruções para verificar se o Python está instalado e configurar o Flask no seu computador:

python --version pip install Flask flask --version

Você pode usar o ngrok para hospedar o servidor web em sua máquina local e enviar/receber solicitações da Web. Recomenda-se instalar a versão mais recente do ngrok. Aqui está um conjunto mínimo de instruções para configurar o ngrok no seu Mac e verificar sua versão:

brew install ngrok/ngrok/ngrok ngrok version

Para começar, aqui está o código mínimo em Python para iniciar o servidor Flask e enviar uma saudação “Hello World”:

from flask import Flask, request

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def callback_listener():
    print(f"event received --> {request.data}")
    return ("Hello world!", 200)

Salve o código acima no arquivo callback.py e execute-o usando o seguinte comando:

flask --app callback run --host=0.0.0.0 --debug

Agora você pode acessar o endereço IP público ou a URL de entrada do ngrok no seu navegador para verificar se o aplicativo está acessível pela Internet e pronto para a próxima etapa.

2. Fazer uma chamada de Voice e acompanhar os eventos

Agora que você concluiu os pré-requisitos, é hora de fazer a primeira chamada de voz e acompanhar o andamento dessa chamada. Existem várias maneiras de fazer uma chamada, incluindo o uso do SDK em Node.js, Python ou .NET. A maneira mais fácil é usar o comando `curl`, que demonstraremos aqui.

O exemplo foi retirado de aqui e adaptado para “action: talk”. Para fazer uma chamada, use o comando curl ou o Postman, utilizando a opção de importação:

curl --location 'https://api-us.vonage.com/v1/calls' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "to": [ { "type": "phone", "number": "" } ], "from": { "type": "phone", "number": "" }, "event_url": [""], "ncco": [ { "action": "talk", "text": "This is a test call." } ] }'

Substitua o seguinte por:

  • YOUR_JWT = JWT gerado na etapa anterior

  • YOUR_MOBILE_NUMBER = Número de celular para receber a chamada de Voice

  • YOUR_VIRTUAL_NUMBER = Número virtual obtido na etapa anterior

  • YOUR_CALLBACK_URL = URL de ingresso do ngrok ou endereço IP público do aplicativo servidor Flask

Se você consultar os logs do aplicativo Flask, verá os detalhes da progressão da chamada, desde o início até o toque.

event received --> b'{"headers":{},"from":"YOUR_VIRTUAL_NUMBER","to":"YOUR_MOBILE_NUMBER","uuid":"2dd98ea6-2518-4e54-8f3a-a8c532f131d6","conversation_uuid":"CON-51982b08-5337-480f-be09-81c3cda3f885","status":"started","direction":"outbound","timestamp":"2023-10-20T13:57:42.895Z"}'
event received --> b'{"headers":{},"from":"YOUR_VIRTUAL_NUMBER","to":"YOUR_MOBILE_NUMBER","uuid":"2dd98ea6-2518-4e54-8f3a-a8c532f131d6","conversation_uuid":"CON-51982b08-5337-480f-be09-81c3cda3f885","status":"ringing","direction":"outbound","timestamp":"2023-10-20T13:57:42.895Z"}'
event received --> b'{"start_time":null,"headers":{},"rate":null,"from":"YOUR_VIRTUAL_NUMBER","to":"YOUR_MOBILE_NUMBER","uuid":"2dd98ea6-2518-4e54-8f3a-a8c532f131d6","conversation_uuid":"CON-51982b08-5337-480f-be09-81c3cda3f885","status":"answered","direction":"outbound","network":null,"timestamp":"2023-10-20T13:57:47.191Z"}'
event received --> b'{"headers":{},"end_time":"2023-10-20T13:57:50.000Z","uuid":"2dd98ea6-2518-4e54-8f3a-a8c532f131d6","network":"23410","duration":"3","start_time":"2023-10-20T13:57:47.000Z","rate":"0.10000000","price":"0.00500000","from":"YOUR_VIRTUAL_NUMBER","to":"YOUR_MOBILE_NUMBER","conversation_uuid":"CON-51982b08-5337-480f-be09-81c3cda3f885","status":"completed","direction":"outbound","timestamp":"2023-10-20T13:57:49.611Z"}'

Parabéns por ter feito sua primeira chamada de voz automatizada. Se você não conseguir fazer uma chamada, pode haver vários motivos para não receber uma chamada no seu celular. Pode ser porque o usuário não foi autenticado, porque o JWT não foi gerado corretamente ou porque o campo “de” não foi definido corretamente. Você sempre pode solucionar problemas relacionados a chamadas usando os dados da resposta do comando e Voice Inspector .

3. Adicionar a detecção de voz humana/correio de voz à chamada

Agora que você já consegue fazer uma ligação, é hora de adicionar recursos avançados para identificar quem está do outro lado da linha. Existem vários cenários possíveis para atender a ligação:

  1. Um ser humano

  2. Uma mensagem de saudação na caixa postal

  3. Uma mensagem de saudação do correio de voz seguida de um bipe

Com o recurso de detecção de pessoa/correio de voz, cada situação pode ser tratada de forma específica para que a mensagem seja transmitida corretamente nas chamadas de voz.

Para adicionar o reconhecimento de voz/humano, atualize o comando curl com a opção “advanced_machine_detection” (detalhes sobre esse parâmetro podem ser encontrados aqui):

curl --location 'https://api-us.vonage.com/v1/calls' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data '{ "to": [ { "type": "phone", "number": "" } ], "from": { "type": "phone", "number": "" }, "advanced_machine_detection": { "behavior": "continue", "beep_timeout": "45" }, "event_url": ["YOUR_CALLBACK_UR"], "ncco": [ { "action": "talk", "text": "This is a test call." } ] }'

Se você atender a chamada e dizer “alô”, a voz será interpretada como uma voz humana, e um evento com “status: human” será gerado e enviado no callback do andamento da chamada, o que você poderá ver nos logs do aplicativo do servidor Flask:

event received --> b'{"call_uuid":"47f22bfd-ddb3-4a02-88be-9cb9673e0ae9","from":"<YOUR_VIRTUAL_NUMBER>","to":"<YOUR_MOBILE_NUMBER>","status":"human","conversation_uuid":"CON-d8ae51d1-6b93-426d-bbd0-2b1c059036ca","timestamp":"2023-10-20T14:34:43.014Z"}'

As saudações do correio de voz são interpretadas como “status: machine” e, se for detectado um bipe após o correio de voz, um parâmetro adicional “sub_state: beep_start” será enviado na chamada de retorno. Todos esses eventos podem ser resumidos da seguinte forma:

  1. Se a chamada for atendida por uma pessoa -> "status":"human"

  2. Se a chamada for encaminhada para uma caixa postal que não emita um bipe após o atendimento -> “status”: “machine” e, em seguida, “sub_state”: “beep_timeout” quando ocorrer o tempo limite do bipe

  3. Se a chamada for encaminhada para a caixa postal com um bipe -> primeiro “status”: “machine” e, em seguida, “sub_state”: “beep_start” quando o bipe for detectado

A detecção de bipe é um recurso útil, pois permite saber com precisão quando a gravação da mensagem de voz começa. Com a detecção de bipe, a mensagem gravada será truncada e poderá ficar incompreensível quando reproduzida pelo ouvinte, já que faltará a parte da mensagem anterior ao bipe.

4. Alteração do fluxo da chamada com base na detecção de atendimento por pessoa ou correio de voz

Vamos usar os recursos de reconhecimento de correio de voz para alterar o fluxo das chamadas. Para um cenário simples, vamos supor que você queira reproduzir mensagens específicas de acordo com a detecção de voz humana ou de correio de voz. Por exemplo:

  1. Reproduza a mensagem “Estou falando com uma pessoa” quando for detectada a presença de alguém

  2. Reproduzir a mensagem “Estou falando com a caixa postal antes do bipe” quando for detectada a caixa postal

  3. Reproduza a mensagem “Estou falando com a caixa postal após o bipe” quando o bipe for detectado

Observe que você já recebe os resultados da detecção de correio de voz durante o andamento da chamada por meio de callbacks; basta processar as informações e incorporar a lógica de tomada de decisão ao seu código do Flask. Aqui está o código atualizado do Flask, que será capaz de processar a detecção de correio de voz e gerar a resposta esperada:

from flask import Flask, request

app = Flask(__name__)

play_to_human = "I am talking to human."
play_to_voicemail = "I am talking to voicemail before the beep."
play_after_beep = "I am talking to voicemail after the beep."

@app.route("/", methods=["GET", "POST"])
def callback_listener():
    ncco, message_to_play = "", ""
    if request.is_json and "status" in request.get_json():
        req_json = request.get_json()
        print(f'status received --> {req_json["status"]}')
        if req_json["status"] == "machine" and "sub_state" not in req_json:
            message_to_play = play_to_voicemail
        elif req_json["status"] == "machine" and "sub_state" in req_json:
            message_to_play = play_after_beep
        elif req_json["status"] == "human":
            message_to_play = play_to_human
        ncco = [{ "action": "talk", "text": message_to_play, "loop": 3 }] if message_to_play != "" else ""
        print(f'response to send --> {ncco}')
    else:
        print(f'event received --> {request.data}')
    return (ncco if ncco != "" else "", 200)

Faça a chamada novamente usando o comando `curl` com a opção `advanced_machine_detection`:

curl --location 'https://api-us.vonage.com/v1/calls' \
--header 'Authorization: Bearer <YOUR_JWT>' \
--header 'Content-Type: application/json' \
--data '{
    "to": [ { "type": "phone", "number": "<YOUR_MOBILE_NUMBER>" } ],
    "from": { "type": "phone", "number": "<YOUR_VIRTUAL_NUMBER>" },
    "advanced_machine_detection": { "behavior": "continue", "beep_timeout": "45" },
    "event_url": ["YOUR_CALLBACK_UR"], 
    "ncco": [
        { "action": "talk",
        "text": "This is a test call." }
    ]
}'

No exemplo acima, a chamada será iniciada com uma simples ação de voz:

{ "action": "talk", "text": "This is a test call." }

À medida que a chamada avança, a ação de fala será substituída por outra ação de fala, dependendo da detecção de voz humana ou de correio de voz. Ou seja:

In case if call is picked up by human (i.e. status: human):
{ "action": "talk", 
"text": "I am talking to human.", 
"loop": 3 }

In case if call goes to voicemail before the beep is detected (i.e status: machine):
{ "action": "talk", 
"text": "I am talking to voicemail before the beep.", 
"loop": 3 }

In case if call goes to voicemail and beep is detected (i.e. status:machine and sub_state: beep_start):
{ "action": "talk", 
"text": "I am talking to voicemail after the beep.", 
"loop": 3 }

5. Conclusão com um exemplo prático

Por fim, vamos colocar em prática esse recurso aprimorado de chamadas de voz, considerando um cenário da vida real. Imagine que você está realizando uma campanha de chamadas de voz e está interessado apenas em atender chamadas feitas por uma pessoa real. Assim, se alguém atender a chamada, ela será conectada ao seu número de telefone. Caso contrário, deixe uma mensagem após o bipe se a chamada for direcionada para a caixa postal. Para resumir o caso de uso:

  1. Conecte o telefone do ativista para falar com a pessoa que está atendendo a ligação

  2. Caso contrário, deixe uma mensagem na caixa postal após o sinal: “Tentamos entrar em contato com você; por favor, entre em contato conosco imediatamente.”

Aqui está o código atualizado do Flask, que será capaz de detectar mensagens de voz e gerar a resposta esperada:

from flask import Flask, request

app = Flask(__name__)

action_when_human = { "action": "connect", "from": "<YOUR_VIRTUAL_NUMBER>", "endpoint": [{ "type": "phone", "number": "<CALL_CAMPAIGNER_PHONE_NUMBER>" }] }
action_when_beep = { "action": "talk", "text": "We tried to reach you, please contact us immediately."}

@app.route("/", methods=["GET", "POST"])
def callback_listener():
    ncco = ""
    if request.is_json and "status" in request.get_json():
        req_json = request.get_json()
        if req_json["status"] == "machine" and "sub_state" in req_json and req_json["sub_state"] == "beep_start":
            ncco = [action_when_beep]
            print(f'status received --> {req_json["status"]}:{req_json["sub_state"]}')
            print(f'response to send --> {ncco}')
        elif req_json["status"] == "human":
            ncco = [action_when_human]
            print(f'status received --> {req_json["status"]}')
            print(f'response to send --> {ncco}')
    else:
        print(f'event received --> {request.data}')
    return (ncco if ncco != "" else "", 200)

No código, substitua YOUR_VIRTUAL_NUMBER por um número virtual obtido anteriormente e CALL_CAMPAIGNER_PHONE_NUMBER pelo número para o qual você deseja ser conectado quando alguém atender a chamada.

Vamos testar o código fazendo uma chamada com o comando `curl`:

curl --location 'https://api-us.vonage.com/v1/calls' \
--header 'Authorization: Bearer <YOUR_JWT>' \
--header 'Content-Type: application/json' \
--data '{
    "to": [ { "type": "phone", "number": "<YOUR_MOBILE_NUMBER>" } ],
    "from": { "type": "phone", "number": "<YOUR_VIRTUAL_NUMBER>" },
    "advanced_machine_detection": { "behavior": "continue", "beep_timeout": "45" },
    "event_url": ["YOUR_CALLBACK_UR"], 
    "ncco": [
        { "action": "talk",
        "text": "Please wait while we connect you to an agent." }
    ]
}'

6. Conclusão

Seguindo as etapas deste tutorial, você criou com sucesso um recurso aprimorado de chamadas de voz para detectar se quem atende a chamada é uma pessoa, uma caixa postal ou se a chamada é direcionada para a caixa postal com um bipe. Ao mesmo tempo, você utilizou o aplicativo Flask para determinar dinamicamente o curso das ações durante a chamada. Com esses trechos de código simples, é possível conduzir rapidamente campanhas de chamadas, realizar chamadas em massa e enviar mensagens de Voice corretamente, sem interação humana. Mais uma vez, o código-fonte deste aplicativo pode ser encontrado no GitHub.

Concepts e documentação adicionais relacionados à API de Detecção Automática podem ser encontrados em Detecção Avançada de Máquinas.

Tem dúvidas ou comentários sobre este tutorial? Compartilhe suas ideias conosco no Twitter ou no nosso canal da Comunidade Vonage no Slack , mencionando este artigo para obter uma resposta rápida. Você também pode entrar em contato com mim no Twitter. Boa sorte e boa programação!

Compartilhar:

https://a.storyblok.com/f/270183/400x400/620f535ce9/atique-khan.jpg
Atique Khan

Atique is a computer graduate and proficient Python developer with a passion for exploring new technologies. With a strong background in programming and system engineering, he holds over 10 years of experience in automation, testing, and integration. His interests span single-board computers, software-defined radios, and continuous experimentation with generative AI tools.