
Compartir:
Naomi Pentrel is a Software Engineer with a passion for organizing and attending hackathons. She has worked at companies such as Google, Microsoft, and Palantir. In her free time, she occasionally blogs about her side projects.
Construye un pez Babel con Nexmo y la API de voz de Microsoft Translator
Tiempo de lectura: 12 minutos
Si has estado en internet en estos últimos meses es muy probable que hayas visto los Pixel Buds de traducción en tiempo real de Google. Una tecnología bastante parecida al pez Babel de Guía del autoestopista galáctico que puede traducir cualquier habla sensible para su portador, permitiéndole así comunicarse con prácticamente cualquier ser. Por supuesto, los Pixel Buds de Google tienen un precio, así que ¿por qué no fabricar los nuestros? Eso es lo que Danielle y yo pensamos en la última hackference. Creamos un Nexmo Babel fish que permite a dos personas hablar por teléfono y que cada una escuche una versión traducida de lo que dice la otra.
Babelfish
En este blogpost, vamos a repasar cómo funciona este sistema de peces Babel paso a paso a partir de la instalación y configuración necesaria. A continuación, configuraremos un número Nexmo para gestionar las llamadas entrantes. A continuación, implementaremos un servidor Python que recibirá la voz a través de un WebSocket y enrutará la voz entrante desde el número Nexmo a la API Microsoft Translator Speech. Utilizaremos el Translator Speech API para gestionar la transcripción y la traducción. Además, implementaremos la lógica para gestionar un diálogo bidireccional e indicar al número Nexmo que pronuncie las traducciones. Para facilitar la implementación, ambas partes tendrán que llamar al número Nexmo de nuestro servicio. A continuación, puede ver un diagrama de sistema de alto nivel de cómo se procesa una instancia de habla de cualquiera de las partes. Tenga en cuenta que a lo largo de este tutorial utilizaré el ejemplo de una conversación alemán/inglés británico.

Si prefiere ver sólo el código, está disponible en GitHub aquí.
Requisitos previos
Necesitarás tener Python 2.x o 3.x y el software de tunelización HTTP ngrok instalados para poder continuar. Enumeraremos todos los comandos que necesitas para instalar todo lo demás.
Primeros pasos
Configure su entorno
Empecemos con nuestra solución DIY Babel fish configurando un entorno virtual para este proyecto utilizando Virtualenv. Virtualenv nos permite aislar las dependencias de este proyecto de nuestros otros proyectos. Vamos a crear un directorio para este proyecto y copiar la siguiente lista de dependencias en un archivo en el directorio del proyecto llamado requirements.txt:
nexmo
tornado>=4.4.2
requests>=2.12.4
Para crear y activar tu entorno virtual, ejecuta los siguientes comandos en tu terminal:
virtualenv venv # sets up the environment
source venv/bin/activate # activates the environment
pip install -r requirement.txt # installs our dependencies
# if you are running python3 please run the following instead
pip3 install -r requirement.txtEn este punto, por favor inicie ngrok en una ventana de terminal separada ejecutando el siguiente comando. ngrok nos permitirá exponer nuestro localhost en el puerto 5000 a las peticiones entrantes. Tendrás que mantener ngrok ejecutándose en segundo plano para que esto funcione. Puedes leer más sobre la conexión de ngrok con Nexmo aquí.
ngrok http 5000Una vez que ejecute el comando anterior, su terminal debe ser similar a la siguiente captura de pantalla. Necesitará la URL de reenvío cuando configure su aplicación y número Nexmo en los siguientes pasos.

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.
This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.
Crear una aplicación Nexmo
Ve a tus Applications y añade una nueva aplicación. Utiliza la URL de reenvío Ngrok tanto para la URL de Evento como para la URL de Respuesta añadiendo /event como ruta para la URL del evento (por ejemplo http://016a0331.ngrok.io/event) y /ncco para la URL de respuesta (por ejemplo http://016a0331.ngrok.io/ncco). Configuraremos estos puntos finales más adelante. Genere un par de claves pública/privada a través de la interfaz de usuario y guarde la clave en su ordenador.

El último paso para la configuración de nuestro número es vincular el número que ha adquirido anteriormente a su aplicación. Utilice el panel de control de la aplicación para vincular el número.

Obtener claves para el Translator Speech API de Microsoft
El otro servicio que vamos a necesitar configurar es Translator Speech API de Microsoft. Regístrese para obtener una Account gratuita de Microsoft Azure en azure.com y después vaya a portal.azure.com y cree un recurso Translator Speech API. Necesitará la clave que genera para el siguiente paso.

Gestión de secretos y configuración
Ahora que tenemos nuestro número Nexmo y nuestra clave API Translator Speech, todo lo que tenemos que hacer es configurar un archivo secrets y config con todos estos detalles importantes para que no tengamos que seguir escribiéndolos y podamos mantenerlos gestionados por separado. Guarde lo siguiente en secrets.py en la carpeta de tu proyecto y sustituye los valores de los marcadores de posición por tus valores.
# Replace the below values with your values
# Your API key and secret can be found here ${CUSTOMER_DASHBOARD_URL}/getting-started-guide
NEXMO_API_KEY = "<your-api-key>"
NEXMO_API_SECRET = "<your-api-secret>"
# Your nexmo number
NEXMO_NUMBER = "+447512345678"
# This is found on your Nexmo application’s dashboard
NEXMO_APPLICATION_ID = "<nexmo-application-id>"
# This is the private key you downloaded when setting up your application
NEXMO_PRIVATE_KEY = '''-----BEGIN PRIVATE KEY-----
<your-private-key>
cobranding_allowed: false
-----END PRIVATE KEY-----'''
# You will have to sign up for a free Microsoft account to use the Microsoft Translator Speech API: http://docs.microsofttranslator.com/speech-translate.html
MICROSOFT_TRANSLATION_SPEECH_CLIENT_SECRET = "<your-api-key>"
A continuación, guarde el archivo en config.py en la carpeta de tu proyecto y sustituye de nuevo los valores del marcador de posición por tus valores. Tenga en cuenta que puede elegir otros idiomas además de los que se indican a continuación. También puede modificarlos posteriormente en cualquier momento.
HOSTNAME = '<your-value>.ngrok.io'
# Replace the variable assignment with your number in the same format
CALLER = '447812345678'
# Replace the variable assignment with your languages
LANGUAGE1 = 'de-DE'
# Replace the variable assignments with the respective name for your language. They can be found here:
# https://developer.nexmo.com/api/voice/ncco#voice-names
VOICE1 = 'Marlene'
# the other person's language and voice
LANGUAGE2 = 'en-US'
VOICE2 = 'Kimberly'
Pasos del tutorial
A continuación vamos a ver primero cómo autenticar con el Translator Speech API. A continuación, vamos a configurar nuestro servidor Web Tornado utilizando una plantilla suministrada. A continuación, implementaremos CallHandlerel EventHandlery el WSHandler. El CallHandler gestionará por nosotros las llamadas entrantes al número Nexmo. Además, el EventHandler se utilizará para gestionar los eventos que Nexmo envíe, como el inicio o la finalización de una llamada. Con cada evento, Nexmo envía información sobre el actor que inició o completó la llamada. Utilizaremos esta información para almacenar quién está en una llamada específica. La dirección WSHandler mientras tanto se utilizará para abrir el WebSocket a través del cual Nexmo y nuestro servidor Python se comunicarán. El servidor Python creará fragmentos de audio y los enviará al Translator Speech API. El manejador utilizará la información que EventHandler para enrutar los mensajes correctamente. Cada una de las secciones siguientes explicará estos conceptos con más detalle y mostrará la implementación respectiva.
Autenticarse con Translator Speech API de Microsoft
Para utilizar la Translator Speech API necesitamos obtener un token al que llamamos MICROSOFT_TRANSLATION_SPEECH_CLIENT_SECRET. Por suerte Microsoft proporciona un Python AzureAuthClient que utilizaremos sin cambios. Por favor, copie lo siguiente y guárdelo en un archivo llamado azure_auth_client.py en el directorio de tu proyecto.
"""
Code example for getting a A from the Azure Platform.
Visit http://docs.microsofttranslator.com/oauth-token.html to view the API reference
for Microsoft Azure Cognitive Services authentication service.
"""
from datetime import timedelta
from datetime import datetime
import requests
class AzureAuthClient(object):
"""
Provides a client for obtaining an OAuth token from the authentication service
for Microsoft Translator in Azure Cognitive Services.
"""
def __init__(self, client_secret):
"""
:param client_secret: Client secret.
"""
self.client_secret = client_secret
# token field is used to store the last token obtained from the token service
# the cached token is re-used until the time specified in reuse_token_until.
self.token = None
self.reuse_token_until = None
def get_access_token(self):
'''
Returns an access token for the specified subscription.
This method uses a cache to limit the number of requests to the token service.
A fresh token can be re-used during its lifetime of 10 minutes. After a successful
request to the token service, this method caches the access token. Subsequent
invocations of the method return the cached token for the next 5 minutes. After
5 minutes, a new token is fetched from the token service and the cache is updated.
'''
if (self.token is None) or (datetime.utcnow() > self.reuse_token_until):
token_service_url = 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken'
request_headers = {'Ocp-Apim-Subscription-Key': self.client_secret}
response = requests.post(token_service_url, headers=request_headers)
response.raise_for_status()
self.token = response.content
self.reuse_token_until = datetime.utcnow() + timedelta(minutes=5)
return self.token
Crear un servidor
El protocolo de comunicaciones informáticas WebSockets nos permite disponer de un canal de comunicación bidireccional a través de una única conexión TCP. Voice API de Nexmo le permite conectar llamadas telefónicas a dichos puntos finales WebSocket. Utilizaremos el framework web Tornado Web server ya que implementa el protocolo WebSocket por nosotros.
Si usted ha estado siguiendo a lo largo y el nombre de todos los archivos como se describe, puede comenzar con la siguiente Tornado configuración del servidor Web. Este código maneja todas nuestras importaciones, configura el cliente Nexmo y el cliente azure auth, e inicia un servidor en el puerto 5000. Tenga en cuenta que este servidor no hace nada útil todavía. Tiene tres puntos finales: ncco, event, y socket que llaman a CallHandler, EventHandlery WSHandler respectivamente. Implementaremos los manejadores en las siguientes secciones.
Cree un archivo llamado main.py en el directorio de tu proyecto y copia este código en él.
from string import Template
import json
import os
import requests
import struct
import StringIO
from tornado import httpserver, httpclient, ioloop, web, websocket, gen
from xml.etree import ElementTree
import nexmo
from azure_auth_client import AzureAuthClient
from config import HOSTNAME, CALLER, LANGUAGE1, VOICE1, LANGUAGE2, VOICE2
from secrets import NEXMO_APPLICATION_ID, NEXMO_PRIVATE_KEY, MICROSOFT_TRANSLATION_SPEECH_CLIENT_SECRET, NEXMO_NUMBER
nexmo_client = nexmo.Client(application_id=NEXMO_APPLICATION_ID, private_key=NEXMO_PRIVATE_KEY)
azure_auth_client = AzureAuthClient(MICROSOFT_TRANSLATION_SPEECH_CLIENT_SECRET)
conversation_id_by_phone_number = {}
call_id_by_conversation_id = {}
class CallHandler(web.RequestHandler):
@web.asynchronous
def get(self):
self.write("Hello world")
class EventHandler(web.RequestHandler):
@web.asynchronous
def post(self):
self.write("Hello world")
class WSHandler(websocket.WebSocketHandler):
def open(self):
print("WebSocket opened")
def on_message(self, message):
self.write_message(u"You said: " + message)
def on_close(self):
print("WebSocket closed")
def main():
application = web.Application([
(r"/event", EventHandler),
(r"/ncco", CallHandler),
(r"/socket", WSHandler),
])
http_server = httpserver.HTTPServer(application)
port = int(os.environ.get("PORT", 5000))
http_server.listen(port)
print("Running on port: " + str(port))
ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main() Implementar el CallHandler
Para conectar las llamadas telefónicas a los puntos finales WebSocket, la Voice API de Nexmo utiliza un protocolo Nexmo Ctodo Control Objeto (NCCO) o una llamada API. Cuando alguien llama a tu número Nexmo, Nexmo emitirá una solicitud get a la URL de respuesta que proporcionaste al configurar tu aplicación Nexmo Voice. Apuntamos nuestra aplicación a nuestro servidor que ahora necesita responder a esta solicitud devolviendo un mensaje NCCO. Este NCCO debe instruir a Nexmo para dar un breve mensaje de bienvenida a la persona que llama y luego conectar a la persona que llama al WebSocket.
Diagram that shows the interactions between a user, Nexmo, and the web server. When the user calls the Nexmo number, Nexmo sends a GET request to the web server's /ncco endpoint. The web server responds with an NCCO that instructs Nexmo to open a socket with the web server.
Siga adelante y guarde lo siguiente NCCO en un archivo llamado ncco.json dentro del directorio de su proyecto. Contiene una plantilla que realizará las acciones requeridas. Sin embargo, incluye algunas variables de marcador de posición ($hostname, $whoamiy $cid) que tendremos que sustituir más adelante cuando la utilicemos.
[
{
"action": "talk",
"text": "Please wait while we connect you."
},
{
"action": "connect",
"eventUrl": [
"http://$hostname/event"
],
"from": "12345",
"endpoint": [
{
"type": "websocket",
"uri" : "ws://$hostname/socket",
"content-type": "audio/l16;rate=16000",
"headers": {
"whoami": "$whoami",
"cid": "$cid"
}
}
]
}
]En la plantilla para el servidor, la sección que se reproduce a continuación configura el mapeo entre el /ncco y el endpoint CallHandler. Esta asignación garantiza que cuando el /ncco reciba una petición GET, el método CallHandlersea ejecutado por el servidor.
application = web.Application([
(r"/event", EventHandler),
(r"/ncco", CallHandler),
(r"/socket", WSHandler),
])Cuando el servidor ejecuta el método, devuelve un ensamblado NCCO utilizando el siguiente código. Para empezar, recogemos los datos de la consulta (es decir, la petición GET) en una variable data variable. También almacenamos el conversation_uuid para su uso posterior. En este caso, hay una sentencia print para que puedas ver los conversation_uuid cuando estés probando tu servidor. En el siguiente paso, el código carga la variable NCCO desde el archivo ncco.json que hemos creado. Para completar la carga NCCOsustituimos las variables ($hostname, $cidy $whoami) por los valores recogidos de la variable de datos. Después de la sustitución, estamos listos para enviarlo de nuevo a Nexmo.
Sustituya el CallHandler de la plantilla anterior por este código:
class CallHandler(web.RequestHandler):
@web.asynchronous
def get(self):
data={}
data['hostname'] = HOSTNAME
data['whoami'] = self.get_query_argument('from')
data['cid'] = self.get_query_argument('conversation_uuid')
conversation_id_by_phone_number[self.get_query_argument('from')] = self.get_query_argument('conversation_uuid')
print(conversation_id_by_phone_number)
filein = open('ncco.json')
src = Template(filein.read())
filein.close()
ncco = json.loads(src.substitute(data))
self.write(json.dumps(ncco))
self.set_header("Content-Type", 'application/json; charset="utf-8"')
self.finish()Cada vez que alguien llame al número de Nexmo, Nexmo enviará una solicitud GET a nuestro endpoint /ncco y el CallHandler ensamblará y enviará el archivo NCCO. A continuación, Nexmo realizará las acciones previstas en el archivo . NCCO. En este caso, eso significa que la persona que llama oirá "Por favor, espere mientras le conectamos".. Después, Nexmo intentará conectar la llamada al punto final proporcionado. socket proporcionado. También proporciona a Nexmo el event endpoint que se utilizará. Si ahora inicia su servidor ejecutando python main.py en tu ventana de terminal, verás que oirás el mensaje pero la llamada terminará después. Esto es porque no hemos implementado el EventHandler o la función WSHandler. ¡Hagámoslo ahora!
Implementar el EventHandler
El sitio EventHandler gestiona los eventos que Nexmo envía. Estamos interesados en cualquier llamada entrante y, por lo tanto, comprobamos cualquier solicitud entrante para ver si su cuerpo contiene una dirección direction y si esa dirección es incoming. Si lo es, querremos almacenar el uuid y terminar el contexto de la petición. El diccionario call_id_by_conversation_id se utilizará para enrutar los mensajes entre las llamadas en el directorio WSHandler.
Sustituye el EventHandler de la plantilla por este código:
class EventHandler(web.RequestHandler):
@web.asynchronous
def post(self):
body = json.loads(self.request.body)
if 'direction' in body and body['direction'] == 'inbound':
if 'uuid' in body and 'conversation_uuid' in body:
call_id_by_conversation_id[body['conversation_uuid']] = body['uuid']
self.content_type = 'text/plain'
self.write('ok')
self.finish() Implementar el WSHandler
En CallHandler y el EventHandler han permitido a nuestra aplicación establecer la llamada. El WSHandler se encargará ahora del flujo de audio de la llamada. El discurso del interlocutor principal será transcrito y traducido por el Traductor Voice API, y el texto resultante será pronunciado por una voz Nexmo al otro lado de la línea. De este modo, la segunda persona podrá escuchar a la persona que llama en un idioma que entienda y responder posteriormente. La Translator Speech API traducirá a su vez la respuesta para que la primera persona la oiga en su idioma. Este flujo de trabajo es el que vamos a implementar a continuación.
Cuando la Voice API de Nexmo se conecta a un WebSocket, Nexmo envía una solicitud HTTP GET inicial al punto final. Nuestro servidor responde con un HTTP 101 para cambiar de protocolo, y el servidor se conectará posteriormente a Nexmo utilizando TCP. Esta actualización de la conexión es manejada para nosotros por Tornado. Cada vez que alguien hace una llamada a nuestro número Nexmo, Nexmo abrirá un WebSocket para la duración de la llamada. Cuando un WebSocket se abre y finalmente se cierra, el framework Tornado llamará a la función open y close a continuación. No necesitamos hacer nada en ninguno de los dos casos, pero imprimiremos mensajes para que podamos seguir lo que está pasando cuando ejecutemos el servidor.
Ahora que tenemos una conexión abierta, Nexmo enviará mensajes que manejamos en el método on_message método. El primer mensaje que recibiremos de Nexmo será texto plano con metadatos. Al recibir este mensaje, estableceremos la propiedad whoami de la propiedad WSHandler para poder identificar al interlocutor. Después, crearemos una cabecera wave que enviaremos al Translator Speech API. Para enviar mensajes a la Translator Speech API, crearemos un archivo . translator_future. En función del emisor, es decir, de la persona de la que procede el mensaje, crearemos el archivo translator_future con las respectivas variables de idioma para que la API sepa de qué idioma traducir a qué otro idioma.
A translator_future es otro WebSocket que se conecta a la API del Traductor de Voz. Lo utilizamos para pasar los mensajes que recibimos de la Voice API de Nexmo. Tras su creación, el translator_future se almacena en la variable ws y se utiliza para enviar la cabecera wave que hemos creado antes. Cada mensaje posterior de Nexmo será un mensaje binario. Estos mensajes binarios son pasados al Translator Speech API usando la variable translator_future que procesa el audio y devuelve la traducción transcrita.
Cuando inicializamos el método translator_futureestablecemos que cuando la Translator Speech API haya procesado nuestro mensaje deberá llamar al método speech_to_translation_completed. Este método, al recibir un mensaje, comprobará que el mensaje no está vacío y, a continuación, pronunciará el mensaje en el idioma de voz del receptor del mensaje. Sólo dirá el mensaje para la otra persona que llama, no para la persona que habló inicialmente. Además, imprimirá la traducción en el terminal.
Sustituye el WSHandler de la plantilla por este código:
class WSHandler(websocket.WebSocketHandler):
whoami = None
def open(self):
print("Websocket Call Connected")
def translator_future(self, translate_from, translate_to):
uri = "wss://dev.microsofttranslator.com/speech/translate?from={0}&to={1}&api-version=1.0".format(translate_from[:2], translate_to)
request = httpclient.HTTPRequest(uri, headers={
'Authorization': 'Bearer ' + azure_auth_client.get_access_token(),
})
return websocket.websocket_connect(request, on_message_callback=self.speech_to_translation_completed)
def speech_to_translation_completed(self, new_message):
if new_message == None:
print("Got None Message")
return
msg = json.loads(new_message)
if msg['translation'] != '':
print("Translated: " + "'" + msg['recognition'] + "' -> '" + msg['translation'] + "'")
for key, value in conversation_id_by_phone_number.iteritems():
if key != self.whoami and value != None:
if self.whoami == CALLER:
speak(call_id_by_conversation_id[value], msg['translation'], VOICE2)
else:
speak(call_id_by_conversation_id[value], msg['translation'], VOICE1)
@gen.coroutine
def on_message(self, message):
if type(message) == str:
ws = yield self.ws_future
ws.write_message(message, binary=True)
else:
message = json.loads(message)
self.whoami = message['whoami']
print("Sending wav header")
header = make_wave_header(16000)
if self.whoami == CALLER:
self.ws_future = self.translator_future(LANGUAGE1, LANGUAGE2)
else:
self.ws_future = self.translator_future(LANGUAGE2, LANGUAGE1)
ws = yield self.ws_future
ws.write_message(header, binary=True)
@gen.coroutine
def on_close(self):
print("Websocket Call Disconnected")
En el ejemplo anterior utilizamos una función llamada make_wave_header para crear la cabecera que espera el Translator Speech API. El código utilizado para crear un encabezado WAV fue copiado del archivo Python-Habla-Traduce y se reproduce a continuación.
Copie la función make_wave_header al final de su archivo main.py archivo:
def make_wave_header(frame_rate):
"""
Generate WAV header that precedes actual audio data sent to the speech translation service.
:param frame_rate: Sampling frequency (8000 for 8kHz or 16000 for 16kHz).
:return: binary string
"""
if frame_rate not in [8000, 16000]:
raise ValueError("Sampling frequency, frame_rate, should be 8000 or 16000.")
nchannels = 1
bytes_per_sample = 2
output = StringIO.StringIO()
output.write('RIFF')
output.write(struct.pack('<L', 0))
output.write('WAVE')
output.write('fmt ')
output.write(struct.pack('<L', 18))
output.write(struct.pack('<H', 0x0001))
output.write(struct.pack('<H', nchannels))
output.write(struct.pack('<L', frame_rate))
output.write(struct.pack('<L', frame_rate * nchannels * bytes_per_sample))
output.write(struct.pack('<H', nchannels * bytes_per_sample))
output.write(struct.pack('<H', bytes_per_sample * 8))
output.write(struct.pack('<H', 0))
output.write('data')
output.write(struct.pack('<L', 0))
data = output.getvalue()
output.close()
return data
Por último, la función speak utilizada anteriormente es una simple envoltura alrededor del método nexmo_client método send_speech. Como se puede ver a continuación, se imprimirá alguna información que puede ser útil para usted cuando se ejecuta el código y, a continuación, utilizar la API de Nexmo para instruir a Nexmo para hablar un determinado text con un voice_name. Copia la speak al final de tu archivo main.py archivo.
def speak(uuid, text, vn):
print("speaking to: " + uuid + " " + text)
response = nexmo_client.send_speech(uuid, text=text, voice_name=vn)
print(response) Conclusión
Si nos has seguido, ¡ya has construido tu propio pez Babel! Si no lo has hecho, puedes encontrar el código final aquí. Ejecútalo escribiendo python main.py en tu terminal. Ahora haz equipo con otro humano (o utiliza dos teléfonos) y llama a tu número Nexmo desde dos líneas. Deberíais oír el mensaje de bienvenida y después podréis hablar entre vosotros en los dos idiomas que hayáis elegido. Recapitulemos: Empezamos configurando nuestro entorno, así como nuestra aplicación Nexmo y la API de voz Microsoft Translator. A continuación, construimos nuestro Tornado WebServer que nos permitió utilizar WebSockets para gestionar las llamadas de voz y pasar el discurso de la llamada de voz a la Translator Speech API. A continuación, la API traduce y transcribe el discurso por nosotros. Al recibir el resultado, pronunciamos el mensaje en el nuevo idioma. Nuestro servicio gestiona llamadas bidireccionales gracias a nuestra lógica de enrutamiento, lo que significa que nuestro servicio, tras conectar a dos interlocutores, traducirá el habla de cualquiera de ellos antes de retransmitirla, permitiéndoles así comunicarse en los idiomas que hayan elegido. Y ya está. Nuestro pez Babel en funcionamiento. Me temo que nuestro pez Babel de bricolaje no es tan entrañable como el de la película, pero es una alternativa que funciona. Si tienes alguna pregunta, no dudes en ponerte en contacto con nosotros en @naomi_pen o búscame en naomi.codes.
¿Y ahora qué?
Si estás interesado en explorar esto más a fondo, ¿por qué no implementar una lógica que permita a los usuarios elegir el idioma al inicio de la llamada? Esta lógica también podría eliminar la necesidad de codificar nuestro número de teléfono principal. Para un proyecto divertido también se podría explorar hacer este trabajo para las llamadas de conferencia y la creación de transcripciones para cada llamada. Por último, supongo que querrás trabajar en la seguridad de tu servicio y no dejar que personas al azar llamen a tu servicio. Podrías conseguirlo permitiendo que sólo un cierto número (o varios) usen tu servicio y teniendo una lógica para iniciar una segunda etapa de la llamada desde dentro de la llamada para permitirte invitar a otros usuarios sin darles el privilegio de usar tu servicio de Babel fish. Me encantaría escuchar lo que construyes en Twitter @naomi_pen¡!
