Faça e receba chamadas telefônicas do navegador com o Programmable Voice da Twilio com Python e JavaScript
Tempo de leitura: 14 minutos
Neste tutorial, vamos escrever um aplicativo que usa a API Twilio Programmable Voice para fazer e receber chamadas telefônicas de um navegador da web. Também implementaremos uma interface de usuário que nos permite fazer, aceitar e rejeitar chamadas telefônicas.
Ao final deste tutorial, teremos um aplicativo semelhante ao seguinte:
Requisitos do tutorial
Para seguir este tutorial você precisará dos seguintes componentes:
- Uma conta da Twilio gratuita ou paga. Se você é novo na Twilio, crie uma conta gratuita agora. Se você criar sua conta usando este link e, posteriormente, atualizar para uma conta paga, você receberá US$ 10 em crédito.
- Um número de telefone Twilio que pode fazer e receber chamadas. Obtenha um agora , se não tiver.
- Python 3.6 ou superior instalado.
- O ngrok instalado. O ngrok é um serviço de proxy reverso que cria um túnel seguro de um endpoint público para um serviço da web executado localmente. Precisaremos usar o ngrok para criar um URL segura que permita que a Twilio se conecte ao nosso aplicativo.
- Um telefone celular ou telefone que pode fazer e receber chamadas telefônicas para testar o projeto.
Conceitos básicos e lógica do aplicativo
O objetivo deste tutorial é criar um aplicativo da web que nos permita fazer e receber chamadas telefônicas no navegador. Usaremos a estrutura do Flask para implementar os webhooks necessários e atender ao aplicativo cliente.
O cliente do aplicativo usará o Twilio Client JS SDK (twilio.js
) para criar um dispositivo Twilio.
Um dispositivo Twilio é nosso principal ponto de entrada para fazer e receber chamadas telefônicas no navegador. Para configurar uma conexão entre um dispositivo Twilio e os servidores da Twilio, precisaremos gerar tokens de acesso em nosso servidor de aplicativos.
Os tokens de acesso são credenciais de curta duração que podem ser distribuídas com segurança aos aplicativos do lado do cliente que podemos usar para autenticar SDKs do cliente Twilio comoVoice,Conversations,Sync e Video. Para gerar tokens de acesso em nosso servidor, precisaremos usar uma chave de API da Twilio.
Uma chave de API da Twilio é uma credencial que nos concede acesso à API da Twilio. Uma chave de API nos permite:
- Autenticar com a API da Twilio
- Crie e revogue tokens de acesso
Os tokens de acesso concedem ao cliente acesso a um aplicativo TwiML (aplicativo TwiML). A Twilio conta com um aplicativo TwiML em nossa conta para determinar como interagir com nosso servidor.
TwiML (Twilio Markup Language) é um conjunto de instruções que podemos usar para dizer à Twilio o que fazer quando recebermos uma chamada, SMS ou fax.
Criar a estrutura do projeto
Nesta seção, criaremos nosso diretório de projeto e, dentro dele, criaremos os diretórios padrão para um aplicativo Flask. Depois disso, criaremos e ativaremos um ambiente virtual. Por fim, instalaremos os pacotes Python necessários para criar esse aplicativo da web.
Abra uma janela de terminal e digite os seguintes comandos:
Aqui, clonamos um projeto inicial que foi criado para este tutorial e definimos o nome como twilio-in-browser-calls
, em seguida, navegamos até o diretório do projeto. Este projeto contém o código padrão que usaremos para construir nosso aplicativo.
Você encontrará os seguintes diretórios padrão para um aplicativo Flask dentro de:
static
: é aqui que todos os arquivos estáticos são armazenados.templates
: é aqui que todos os modelos são armazenados
O subdiretório static
tem o seguinte conteúdo:
css
- é aqui que armazenaremos todos os arquivos CSS. Dentro deste subdiretório você encontrará um arquivo chamadostyle.css
, este arquivo será responsável por modelar a UI do cliente do aplicativo.images
- é aqui que armazenaremos todas as imagens. Neste subdiretório você encontrará um arquivo chamadouser.png
, que exibiremos na IU do cliente do nosso aplicativo.js
: É aqui que armazenamos todos os nossos arquivos Javascript. Dentro desse diretório, você encontrará um arquivo chamadomodals.js
. Este arquivo contém o código para gerenciar os módulos armazenados no diretóriotemplates
.
O subdiretório templates
tem três arquivos: call_in_progress_modal.html
, dial_modal.html
e incoming_call_modal.html
.
O arquivo call_in_progress_modal.html
contém o código HTML que implementa um modal que será exibido durante uma chamada. Este modal mostra a duração da chamada em andamento, o número que você está chamando e um botão com um ícone de telefone vermelho que permitirá que você encerre a chamada. É assim que este modal se parece:
O arquivo dial_modal.html
contém o código HTML que implementa um modal que será exibido quando você quiser discar um número de telefone. Este modal mostra um teclado numérico e um botão com um ícone de telefone verde. É assim que ele se parece:
O arquivo incoming_call_modal.html
contém o código HTML de um modelo que implementa um modal que só será exibido quando você estiver recebendo uma chamada. Este modal mostra o número que está chamando você, e dois botões, um botão com um ícone de telefone verde e outro com um ícone de telefone vermelho. O primeiro botão permitirá que você aceite uma chamada recebida e o segundo, que a rejeite.
Dentro do nosso diretório de trabalho, crie um ambiente virtual e ative-o. Se você estiver usando um sistema Unix ou Mac OS, execute os seguintes comandos para fazer isso:
Se você estiver seguindo o tutorial no Windows, execute os seguintes comandos:
Agora que criamos e ativamos nosso ambiente virtual, podemos instalar as bibliotecas necessárias para criar nosso aplicativo:
No comando acima utilizamos, pip
, o instalador de pacotes Python, para instalar os seguintes pacotes que iremos utilizar neste projeto:
- Twilio, um pacote Python para comunicação com a API da Twilio.
- Flask, uma microestrutura Python para a criação de aplicativos da web. Vamos usá-lo para criar um webhook para interagir com a Twilio e criar a interface do usuário do cliente para fazer e receber chamadas telefônicas.
- Python-dotenv, uma biblioteca que lê pares chave-valor de um arquivo e os adiciona como variáveis de ambiente. Usaremos este módulo para recuperar nossas credenciais da Twilio armazenadas em um arquivo de configuração
.env
.
Para sua referência, quando este tutorial foi lançado, estas eram as versões dos pacotes acima e das respectivas dependências testadas:
Além dos pacotes Python mencionados acima, usaremos as seguintes bibliotecas de front-end:
- Bootstrap, uma poderosa estrutura de front-end usada para criar sites modernos.
- Twilio Client JS SDK (twilio.js), uma biblioteca que permite fazer chamadas de voz a partir de um navegador da web.
- JQuery, uma biblioteca JavaScript rápida, pequena e repleta de recursos que torna coisas como passagem e manipulação de documentos HTML, manipulação de eventos, animação e Ajax muito mais simples. Nós o usaremos para realizar alguma manipulação de Dom e tratamento de eventos.
- Font Awesome, um popular kit de ferramentas de ícones de SVG, fontes e CSS. Usaremos alguns dos ícones criados por eles em nosso cliente de aplicativos.
Criar um aplicativo TwiML
Nesta seção, vamos utilizar o console da Twilio para criar um "aplicativoTwiML", no qual iremos posteriormente armazenar o URL do webhook que criaremos.
Abra uma nova janela do navegador e navegue até Console da conta Twilio > Voice > TwiML > Apps TwiML. Clique no botão "Criar novo aplicativo TwiML" ou no ícone vermelho "+" se você já tiver outros aplicativos TwiML.
Digite o nome do seu aplicativo TwiML no campo "Nome amigável", por exemplo, chamadas no navegador. Deixe os outros campos vazios por enquanto. Clique no botão "Criar" para criar o aplicativo TwiML.
Você será redirecionado para o dashboard de aplicativos TwiML. Clique no aplicativo TwiML que você acabou de criar. Na página deste aplicativo, selecione o valor SID e copie-o para a área de transferência.
No diretório raiz do projeto, crie um arquivo nomeado .env
e insira o seguinte conteúdo nele:
Criar uma chave de API Twilio
Para a próxima etapa, vamos criar uma chave de API da Twilio para a API de voz. A chave de API será usada para gerar tokens de acesso, o que permitirá que o front-end em execução no navegador faça chamadas para as APIs da Twilio.
Navegue até o Console da Twilio > Voice > Configurações > Chaves de API em seu navegador. Clique no botão "Criar nova chave de API" ou no ícone vermelho "+" se já tiver outras chaves de API.
Digite o nome da sua chave de API no campo "Nome amigável", por exemplo, chamadas no navegador. Deixe o "Tipo de chave" como "Padrão". Clique no botão "Criar chave de API" para criar a chave de API.
Você será redirecionado para uma página onde encontrará informações sobre sua nova chave de API. Copie os valores "SID" e "Segredo" e cole-os no arquivo .env
como TWILIO_API_KEY_SID
e TWILIO_API_KEY_SECRET
. Seu arquivo .env
agora deve ter a seguinte aparência:
Verifique o campo "Entendi!" e, em seguida, clique no botão "Finalizar".
Agora vá para a página inicial do console da Twilioe copie o valor SID da conta da Twilio para o arquivo .env
da seguinte maneira:
Em seguida, vá para o Console da sua conta Twilio > Números de telefone > Gerenciar números > Números ativos, selecione o número que você comprou para este tutorial e você será redirecionado para uma página onde poderá configurar esse número. Localize o campo "Número de telefone", copie o número de telefone exibido neste campo e cole-o no arquivo .env
como TWILIO_NUMBER
. Remova todos os espaços entre os dígitos, mas deixe o sinal de mais inicial, garantindo que o número esteja no formato E.164.
Seu arquivo .env
deve ter a seguinte aparência quando o número de telefone for adicionado:
Criar o aplicativo Flask
Nesta seção, criaremos a lógica do nosso aplicativo Flask, que fornecerá as funções de suporte necessárias ao front-end para fazer e receber chamadas telefônicas.
Criar o servidor de aplicativos
Nesta subseção, criaremos os endpoints necessários para fazer e receber chamadas telefônicas. Precisaremos criar os seguintes endpoints:
/
- esse endpoint será responsável por servir a interface do usuário do aplicativo (cliente)./token
- esse endpoint será responsável por gerar e devolver tokens de acesso ao cliente./handle_calls
- este endpoint será responsável por gerar as instruções TwiML necessárias para fazer e receber chamadas telefônicas.
No diretório raiz do projeto, crie um arquivo chamado main.py
. Abra-o usando seu editor de texto favorito e adicione o seguinte código a ele:
Aqui, importamos todos os pacotes que precisaremos para criar nosso aplicativo de servidor:
flask
será usado para definir os endpoints do aplicativo.- O pacote
twilio
será usado para interagir com a API da Twilio, permitindo que façamos e recebam chamadas telefônicas por meio do dispositivo Twilio que será criado no cliente. load_dotenv
será usado para importar nossas credenciais de conta da Twilio do arquivo.env
.pprint
será usado para formatar e imprimir os dados recebidos quando a Twilio enviar uma solicitação ao endpoint/handle_calls
para notificar que há uma chamada.os
será usado comload_dotenv
para recuperar as credenciais armazenadas no arquivo.env
Adicione o seguinte código na parte inferior do arquivo main.py
:
O aplicativo é iniciado importando as variáveis de ambiente armazenadas no arquivo .env
com uma chamada para o load_dotenv()
. Isso nos permite recuperar as cinco variáveis de configuração necessárias para este aplicativo.
Em seguida, criamos uma instância de aplicativo Flask
em uma variável com o nome de app
e, com isso, criamos o endpoint /
do nosso aplicativo. Esta rota está servindo um modelo chamado home.html
que criaremos mais tarde.
Adicione o seguinte código abaixo da rota /
:
Isso adiciona o endpoint /token
, que será chamado pelo cliente para solicitar um token de acesso.
Quando esse endpoint é acionado, criamos uma variável nomeada identity
e a atribuímos a ele nosso número Twilio. Uma identidade é exclusiva para um usuário e pode ser conetada em vários dispositivos simultaneamente. Em um servidor de aplicativos destinado a ser usado por vários usuários, precisaríamos decidir, com base na solicitação de token que nos seria enviada, quem é o usuário e o que ele tem permissão para fazer. Para descobrir quem é o usuário (sua identidade), usaríamos nosso sistema de login ou provedor de identidade existente (por exemplo, cookies de sessão, um token de API ou qualquer outro mecanismo usado para proteger suas solicitações de API). Neste tutorial, no entanto, somos o único usuário, portanto, não precisamos trabalhar com várias identidades, e o número da Twilio que adquirimos para este tutorial funciona bem para essa finalidade.
Em seguida, usamos o account_sid
, api_key
, api_key_secret
e identity
para criar um token de acesso. O token precisa ser provisionado com "concessões", que determinam quais operações o cliente que apresenta o token tem permissão para executar. Para este aplicativo, criamos um objeto de concessão de voz que é configurado com o sid
do aplicativo TwiML criado anteriormente.
Para concluir o endpoint, retornamos o access_token
e identity
para o cliente no formato JSON.
Adicione o seguinte código abaixo da rota /token
:
Esse bloco adiciona um endpoint chamado /handle_calls
. Esse endpoint será chamado pela Twilio sempre que fizermos ou recebermos uma chamada telefônica.
Quando esse endpoint é acionado, usamos pprint
para imprimir o conteúdo do request.form
, e, em seguida, criamos um objeto de resposta TwiML
e um objeto de discagem TwiML
. No objeto dial
, configuramos o callerId
como o número Twilio que adquirimos para este tutorial, desta forma, quando ligamos para um número de telefone usando este aplicativo, o telefone do destinatário mostrará esse número em vez de anonymous
.
Depois disso, usamos a lógica condicional para verificar se o objeto request.form
possui a propriedade chamada To
, e se o valor dessa propriedade não é igual ao nosso twilio_number
. Esse teste garante que a chamada do endpoint foi feita para fazer uma chamada (e não para receber uma), que é o primeiro caso que trataremos.
Quando tivermos certeza de que se trata de uma solicitação para fazer uma chamada, definimos o número que queremos discar para o valor em request.form['To']
, anexamos o objeto dial
ao objeto response
e retornamos o objeto response
como uma string de volta à Twilio, que executará essas instruções e discará o número solicitado.
A parte inferior do script é uma condicional padrão que executa o servidor de desenvolvimento do Flask na porta 3000 quando o script é chamado a partir da linha de comando.
Criar o cliente do aplicativo
Nesta subseção, criaremos o front-end que nos permitirá fazer e receber chamadas telefônicas no navegador.
Criar a página inicial
Crie um arquivo chamado home.html
dentro do diretório templates
. Abra-o e adicione o seguinte código a ele:
Este modelo implementa uma página que mostra um console onde podemos monitorar o estado do dispositivo Twilio que criaremos em breve usando JavaScript. Incluímos neste modelo os modelos call_in_progress_modal.html
, dial_modal.html
e incoming_call_modal.html
e os modelos que vieram com o padrão deste projeto. Esta página também mostra um botão com um ícone de telefone. Sempre que pressionarmos este botão, será aberto um modal e, neste modal, inseriremos o número que desejamos chamar.
Além do Bootstrap, jQuery, FontAwesome e arquivos twilio.js
, observe como estamos incluindo os seguintes arquivos neste modelo:
style.css
- este arquivo contém algumas das CSS usadas para modelar nosso aplicativomain.js
- este arquivo javascript contém o código para criar um dispositivo Twilio e conectá-lo ao aplicativo TwiML .modals.js
- este arquivo javascript contém o código para gerenciar os módulos de nosso aplicativo.
Os arquivos style.css
e modals.js
vieram dentro do repositório de boilerplate do projeto. Criaremos o arquivo main.js
na próxima subseção.
Criando o dispositivo Twilio
Crie um arquivo chamado main.js
dentro do diretório static/js
. Abra-o e adicione o seguinte código:
Aqui criaremos o dispositivo Twilio que nos permitirá fazer e receber chamadas telefônicas no navegador.
Primeiro, usamos a função getJSON()
fornecida pelo jQuery para enviar uma solicitação GET para o endpoint /token
em nosso servidor de aplicativos e recuperar um token de acesso. Depois de recuperar o token, usamos o twilio.js
e o token para criar um dispositivo Twilio e conectá-lo ao aplicativo TwiML.
Depois de criar o dispositivo Twilio, adicionamos alguns ouvintes de eventos a este dispositivo e algum código que nos permitirá interagir com este dispositivo usando a interface do usuário.
Fazer chamadas telefônicas outbound
Nesta seção, usaremos nosso aplicativo para fazer chamadas telefônicas outbound. Mas antes de fazermos isso, precisamos executar o aplicativo, configurar o ngrok e configurar nosso aplicativo TwiML.
Abra uma segunda janela de terminal em nosso diretório de projeto, ative o ambiente virtual Python e inicie o aplicativo executando o seguinte comando:
Depois de executar o comando acima, você verá algo semelhante a este:
Copie o URL https
do ngrok para a área de transferência. Em seguida, acesse o dashboard do Console da conta Twilio > Voice > TwiML > Apps TwiML e selecione o aplicativo TwiML que você criou para este tutorial.
Localize a seção "Voice" da configuração do aplicativo TwiML e cole o URL https://
fornecida pelo ngrok
seguida do endpoint /handle_calls
no campo "URL de solicitação" e clique no botão "Salvar". Isso criará um webhook que conecta seu aplicativo ao aplicativo TwiML.
Neste exemplo, o URL do ngrok é https://48dcc810632b.ngrok.io/handle_calls
. A primeira parte do URL será diferente toda vez que o ngrok for iniciado.
Agora, conecte um fone de ouvido com microfone ao seu computador, depois abra seu navegador e digite http://localhost:3000/
na barra de endereço. Você deverá ver algo semelhante a isto:
Depois de ver uma mensagem dizendo Twilio.Device Ready!
, seu dispositivo Twilio está funcionando como deveria. Clique no botão com o ícone verde do telefone e você verá o modal de discagem:
Use os números no teclado para inserir o número que você gostaria de chamar ou apenas digite-o usando seu teclado no campo de inserção acima do teclado e, quando estiver pronto, clique no telefone verde para fazer a chamada.
Depois de clicar neste botão, seu navegador solicitará sua permissão para usar o microfone e concederá a permissão. Assim que o número que você está ligando atender a chamada, você verá a chamada em andamento modal:
Vá para o terminal que está executando nosso aplicativo Flask e os dados de solicitação que a Twilio envia para nosso endpoint /handle_calls
serão semelhante ao seguinte:
Como o valor da propriedade To
(o número que chamamos) não é igual ao nosso número Twilio, o código dentro da instrução if
no edpoint handle_calls
foi executado.
Atender chamadas telefônicas recebidas
Na seção anterior, você conseguiu usar seu aplicativo para fazer chamadas telefônicas, mas até o momento o aplicativo não pode receber nenhuma chamada. Para poder receber chamadas, precisaremos adicionar algum código adicional em main.py
, main.js
, e home.html
, além de configurar o número que compramos para este tutorial no console da Twilio para poder receber telefonemas.
Volte para o arquivo main.py
e substitua o código no endpoint /handle_calls
pelo seguinte:
Aqui adicionamos a instrução else
ao endpoint /handle_calls
. O código nesta parte será executado se o número que recebe a chamada for o número que adquirimos para este tutorial, o que significa que temos uma chamada recebida.
Estamos definindo o callerId
no objeto de discagem TwiML para o valor da propriedade Caller
em request.form
. Como o nome sugere, Caller
é o número que está ligando para nosso número Twilio. Isso é para que possamos ver quem está nos ligando na interface do usuário do nosso aplicativo. Também estamos definindo client
no objeto de discagem como o valor de identity
que usamos quando criamos um token de acesso no endpoint /token
.
Para concluir o fluxo de chamadas recebidas, anexamos o objeto de discagem ao objeto de resposta TwML e, em seguida, retornamos esse objeto de resposta como uma string.
Volte para o arquivo main.js
e adicione o seguinte código abaixo do ouvinte device.on(‘disconnect')
:
Aqui, adicionamos um ouvinte de eventos que permitirá que seu dispositivo Twilio monitore chamadas recebidas e mostre o modal de chamadas recebidas assim que detectar uma.
Vá para o dashboard do Console da Twilio > Números de telefone > Gerenciar números > Números ativos e selecione o número que você comprou para este tutorial.
Localize a seção "Voz e fax" da configuração do número de telefone e selecione "aplicativo TwiML" no campo "Configurar com". Depois, selecione o nome do aplicativo TwiML que você criou para este tutorial no campo "aplicativo TwiML". Isso vinculará o número da Twilio adquirido para este tutorial com o aplicativo TwiML que você criou. Dessa forma, sempre que esse número receber uma chamada telefônica, ele recuperará o URL do webhook e outras configurações no aplicativo TwiML e o usará para responder à chamada. Em nosso caso, ele enviará uma solicitação de POST para https://48dcc810632b.ngrok.io/handle_calls
contendo o número do chamador e outras informações úteis.
Volte para o seu navegador e navegue até http://localhost:3000/
, aguarde a mensagem Twilio.Device Ready!
a ser exibida na página e, em seguida, use um dispositivo capaz de fazer chamadas para ligar para o número Twilio que você comprou para este tutorial. Quando o número estiver tocando, você deverá ver o modal de chamada recebida :
Pressione o botão com o ícone verde para aceitar a chamada e o ícone de telefone vermelho para rejeitá-la.
Vá para o terminal que está executando nosso aplicativo Flask e os dados de solicitação que a Twilio envia para nosso endpoint /handle_calls
serão semelhante ao seguinte:
Conclusão
Neste tutorial, aprendemos a usar a API do Twilio Voice para fazer e receber chamadas telefônicas no navegador. Aprendemos a usar a estrutura do Flask para criar o aplicativo cliente que nos permitiu interagir com um dispositivo Twilio criado com o Twilio Client JS SDK.
O código de todo o aplicativo está disponível no seguinte repositório https://github.com/CSFM93/twilio-in-browser-calls.
Carlos Mucuho é um geólogo moçambicano que se tornou desenvolvedor e gosta de usar a programação para transformar ideias em realidade. https://github.com/CSFM93
Publicações relacionadas
Recursos relacionados
Twilio Docs
De APIs a SDKs e aplicativos de amostra
Documentação de referência de API, SDKs, bibliotecas auxiliares, guias de início rápido e tutoriais para sua linguagem e plataforma.
Centro de Recursos
Os mais recentes e-books, relatórios do setor e webinars
Aprenda com especialistas em engajamento do cliente para melhorar sua própria comunicação.
Ahoy
Centro da comunidade de desenvolvedores da Twilio
Melhores práticas, exemplos de código e inspiração para criar comunicações e experiências de engajamento digital.