
Compartir:
Michael es un ingeniero de software políglota, empeñado en reducir la complejidad de los sistemas y hacerlos más predecibles. Trabaja con una gran variedad de lenguajes y herramientas, y comparte sus conocimientos técnicos con audiencias de todo el mundo en grupos de usuarios y conferencias. En el día a día, Michael es un antiguo defensor de los desarrolladores en Vonage, donde pasaba su tiempo aprendiendo, enseñando y escribiendo sobre todo tipo de tecnología.
Susurro de llamada con controles de audio selectivos
Tiempo de lectura: 5 minutos
Nexmo ha sido una opción popular para las soluciones de centros de contacto durante mucho tiempo, pero con el lanzamiento de hoy de los controles de audio selectivos lo estamos llevando al siguiente nivel. Los controles de audio selectivos resuelven un caso de uso común -un supervisor que escucha una llamada pero al que solo oye su empleado y no el cliente- de forma intuitiva.
A cada participante en una conversación en la plataforma Nexmo se le asigna un ID. Utilizando estos IDs y la acción de conversación puedes crear una aplicación que controle qué participantes puede escuchar alguien nuevo en la conversación. En este post, vamos a construir el supervisor escuchando a un empleado caso de uso.
El código de esta aplicación está disponible en Github
Puesta en marcha de una aplicación
Para construir este flujo de llamadas necesitamos escribir una pequeña aplicación node.js. Creemos un nuevo proyecto e instalemos express para servir nuestra aplicación answer_url.
Una vez hecho esto, tendrá que crear una instancia de expressregistrar un answer_url y escuchar en un puerto. Para ello, crea index.js con el siguiente contenido:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({"extended": true}));
app.use(bodyParser.json());
app.get('/webhooks/answer', (req, res) => {
return res.json([]);
});
app.listen(3000, () => {
console.log('Listening');
});
Creación de la URL de respuesta
Ahora que tenemos una aplicación de arranque, es el momento de empezar a añadir nuestra lógica de negocio. Hay tres participantes en nuestra llamada:
Alice, la supervisora del centro de contacto
Bob, el agente del centro de contacto
Charlie, el cliente
En el mundo real utilizaríamos una base de datos para almacenar toda la información necesaria, pero en este artículo vamos a utilizar un objeto en memoria. La clave es el número de teléfono del participante, que se asigna a un objeto que contiene información sobre él. Por ahora, es sólo su papel. Añade el siguiente código después de app.use(bodyParser.json());asegurándote de actualizar el código de abajo, sustituyendo las claves por tus números de teléfono reales.
const conversationName = 'selective-audio-demo';
const participants = {
"<supervisor_phone_number>": {
"role": "supervisor",
},
"<agent_phone_number>": {
"role": "agent",
},
"<customer_phone_number>": {
"role": "customer",
}
};Una vez hecho esto, debe actualizar su /webhooks/answer URL para que devuelva una NCCO válida. Como necesitaremos una NCCO diferente para cada tipo de llamante, vamos a añadir una sentencia switch y llamemos a un método que devuelva una OCNC para cada tipo de llamante:
app.get('/webhooks/answer', (req, res) => {
const caller = participants[req.query.from];
if (!caller) {
return res.status(400).json("Unknown caller type: " + req.query.from);
}
// Generate an NCCO based on role
let ncco;
switch (caller.role) {
case 'supervisor':
ncco = createSupervisorNcco(caller);
break;
case 'agent':
ncco = createAgentNcco(caller);
break;
case 'customer':
ncco = createCustomerNcco(caller);
break;
default:
return res.status(400).json("Unknown caller type: " + caller.type);
}
return res.json(ncco);
});
Este código llama a createSupervisorNcco, createAgentNcco o createCustomerNcco dependiendo del tipo de llamada proporcionada. Tenemos que seguir adelante y crear esas funciones y devolver NCCO.
La OCN del cliente
Empecemos por la OCN del cliente. Cuando el cliente se incorpora, queremos que pueda oír al agente pero no al supervisor, y que pueda hablar tanto con el agente como con el supervisor. Además, cuando el cliente llama queremos que quede en espera hasta que un agente se incorpore a la conversación.
Añada lo siguiente al final de su fichero para generar la OCN del cliente. Usamos la conversation acción, damos a la conversación un name, especificamos que la llamada no debe iniciarse automáticamente y que el usuario debe ser puesto en espera. Todos estos son parámetros existentes para la Voice API de Nexmo.
Lo que hace interesante a esta OCN, son los canSpeak y canHear . Estos dos parámetros aceptan una lista de UUID que identifican a otros participantes y controlan con quién puede hablar y escuchar la persona que se conecta a la llamada. Si no se proporciona el UUID de un participante, el usuario que se conecte no podrá hablar ni escuchar a ese participante.
En este ejemplo, nuestro cliente puede hablar con el agente y con su supervisor, pero sólo puede escuchar el audio del agente. Añade lo siguiente al final de tu archivo:
function createCustomerNcco(caller){
// Customer can hear agent, and speak to everyone
return [
{
"action": "conversation",
"name": conversationName,
"startOnEnter": false,
"musicOnHoldUrl": ["https://nexmo-community.github.io/ncco-examples/assets/voice_api_audio_streaming.mp3"],
"canSpeak": findParticipants('agent').concat(findParticipants('supervisor')),
"canHear": findParticipants('agent')
}
]
} El Agente NCCO
El siguiente paso es la OCN del agente. Los agentes deben poder hablar con todos los participantes y ser escuchados por todos ellos. Son los propietarios de esta multiconferencia, por lo que establecemos startOnEnter en true para indicar que la conferencia se activa cuando se unen. Además, establecemos record en true para que la llamada se grabe.
Como el agente puede hablar y oír a todo el mundo, encontramos a todos los clientes y a todos los supervisores y suministramos sus UUID a la conversation acción.
En este caso podríamos omitir
canSpeakycanHearde la OCNC, ya que los valores por defecto permiten el audio entre todos los participantes. En aras de un control total sobre los participantes, he optado por suministrarlos de todos modos
function createAgentNcco(caller){
// Agent can hear everyone, and speak to everyone
return [
{
"action": "conversation",
"name": conversationName,
"startOnEnter": true,
"record": true,
"canSpeak": findParticipants('customer').concat(findParticipants('supervisor')),
"canHear": findParticipants('customer').concat(findParticipants('supervisor'))
}
]
} El Supervisor NCCO
Por último, tenemos el supervisor NCCO. El supervisor puede oír a todo el mundo, pero sólo habla con el agente (es lo contrario del cliente). Como antes, no son dueños de la llamada por lo que startOnEnter se establece en false.
Proporcionamos canSpeak y canHear con una lista de UUIDs como nuestras NCCOs anteriores, y esto asegura que el supervisor sólo puede hablar con el agente, pero oirá tanto al agente como al cliente.
function createSupervisorNcco(caller){
// Supervisor can hear everyone, but only speak to agents
return [
{
"action": "conversation",
"name": conversationName,
"startOnEnter": false,
"musicOnHoldUrl": ["https://nexmo-community.github.io/ncco-examples/assets/voice_api_audio_streaming.mp3"],
"canSpeak": findParticipants('agent'),
"canHear": findParticipants('customer').concat(findParticipants('agent'))
}
]
} Hacer que todo funcione
¡Ya casi lo tenemos! Sólo nos quedan dos cosas por hacer para que nuestra aplicación funcione. La primera es implementar nuestro método findParticipants método. Añade la siguiente función al final de tu archivo:
function findParticipants(callerType) {
let legs = [];
Object.entries(participants).forEach(([number, participant]) => {
if (participant.role == callerType && participant.legId) {
legs.push(participant.legId);
}
});
return legs;
}
Busca en todos los participantes el rol proporcionado. Si el rol coincide, el UUID de la pierna se introduce en un array y se devuelve.
La segunda cosa que hay que hacer es asegurarse de que almacenamos el UUID de la pata de la persona que llama cuando se hace una petición a /webhooks/answer. Actualiza tu código para almacenar el UUID de la pierna después de que comprobemos si el llamante actual puede ser encontrado:
if (!caller) {
return res.status(400).json("Unknown caller type: " + req.query.from);
}
// Add their leg ID to the caller
caller.legId = req.query.uuid;En este punto, su aplicación debería funcionar. Asegúrese de que su answer_url sea accesible (quizás usando ngrok si está en tu máquina local) y llama a un número que apunte a la aplicación que acabas de crear. Si usted necesita para crear una aplicación Nexmo y alquilar un número, echa un vistazo a nuestro Conceptos de aplicación en nuestro portal para desarrolladores.
Compartir:
Michael es un ingeniero de software políglota, empeñado en reducir la complejidad de los sistemas y hacerlos más predecibles. Trabaja con una gran variedad de lenguajes y herramientas, y comparte sus conocimientos técnicos con audiencias de todo el mundo en grupos de usuarios y conferencias. En el día a día, Michael es un antiguo defensor de los desarrolladores en Vonage, donde pasaba su tiempo aprendiendo, enseñando y escribiendo sobre todo tipo de tecnología.