
Compartir:
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.
Potenciación de las llamadas de voz con la API de Vonage Detección de personas/máquinas y Flask
Tiempo de lectura: 13 minutos
Introducción
En determinados escenarios empresariales, surge la necesidad de establecer una comunicación basada en la voz con los clientes, en la que las limitaciones de tiempo se convierten en un factor crítico a la hora de entregar mensajes de voz de forma eficiente, especialmente cuando la mano de obra disponible es limitada. Cuando un agente inicia una llamada marcando un número de teléfono, debe armarse de paciencia hasta que la llamada es atendida por la parte receptora, que puede ser un humano o un sistema de buzón de voz. Estas interacciones consumen tiempo y recursos valiosos.
Aprovechando la Voice API de Vonage y sus capacidades aumentadas que abarcan la detección humana, de buzón de voz y de pitidos, es posible automatizar todo el proceso de comunicación con una implementación de código mínima. Además, la sofisticada función de detección de máquinas garantiza la entrega completa del mensaje deseado. El siguiente tutorial le guiará en el inicio de la automatización de las llamadas de voz, con la identificación de entidades humanas o de buzón de voz. El código fuente de esta aplicación se encuentra en Github.
1. Requisitos previos
Existen requisitos previos específicos que debes cumplir antes de usar la Voice API de Vonage. Esto incluye crear una cuenta de desarrollador de Vonage, obtener un número virtual, configurar un entorno Python junto con la aplicación Flask y la aplicación ngrok Ingress. Las siguientes secciones describen estos requisitos previos en detalle.
Crear una cuenta de desarrollador de Vonage
Vonage es un proveedor líder de comunicaciones que ofrece a los desarrolladores acceso a API para enviar voz, vídeo y mensajes. En registrarte para obtener una Account gratuitatendrás acceso a créditos gratuitos y a una sencilla documentación para utilizar las API de Vonage. Una vez que hayas obtenido la clave y el secreto de API, sigue la documentación para crear una aplicación de voz usando Dashboard y generar un JWT que será necesario en los próximos pasos. Puedes leer más sobre la generación de JWT aquí.
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
Obtener un número de teléfono virtual
Una vez completada la inscripción, obtén un número de teléfono virtual del sitio web de Vonage. En algunos países, se requieren números de teléfono para realizar una llamada, y el identificador de llamadas "desconocido" no está permitido para realizar una llamada. Por lo tanto, es muy recomendable obtener un número de teléfono virtual por un módico precio.
Configuración del servidor Flask y la aplicación ngrok Ingress
Se necesita un servidor web que pueda comunicarse con un punto final publicado para recibir eventos del progreso de la llamada y emitir posteriormente elementos de acción. Flask es un marco de aplicaciones web que ocupa poco espacio y utiliza Python para crear aplicaciones basadas en web. Configure el servidor Flask en su entorno utilizando la documentación oficial.
Para acceder a una aplicación Flask ejecutada localmente, necesitas una URL pública accesible a través de Internet. Aquí está el conjunto mínimo de instrucciones para comprobar si Python está instalado y configurar Flask en su máquina:
Puede utilizar ngrok para alojar el servidor web en su máquina local y enviar/recibir peticiones desde la Web. Se recomienda instalar la última versión de ngrok. Aquí hay un conjunto mínimo de instrucciones para configurar ngrok en tu Mac y comprobar su versión:
Para empezar, aquí está el código Python mínimo para iniciar el servidor flask y enviar un saludo 'Hola Mundo':
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)
Guarda el código anterior en callback.py y ejecútalo utilizando el siguiente comando:
Ahora puede apuntar su navegador a la dirección IP pública o a la URL de entrada ngrok para ver si la aplicación es accesible a través de Internet y está lista para el siguiente paso.
2. Realizar una llamada de Voice y seguir eventos
Ahora que ha completado los requisitos previos, es el momento de realizar la primera llamada de voz y seguir el progreso de esa llamada de voz. Varias maneras de realizar una llamada incluyen el uso de SDK en Node.js, Python, o .NET. La forma más fácil es utilizando el comando curl, que vamos a demostrar aquí.
El ejemplo está tomado de aquí y modificado para 'action: talk'. Para realizar una llamada, utilice el comando curl o utilice Postman con la opción import:
Sustituye lo siguiente por:
YOUR_JWT = JWT generado en el paso anterior
YOUR_MOBILE_NUMBER = Número de móvil para recibir la llamada de voz
YOUR_VIRTUAL_NUMBER = Número virtual obtenido en el paso anterior
YOUR_CALLBACK_URL = URL de entrada ngrok o dirección IP pública de la aplicación del servidor Flask
Si echa un vistazo a los registros de la aplicación Flask, verá los detalles de la progresión de las llamadas desde que se inician hasta que suenan.
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"}'Enhorabuena por realizar su primera llamada de voz automatizada. Si no puede realizar una llamada, puede haber muchas razones para no recibirla en su teléfono móvil. Puede deberse a que el usuario no se ha autenticado, a que el JWT no se ha acuñado correctamente o a que el campo "de" no se ha configurado correctamente. Siempre puedes solucionar los problemas de las llamadas utilizando los datos de la respuesta del comando e Inspector de voz .
3. Añadir Detección Humana/Buzón de Voz a la Llamada
Ahora que puede realizar una llamada, es el momento de añadir funciones avanzadas para detectar quién está al otro lado de la llamada. Hay varios escenarios posibles para descolgar la llamada:
Un humano
Un saludo de voz
Un saludo del buzón de voz seguido de un pitido
Con la función de detección de buzón de voz/humano, cada caso puede tratarse de forma específica para transmitir correctamente el mensaje en las llamadas de voz.
Para añadir el reconocimiento humano/de voz, actualice el comando curl con la opción 'advanced_machine_detection' (puede encontrar más detalles sobre este parámetro aquí):
Si coges la llamada y dices "hola", la voz se interpretará como una voz humana, y se generará un evento "estado: humano" que se enviará en la devolución de llamada del progreso de la llamada, y que podrás ver en los registros de la aplicación del 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"}'Los saludos del buzón de voz se interpretan como 'estado: máquina', y si se detecta un pitido después del buzón de voz, se enviará un parámetro adicional 'sub_state: beep_start' en la devolución de llamada. Todos estos eventos pueden resumirse como sigue:
Si la llamada la coge una persona -> "status": "human"
Si la llamada va a un buzón de voz que no tiene bip después -> "status": "machine" y luego "sub_state": "beep_timeout" cuando se agote el tiempo de espera del pitido
Si la llamada va al buzón de voz con bip -> primero "status": "machine" y luego "sub_state": "beep_start" cuando se detecta el pitido
La detección de pitidos es una función muy útil, ya que le permitirá saber con precisión cuándo comienza la grabación del buzón de voz. Con la detección de pitidos, el mensaje que queda en la grabación se truncará y podría quedar claro cuando lo reproduzca la persona que escucha, ya que se perderá la parte del mensaje anterior al pitido.
4. Alteración de la progresión de llamadas basada en la detección de personas/correos electrónicos
Utilicemos las capacidades de reconocimiento del buzón de voz para alterar el curso de la progresión de las llamadas. Para un escenario sencillo, supongamos que desea reproducir mensajes específicos según la detección de humanos/buzón de voz. Por ejemplo:
Reproducir un mensaje "Estoy hablando con un humano" cuando se detecta a una persona.
Reproducir un mensaje "Estoy hablando con el buzón de voz antes del pitido" cuando se detecta el buzón de voz.
Reproducir un mensaje "Estoy hablando con el buzón de voz después del pitido" cuando se detecta el pitido.
Ten en cuenta que ya recibes los resultados de la detección del buzón de voz en la progresión de llamadas mediante callbacks; sólo es cuestión de procesar la información y añadir la lógica de toma de decisiones en tu código Flask. Aquí está el código Flask actualizado que será capaz de procesar la detección de buzón de voz y generar la respuesta 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)Vuelva a realizar la llamada utilizando el comando curl con la opción 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." }
]
}'En el ejemplo anterior, la llamada se iniciará con una simple acción de hablar:
{ "action": "talk", "text": "This is a test call." }A medida que avanza la llamada, la acción de hablar será sustituida por otra acción de hablar, en función de la detección de humano/correo de voz. p. ej:
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. Conclusión con un ejemplo del mundo real
Por último, pongamos en práctica esta capacidad mejorada de llamadas de voz a partir de un escenario real. Imagine que está realizando una campaña de llamadas de voz y que sólo le interesa atender llamadas con una persona real. Entonces, si una persona coge la llamada, se conecta a su número de teléfono. En caso contrario, deja un mensaje después del tono si la llamada va al buzón de voz. Para resumir el caso de uso:
Conectar el teléfono del activista para hablar con la persona que atiende el teléfono
Si no, deja un mensaje en el buzón de voz después de la señal: "Hemos intentado localizarle; póngase en contacto con nosotros inmediatamente".
Aquí está el código Flask actualizado que será capaz de procesar la detección del buzón de voz y generar la respuesta 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)En el código, sustituya YOUR_VIRTUAL_NUMBER por un número virtual obtenido previamente y CALL_CAMPAIGNER_PHONE_NUMBER por un número al que desee que se le conecte cuando una persona descuelgue una llamada.
Probemos el código realizando una llamada mediante el 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. Conclusión
Siguiendo los pasos de este tutorial, has creado con éxito una capacidad de llamada de voz mejorada para detectar si un humano, un buzón de voz o un buzón de voz coge la llamada con un pitido. Al mismo tiempo, has utilizado la aplicación Flask para decidir el curso de las acciones en la llamada de forma dinámica. Utilizando estos sencillos fragmentos de código, puede impulsar rápidamente campañas de llamadas, realizar llamadas masivas y enviar mensajes de voz correctamente sin interacción humana. De nuevo, el código fuente de esta aplicación se puede encontrar en Github.
Conceptos adicionales y documentación relacionada con la API de Detección de Máquinas pueden encontrarse en Detección avanzada de máquinas.
¿Tienes preguntas o comentarios sobre este tutorial? Comparte tus opiniones con nosotros en Twitter o en nuestro canal canal Slack de la comunidad de Vonage citando este artículo para obtener una respuesta rápida. También puedes conectar conmigo conmigo en Twitter. ¡Buena suerte y feliz codificación!
Compartir:
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.
