Realiza y recibe llamadas telefónicas desde el navegador con Twilio Programmable Voice, Python y JavaScript.
Tiempo de lectura: 15 minutos
En este tutorial, escribiremos una aplicación que utiliza la API de voz programable de Twilio para realizar y recibir llamadas telefónicas desde un navegador web. También implementaremos una IU que nos permita realizar, aceptar y rechazar llamadas telefónicas.
Al final de este tutorial, tendremos una aplicación que se parecerá a la siguiente:
Requisitos del tutorial
Para seguir este tutorial, necesitarás los siguientes componentes:
- Una cuenta de Twilio gratuita o pagada. Si eres nuevo en Twilio, crea una cuenta gratuita ahora. Si creas tu cuenta con este enlace y, luego la actualizas a una cuenta pagada, recibirás USD 10 en crédito.
- Un número de teléfono de Twilio que pueda realizar y recibir llamadas. Obtén uno ahora si no lo tienes.
- Tener Python 3.6+ instalado.
- Tener ngrok instalado. ngrok es un servicio de proxy inverso que crea un túnel seguro desde un punto final público hacia un servicio web que se ejecuta localmente. Tendremos que utilizar ngrok para crear una URL segura que permita que Twilio se conecte a nuestra aplicación.
- Un teléfono celular o teléfono capaz de realizar y recibir llamadas telefónicas para probar el proyecto.
Conceptos básicos y lógica de la aplicación
El objetivo de este tutorial es crear una aplicación web que nos permita realizar y recibir llamadas telefónicas en el navegador. Utilizaremos la estructura Flask para implementar los webhooks necesarios y poner en funcionamiento la aplicación del cliente.
El cliente de la aplicación utilizará el SDK de Twilio Client JS (twilio.js
) para crear un dispositivo de Twilio.
Un dispositivo de Twilio es nuestro principal punto de entrada para realizar y recibir llamadas telefónicas en el navegador. Para configurar una conexión entre un dispositivo de Twilio y los servidores de Twilio, necesitaremos generar tokens de acceso en nuestro servidor de aplicaciones.
Los tokens de acceso son credenciales de corta duración que se pueden distribuir de forma segura a las aplicaciones del lado del cliente que podemos utilizar para autenticar SDK de Twilio Client como Voice (Voz), Conversations (Conversaciones), Sync (Sincronización) y Video (Video). Para generar tokens de acceso en nuestro servidor, tendremos que utilizar una clave de la API de Twilio.
Una clave de la API de Twilio es una credencial que nos otorga acceso a la API de Twilio. Una clave de API nos permite:
- autenticar con la API de Twilio;
- crear y revocar tokens de acceso.
Los tokens de acceso otorgarán al cliente acceso a una aplicación de TwiML . Twilio se basa en una aplicación de TwiML dentro de nuestra cuenta para determinar cómo interactuar con nuestro servidor.
TwiML (Twilio Markup Language) es un conjunto de instrucciones que se pueden utilizar para decirle a Twilio lo que debe hacer cuando recibe una llamada entrante, un SMS o un fax.
Creación de la estructura del proyecto
En esta sección, crearemos nuestro directorio de proyectos y, dentro de este, crearemos los directorios estándar para una aplicación de Flask. Después de eso, crearemos y activaremos un entorno virtual. Por último, instalaremos los paquetes Python necesarios para crear esta aplicación web.
Abre una ventana de tu terminal y ejecuta los siguientes comandos:
Aquí clonamos un proyecto de inicio que se creó para este tutorial con el nombre twilio-in-browser-calls
. Después de eso nos dirigimos a este directorio de proyectos. Este proyecto contiene el código base que usaremos para construir nuestra aplicación.
Encontrarás los siguientes directorios estándar para una aplicación de Flask en:
static
: aquí es donde se almacenan todos los archivos estáticos.templates
: aquí es donde se almacenan todas las plantillas.
El subdirectorio static
tiene los siguientes contenidos:
css
: aquí es donde almacenaremos todos los archivos CSS. Dentro de este subdirectorio encontrarás un archivo llamadostyle.css
. Este archivo será responsable de estilizar la IU para los clientes de nuestra aplicación.images
: aquí es donde almacenaremos todas las imágenes. Dentro de este subdirectorio, encontrarás un archivo llamadouser.png
, que se mostrará en nuestra IU para los clientes de nuestra aplicación.js
: aquí es donde almacenamos todos nuestros archivos Javascript. Dentro de este directorio, encontrarás un archivo con el nombremodals.js
. Este archivo contiene el código para administrar los modales almacenados en el directoriotemplates
.
El subdirectorio templates
tiene tres archivos: call_in_progress_modal.html
, dial_modal.html
y incoming_call_modal.html
.
El archivo call_in_progress_modal.html
contiene el código HTML que implementa un modal que se mostrará durante una llamada. Este modal muestra la duración de la llamada en curso, el número al que estás llamando y un botón con un ícono de teléfono rojo que te permitirá finalizar la llamada. Así es como se ve este modal:
El archivo dial_modal.html
contiene el código HTML que implementa un modal que aparecerá cuando desees marcar un número de teléfono. Este modal muestra un teclado numérico y un botón con un ícono de teléfono verde. Así es como se ve:
El archivo incoming_call_modal.html
contiene el código HTML de una plantilla que implementa un modal que solo aparecerá cuando recibes una llamada. Este modal muestra el número que te llama y dos botones, un botón con un ícono de teléfono verde y otro con un ícono de teléfono rojo. El primer botón te permitirá aceptar una llamada entrante y el segundo, rechazarla.
Dentro de nuestra carpeta de trabajo, crea un entorno virtual y actívalo. Si utilizas un sistema operativo Unix o Mac, introduce los siguientes comandos para hacerlo:
Si estás siguiendo este tutorial desde Windows, ingresa los siguientes comandos:
Ahora que creamos y activamos nuestro entorno virtual, podemos instalar las bibliotecas que necesitamos para crear nuestra aplicación:
En el comando anterior, utilizamos pip
, el instalador de paquetes de Python para instalar los siguientes paquetes que utilizaremos en este proyecto:
- Twilio, un paquete de Python para la comunicación con la API de Twilio.
- Flask, una microestructura de Python para construir aplicaciones web. La usaremos con el fin de crear un webhook para interactuar con Twilio y para crear la IU del cliente para realizar y recibir llamadas telefónicas.
- Python-dotenv, una biblioteca que lee pares de valores clave de un archivo y los agrega como variables de entorno. Utilizaremos este módulo para recuperar nuestras credenciales de Twilio almacenadas en un archivo de configuración
.env
.
Como referencia, en el momento en que se publicó este tutorial, estas eran las versiones de los paquetes anteriores y las dependencias que se probaron:
Aparte de los paquetes de Python mencionados anteriormente, usaremos las siguientes bibliotecas de la interfaz:
- Bootstrap, una potente estructura de interfaz utilizada para crear sitios web modernos.
- SDK de Twilio Client JS (twilio.js), una biblioteca que te permite realizar llamadas de voz desde un navegador web.
- JQuery, una biblioteca JavaScript rápida, pequeña y con muchas funciones que hace mucho más sencillo realizar tareas como la manipulación y el desplazamiento de documentos HTML, el manejo de eventos, la animación y Ajax. Lo usaremos para realizar alguna manipulación de DOM y manejo de eventos.
- Font Awesome, un popular conjunto de herramientas de SVG, fuente y CSS. Usaremos algunos de los íconos diseñados por ellas en nuestro cliente de la aplicación.
Crea una aplicación de TwiML
En esta sección, usaremos la consola de Twilio para crear una "aplicación de TwiML", en la que luego almacenaremos la URL del webhook que crearemos.
Abre una nueva ventana del navegador y sigue esta ruta: Twilio account Console > Voice > TwiML > TwiML Apps (consola de la cuenta Twilio > Voice > TwiML > aplicaciones de TwiML). Haz clic en el botón "Create new TwiML App" (Crear nueva aplicación de TwiML) o en el ícono rojo "+" si ya tienes otras aplicaciones de TwiML.
Ingresa el nombre de tu app de TwiML en el campo "Friendly Name" (Nombre descriptivo), por ejemplo, llamadas en el navegador. Deja los otros campos vacíos por ahora. Haz clic en el botón "Create" (Crear) para crear la aplicación de TwiML.
Se te redirigirá de nuevo al TwiML Apps dashboard (panel de control de aplicaciones de TwiML). Haz clic en la app de TwiML que acaba de crear. En la página de esta aplicación, selecciona el SID Value (valor de SID) y cópialo en el portapapeles.
En el directorio raíz del proyecto, crea un archivo con el nombre .env
e ingresa el siguiente contenido:
Creación de una clave de la API de Twilio
Para el siguiente paso, vamos a crear una clave de la API de Twilio para la API de voz. La clave de API se utilizará para generar tokens de acceso, lo que permitirá que la interfaz se ejecute en el navegador para realizar llamadas a las API de Twilio.
Sigue esta ruta en el navegador: Twilio console > Voice > Settings > API Keys (consola de Twilio > Voice > Configuración > Claves de API). Haz clic en el botón "Create new API Key" (Crear nueva clave de API) o en el ícono rojo "+" si ya tienes otras claves de API.
Ingresa el nombre de tu clave API en el campo "Friendly Name" (Nombre descriptivo), por ejemplo, llamadas en el navegador. Deja el "Key Type" (Tipo de clave) como "Standard" (Estándar). Haz clic en el botón "Create API Key" (Crear clave de API) para crear la clave de API.
Se te redirigirá a una página donde encontrarás información sobre tu nueva clave de API. Copia los valores "SID" (SID) y "Secret" (Secreto) y pégalos en tu archivo .env
como TWILIO_API_KEY_SID
y TWILIO_API_KEY_SECRET
. Tu archivo .env
debería verse de la siguiente manera:
Selecciona "Got it!" (Entendido) y, a continuación, haz clic en el botón "Done" (Listo).
Ahora ve a la Twilio Console home page (Página de inicio de la consola de Twilio) y copia el valor de SID de la cuenta de Twilio en el archivo .env
de la siguiente manera:
A continuación, sigue la ruta Twilio account console > Phone Numbers > Manage Numbers > Active Numbers (Consola de la cuenta de Twilio > Números de teléfono > Administrar números > Números activos), selecciona el número que compraste para este tutorial y se te redirigirá a una página donde puedes configurar este número. Busca el campo "Phone Number" (Número de teléfono), copia el número de teléfono que aparece en este campo y pégalo en el archivo .env
como TWILIO_NUMBER
. Elimina cualquier espacio entre los dígitos, pero deja el signo + inicial y asegúrate de que el número esté en formato E.164.
El archivo .env
debe tener el siguiente aspecto una vez que se agregue el número de teléfono:
Creación de una aplicación de Flask
En esta sección, crearemos la lógica de nuestra aplicación de Flask, que proporcionará las funciones de soporte necesarias para que el usuario realice y reciba llamadas telefónicas.
Creación del servidor de la aplicación
En esta sección, vamos a crear los puntos finales necesarios para realizar y recibir llamadas telefónicas. Necesitaremos crear los siguientes puntos finales:
/
: este punto final será responsable de prestar servicio a la IU de la aplicación (es decir, al cliente)./token
: este punto final será responsable de generar y devolver tokens de acceso al cliente./handle_calls
: este punto final será responsable de generar las instrucciones de TwiML necesarias para realizar y recibir llamadas telefónicas.
En el directorio raíz de su proyecto, crea un archivo con el nombre main.py
. Abre el archivo con tu editor de texto favorito y, luego, agrega el siguiente código:
Aquí, importamos todos los paquetes que necesitaremos para construir nuestra aplicación de servidor:
flask
se utilizará para definir los puntos finales de la aplicación.- El paquete de
twilio
se utilizará para interactuar con la API de Twilio, lo que nos permite realizar y recibir llamadas telefónicas a través del dispositivo de Twilio que se creará en el lado del cliente. load_dotenv
se utilizará para importar las credenciales de nuestra cuenta de Twilio desde el archivo.env
.pprint
se utilizará para formatear e imprimir los datos recibidos cuando Twilio envíe una solicitud al punto final/handle_calls
para notificar que hay una llamada.os
se utilizará junto conload_dotenv
para recuperar las credenciales almacenadas en el archivo.env
.
Agrega el siguiente código a la parte inferior del archivo main.py
:
La aplicación comienza importando las variables del entorno almacenadas en el archivo .env
con una llamada a load_dotenv()
. Esto nos permite recuperar las cinco variables de configuración que necesitamos para esta aplicación.
A continuación, creamos una instancia de una aplicación de Flask
en una variable llamada app
y con eso creamos el punto final /
de nuestra aplicación. Esta ruta brinda una plantilla con el nombre home.html
que crearemos más adelante.
Agrega el código siguiente debajo de la ruta /
:
Esto agrega el punto final /token
, que el cliente invocará para solicitar un token de acceso.
Cuando se activa este punto final, creamos una variable llamada identity
y la asignamos a nuestro número de Twilio. Una identidad es única para cada usuario y puede iniciar sesión en varios dispositivos a la vez. En un servidor de aplicaciones diseñado para que varios usuarios lo utilicen, debemos decidir, según la solicitud de token que se nos envíe, quién es el usuario y qué puede hacer. Para averiguar quién es el usuario (su identidad), usaremos nuestro sistema de inicio de sesión o proveedor de identidad existente (p. ej., cookies de sesión, un token de API o cualquier otro mecanismo que se utilice para asegurar sus solicitudes de API). Sin embargo, en este tutorial, somos el único usuario, por lo que no necesitamos trabajar con varias identidades y el número de Twilio que compramos para este tutorial funciona bien para este propósito.
A continuación, usamos account_sid
, api_key
, api_key_secret
y identity
para crear un token de acceso. El token se debe proporcionar con "concesiones", que determinan qué operaciones tiene permitido realizar el cliente que presenta el token. Para esta aplicación, creamos un objeto de concesión de voz que está configurado con el sid
de la app de TwiML que creamos anteriormente.
Para completar el punto final, devolvemos el access_token
y identity
al cliente en formato JSON.
Agrega el código siguiente debajo de la ruta /token
:
Este bloque agrega un punto final llamado /handle_calls
. Twilio invocará este punto final cada vez que hagamos o recibamos una llamada telefónica.
Cuando se activa este punto final, se utiliza pprint
para imprimir el contenido de request.form
y, luego, creamos un objeto de respuesta de TwiML
y un objeto de marcado de TwiML
. En el objeto dial
, el callerId
será el número de Twilio que compramos para este tutorial. De esta manera, cuando llamemos a un número de teléfono con esta aplicación, el teléfono del destinatario mostrará este número en lugar de anonymous
.
Después de eso, utilizamos la lógica condicional para comprobar si el objeto request.form
tiene la propiedad con el nombre To
y si este valor de propiedad no es el mismo que nuestro twilio_number
. Lo que esta prueba logra es asegurarse de que la invocación del punto final sea para realizar una llamada (y no recibir una), que es el primer caso que manejaremos.
Una vez que estamos seguros de que esta es una solicitud para realizar una llamada, estableceremos el número que queremos marcar en el valor del request.form['To']
, anexaremos el objeto dial
al objeto response
y devolveremos el objeto response
como una cadena que regresa a Twilio, que ejecutará estas instrucciones y marcará el número solicitado.
La parte inferior del guion es una condicional estándar que ejecuta el servidor de desarrollo de Flask en el puerto 3000 cuando se invoca el guion desde la línea de comandos.
Creación de un cliente de la aplicación
En esta sección, crearemos la interfaz que nos permitirá realizar y recibir llamadas telefónicas en el navegador.
Creación de la página de inicio
Crea un archivo con el nombre home.html
dentro del directorio templates
. Ábrelo y agrega el siguiente código:
Esta plantilla implementa una página que muestra una consola donde podemos monitorear el estado del dispositivo de Twilio que crearemos pronto con JavaScript. Hemos incluido en esta plantilla las plantillas call_in_progress_modal.html
, dial_modal.html
y incoming_call_modal.html
que venían con el modelo estándar de este proyecto. Esta página también muestra un botón con un ícono de teléfono. Cada vez que presionemos este botón, se abrirá un modal y, en este modal, ingresaremos el número al que nos gustaría llamar.
Aparte de Bootstrap, jQuery, FontAwesome y los archivos twilio.js
, observa cómo incluimos los siguientes archivos en esta plantilla:
style.css
: este archivo contiene algunos de las CSS utilizadas para modelar nuestra aplicación.main.js
: este archivo javascript contiene el código para crear un dispositivo de Twilio y conectarlo a nuestra aplicación de TwiML.modals.js
: este archivo javascript contiene el código para administrar los modales de nuestra aplicación.
Los archivos style.css
y modals.js
se encontraban dentro del repositorio estándar del proyecto. Vamos a crear el archivo main.js
en la siguiente sección.
Creación del dispositivo de Twilio
Crea un archivo con el nombre main.js
dentro del directorio static/js
. Ábrelo y agrega el siguiente código:
Aquí, crearemos el dispositivo de Twilio que nos permitirá realizar y recibir llamadas telefónicas en el navegador.
En primer lugar, utilizamos la función getJSON()
proporcionada por jQuery para enviar una solicitud GET (OBTENCIÓN) al punto final /token
de nuestro servidor de aplicaciones y obtener un token de acceso. Después de obtener el token, utilizamos twilio.js
y el token para crear un dispositivo de Twilio y conectarlo a nuestra aplicación de TwiML.
Después de crear el dispositivo de Twilio, agregamos algunos oyentes de eventos a este dispositivo y algún código que nos permitirá interactuar con este dispositivo mediante la IU.
Realizar llamadas telefónicas salientes
En esta sección, vamos a utilizar nuestra aplicación para realizar llamadas telefónicas. Sin embargo, antes de poder hacerlo, debemos ejecutar la aplicación, configurar ngrok y configurar nuestra aplicación de TwiML.
Abre una segunda ventana de terminal en nuestro directorio de proyectos, activa el entorno virtual de Python e inicia la aplicación ejecutando el siguiente comando:
Después de ejecutar el comando anterior, deberías ver algo similar a esto:
Copia la URL https
de ngrok en el portapapeles. Luego, sigue la ruta Twilio account Console > Voice> TwiML > TwiML Apps dashboard (Consola de la cuenta de Twilio > Voice> TwiML > Panel de control de aplicaciones de TwiML) y selecciona la app de TwiML que creaste para este tutorial.
Encuentra la sección "Voice" en la configuración de la app de TwiML y pega la URL https://
que proporcionó ngrok
seguida de /handle_calls
en el campo "Request URL" (Solicitar URL) y haz clic en el botón "Save" (Guardar). Esto creará un webhook que conecta tu aplicación a la app de TwiML.
En este ejemplo, la URL de ngrok es https://48dcc810632b.ngrok.io/handle_calls
. La primera parte de la URL será diferente cada vez que se inicie ngrok.
Ahora, conecta un auricular con micrófono a tu computadora, abre el navegador y escribe http://localhost:3000/
en la barra de direcciones. Deberías ver algo similar a esto:
Cuando veas un mensaje que diga Twilio.Device Ready!
(Tu dispositivo de Twilio está funcionando correctamente), sabrás que todo funciona como debería. Haz clic en el botón con el ícono verde del teléfono y verás el modal de marcado:
Utiliza los números del panel para insertar el número al que deseas llamar o simplemente escríbelo con el teclado en el campo de inserción sobre el panel y, una vez que esté listo, haz clic en el teléfono verde para realizar la llamada.
Cuando hagas clic en dicho botón, tu navegador te pedirá permiso para usar el micrófono y deberás concederlo. Cuando el número responda tu llamada, verás el modal de llamada en curso:
Ve a la terminal que ejecuta nuestra aplicación de Flask. Los datos de la solicitud que Twilio envía a nuestro punto final /handle_calls
se parecerán a estos:
Dado que el valor de la propiedad To
(el número al que llamamos) no es igual a nuestro número de Twilio, se ejecutó el código dentro de la declaración if
en el punto final handle_calls
.
Responder llamadas telefónicas entrantes
En la sección anterior, pudiste utilizar tu aplicación para realizar llamadas telefónicas, pero hasta ahora no puedes recibir ninguna llamada. Para poder recibir llamadas, necesitaremos agregar un código adicional a main.py
, main.js
y home.html
, así como configurar el número que compramos para este tutorial en la consola de Twilio para que pueda recibir llamadas telefónicas.
Vuelve al archivo main.py
y reemplaza el código en el punto final /handle_calls
con el siguiente:
Aquí hemos agregado la declaración else
al punto final /handle_calls
. El código en esta parte se ejecutará si el número que recibe la llamada es el número que compramos para este tutorial, lo que significa que tenemos una llamada entrante.
Estamos configurando el callerId
en el objeto de marcado de TwiML para el valor de la propiedad Caller
en request.form
. Caller
(palabra que, en inglés, significa "agente de llamada") es el número que llama a nuestro número de Twilio. Esto es para que podamos ver quién nos llama en la IU de nuestra aplicación. También estamos configurando el client
en el objeto de marcado con el valor identity
que utilizamos cuando creamos un token de acceso en el punto final /token
.
Para completar el flujo de llamadas entrantes, adjuntamos el objeto de marcado al objeto de respuesta de TwiML y, luego, devolvemos este objeto de respuesta como una cadena.
Vuelve a tu archivo main.js
y agrega el siguiente código debajo del oyente device.on(‘disconnect')
:
Aquí agregamos un oyente de eventos que permitirá que el dispositivo de Twilio monitoree las llamadas entrantes y muestre el modal de llamadas entrantes una vez que detecte una.
Sigue la ruta Twilio console > Phone Numbers > Manage Numbers > Active Numbers dashboard (Consola de Twilio > Números de teléfono > Administrar números > Panel de control de números activos) y selecciona el número que compraste para este tutorial.
Busca la sección "Voice & Fax" (Voz y fax) de la configuración del número de teléfono y selecciona "TwiML App" (App de TwiML) en el campo "Configure With" (Configurar con). Luego, selecciona el nombre de la app de TwiML que creaste para este tutorial en el campo "TwiML App" (App de TwiML). Esto vinculará el número de Twilio que compraste para este tutorial con la app de TwiML que creaste. De esta manera, cada vez que este número reciba una llamada telefónica, obtendrás la URL del webhook y otros ajustes en la app de TwiML y la usarás para responder a la llamada. En nuestro caso, enviará una solicitud POST a https://48dcc810632b.ngrok.io/handle_calls
que contenga el número del agente de llamada y otra información útil.
Vuelve a tu navegador y ve a http://localhost:3000/
, espera a que el mensaje Twilio.Device Ready!
(Tu dispositivo de Twilio está funcionando correctamente) aparezca en la página y, a continuación, utiliza un dispositivo capaz de realizar llamadas telefónicas para llamar al número de Twilio que compraste para este tutorial. Cuando el número dé tono, deberías ver el modal de llamada entrante:
Presiona el botón con el ícono verde para aceptar la llamada y el botón con el ícono rojo para rechazarla.
Ve a la terminal que ejecuta nuestra aplicación de Flask. Los datos de la solicitud que Twilio envía a nuestro punto final /handle_calls
se parecerán a estos:
Conclusión
En este tutorial, aprendimos a utilizar la API de Twilio Voice para realizar y recibir llamadas telefónicas en el navegador. Aprendimos cómo utilizar la estructura Flask para construir el cliente de aplicación que nos permitió interactuar con un dispositivo de Twilio creado con el SDK de Twilio Client JS.
El código para la aplicación completa está disponible en el siguiente repositorio https://github.com/CSFM93/twilio-in-browser-calls.
Carlos Mucuho es un geólogo mozambiqueño que se ha convertido en desarrollador y disfruta de usar la programación para hacer que las ideas se vuelvan realidad https://github.com/CSFM93.
Publicaciones relacionadas
Recursos relacionados
Twilio Docs
Desde API hasta SDK y aplicaciones de muestra
Documentación de referencia de API, SDK, bibliotecas auxiliares, inicios rápidos y tutoriales para su idioma y plataforma.
Centro de Recursos
Los últimos libros electrónicos, informes de la industria y seminarios web
Aprenda de los expertos en participación del cliente para mejorar su propia comunicación.
Ahoy
Centro de la comunidad de desarrolladores de Twilio
Mejores prácticas, ejemplos de códigos e inspiración para crear comunicaciones y experiencias de participación digital.