Agregar un canal de chat personalizado a Twilio Flex

January 28, 2020
Redactado por

canal-personalizado

En este artículo, le mostraré cómo agregar un canal de chat personalizado, como Socket.IO, en Twilio Flex. Existen varias formas diferentes de integrar un canal personalizado, pero en este artículo veremos aquella que no exige el desarrollo de un plugin adicional al de la interfaz de usuario de Flex.

Requisitos previos para agregar un canal de chat a Twilio Flex

Antes de empezar, tendrá que asegurarse de que tiene algunas opciones configuradas.

Chat Socket.IO personalizado en Flex

Después de esto, estará listo para chatear, veamos el flujo de mensajes.

Agregar un canal de chat en Flex

Antes de analizar cómo se puede integrar un chat personalizado, tenemos que entender el flujo por el que pasa un mensaje antes de aparecer en la interfaz de usuario de Flex. Veamos un mensaje de chat web estándar como ejemplo.

Cuando un cliente abre el componente de la interfaz de usuario de Flex WebChat, recibe un mensaje del bot. En esta etapa suceden dos situaciones:

  • Se crea un nuevo usuario con un nombre amigable Customer.
  • Se crea un nuevo canal de chat, y el usuario anterior se agrega a ese canal.

Canal de chat en Flex

Tenga en cuenta que, en esta fase, solo hay un miembro en el canal (es decir, el trabajador del enrutador de tareas no se ha agregado todavía al canal), y no hay mensajes en el canal.

Cuando el usuario envía un mensaje en el chat, sucede lo siguiente:

  • Se agrega un nuevo mensaje al canal.
  • Se crea una nueva tarea en el espacio de trabajo del TaskRouter “Asignación de tareas de Flex”. Esta tarea tiene los siguientes atributos: {"channelSid":"CH********","name":"Customer","channelType":"web"}. Tenga en cuenta que el channelSid es el SID del canal de chat creado anteriormente.
  • Se crea una reserva para la tarea (si hay algún trabajador disponible).

Una vez que el trabajador del TaskRouter acepta la reserva, se agrega al canal de chat. En este momento, la conversación entre el cliente y el agente se genera dentro del canal de chat.

Orquestación de mensajes de chat de Flex

Es posible que se pregunte cómo sucede esto. El siguiente diagrama proporciona una vista de alto nivel del flujo.

Flujo de orquestación de mensajes de chat de Flex

Flujo de orquestación de mensajes de chat de Flex

La clave de este flujo es el flujo de Flex. Las principales propiedades de un flujo de Flex son las siguientes:

  • channelType : qué tipo de canal está utilizando este chat. Existe algo predefinido (webfacebooksmswhatsappline) o puede usar custom para su propio canal. Puede definir varios flujos de Flex para un tipo de canal, pero solo uno puede tener la propiedad enabled configurada como true
  • integrationType : con qué producto se integra el flujo para manejar los mensajes entrantes. Los valores permitidos son:
    • studio: un mensaje nuevo activará un flujo de Twilio Studio. Esto es particularmente útil cuando desea agregar IVR/bot de chat a su chat antes de transferirlo a un agente.
    • task: un mensaje nuevo activará la creación de una tarea en Twilio TaskRouter.
    • external: un mensaje nuevo activará una llamada en su propio webhook. Puede utilizarlo para integrar el flujo con su infraestructura u otros productos de Twilio. Al final de su flujo, si desea que Flex maneje el chat, necesita crear una nueva tarea en el espacio de trabajo de TaskRouter de Flex.
  • integration: este es un objeto que contiene propiedades relacionadas con la tarea específica inegrationType. Obtenga más información sobre esto más adelante.
  • chatServiceSid: el SID del servicio de chat que se utilizará al crear un nuevo canal para un nuevo chat.

La propiedad integration puede tener los siguientes valores:

  • Para integraciones de Twilio Studio:
  • integration.flowSid: el SID del flujo de Twilio Studio (FWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)
  • Para integraciones de Twilio TaskRouter:
    • integration.workspaceSid: El SID del espacio de trabajo de Twilio TaskRouter (WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)
    • integration.workflowSid: El SID del flujo de trabajo de Twilio TaskRouter (WWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX). El flujo de trabajo debe pertenecer al espacio de trabajo definido anteriormente.
    • integration.creationOnMessage: Si se configura como true, la tarea se crea la primera vez que se recibe el mensaje. De manera predeterminada, la tarea se crea cuando se agrega el canal.
  • Para integraciones externas: 
    • integration.url: la URL de su webhook

Para obtener una lista completa de las propiedades del objeto de integración, consulte la documentación.

En el diagrama de flujo anterior, puede ver que cuando se envía un nuevo mensaje de chat en el flujo de Flex, tenemos la información necesaria para crear un nuevo canal en el servicio de chat y para establecer el webhook para el flujo de Studio.

Implementación de un canal de chat

Suficiente teoría por ahora. Veamos cómo agregar un chat web de cliente a Flex.

Como se mencionó al principio de este artículo, este método no cambia el componente de WebChat en Flex. El principal compromiso es que volveremos a utilizar el servicio de chat de Flex predeterminado que viene suministrado previamente cuando se crea un proyecto nuevo de Flex. Este servicio de chat predeterminado se llama “servicios de chat de Flex” y puede encontrar su SID en esta página de la consola.

Para integrar un nuevo canal, deberá hacer lo siguiente:

  • Crear un nuevo flujo de Twilio Studio (opcional).
  • Crear un nuevo flujo de Flex que lo asocie con el flujo de Twilio Studio (ya sea el predeterminado o el que ha creado) y al “servicio de chat de Flex”.
  • Implementar un middleware que recibirá los mensajes del canal de chat y los enviará a Twilio.

El flujo se verá de la siguiente manera:

Flujo de chat personalizado

Crear un nuevo flujo de Studio (opcional)

Este paso es opcional, puede volver a utilizar el flujo predeterminado en su proyecto Flex.

  1. Navegue por el panel de control de Twilio Studio y haga clic en el icono “plus” (más) para agregar un nuevo flujo.
  2. Asigne un nombre al nuevo flujo, por ejemplo, Flujo de webchat personalizado.
  3. En la ventana de selección de plantillas, seleccione “Start from Scratch” (Empezar de cero). Observe las otras plantillas, en caso de que quiera que el webchat pase por algunos pasos adicionales antes de ser asignado a un agente de Flex.
  4. Una vez que se abra el editor de Studio Flow, busque el widget “Send To Flex” (Enviar a Flex) y suéltelo en el lienzo.
  5. Conecte el activador “Incoming message” (Mensaje entrante) al widget “Send To Flex” (Enviar a Flex).
  6. Seleccione el widget “Send To Flex” (Enviar a Flex) y elija los siguientes valores:
    1. Workflow: "Assign to Anyone"
    2. Channel: "Programmable Chat"
    3. Attributes: Paste the following: {"name": "{{trigger.message.ChannelAttributes.from}}", "channelType": "web", "channelSid": "{{trigger.message.ChannelSid}}"}
  7. Haga clic en “Save” (Guardar)
  8. Haga clic en “Publish” (Publicar) para publicar el flujo

Los principales puntos que se deben tener en cuenta en los pasos anteriores son las decisiones en torno al flujo de trabajo y al canal. Estas dos configuraciones son necesarias para conectar la tarea que se crea como resultado de la activación de este flujo de Studio con el canal de chat utilizado para intercambiar mensajes entre el agente y el cliente.

Crear un nuevo flujo de Flex

Los flujos de Flex no se pueden crear directamente en la consola. En su lugar, vamos a utilizar la CLI de Twilio.

Una vez instalada la CLI, utilice el siguiente comando para crear un nuevo flujo:

$ twilio api:flex:v1:flex-flows:create \
--friendly-name="Custom Webchat Flex Flow" \
--channel-type=custom \
--integration.channel=studio \
--chat-service-sid=<Flex Chat Service SID> \
--integration.flow-sid=<Flex Studio Flow SID> \
--contact-identity=custom \
--enabled

Dónde:

  • <Flex Chat Service SID>: este es el SID (IS****) del servicio de chat llamado “Servicios de chat de Flex” en el Panel de control del chat programable.
  • <Flex Studio Flow SID>: este es el SID (FW****) del flujo de Studio que creó en el capítulo anterior o (en caso de que haya omitido ese capítulo) el llamado “Flujo de webchat” en el Panel de control de Studio.

Si el comando se ejecuta sin errores, anote el SID del flujo que acaba de crear. Ahora diríjase a la mensajería de Flex en la consola, después debería ver un nuevo “Custom WebChat Flex Flow” (Flujo de webchat personalizado de Flex).

Middleware

Ahora que se creó el aprovisionamiento , vamos a implementar el middleware entre Flex y nuestro servicio externo (aquí, Socket.io). Necesitamos dos funciones en el middleware: createNewChannel() y sendChatMessage().

createNewChannel()

Esta función utiliza la API de Flex para crear un nuevo canal y configurar un webhook que se llama cuando se agrega un mensaje al canal. Este último es necesario para manejar de manera adecuada los mensajes de chat que llegan desde Flex. Para lograr esto, esta función debe:

  • Utilizar la API de canales de Flex para crear un nuevo canal de chat. Esto se implementa mediante el uso de JavaScript client.flexApi.channel.create() en las líneas del 2 al 9 del código siguiente.
  • Una vez creado el canal, utilicec la API del canal de chat para configurar un nuevo webhook para el evento onMessageSent del canal de chat. Esto se implementa mediante el uso del JavaScript client.chat.services().channels().webhooks.create() en las líneas del 12 al 20 a continuación.

Este es un ejemplo de cómo implementar esta función mediante el uso de JavaScript:

 function createNewChannel(flexFlowSid, flexChatService, chatUserName) {
  return client.flexApi.channel
    .create({
      flexFlowSid: flexFlowSid,
      identity: chatUserName,
      chatUserFriendlyName: chatUserName,
      chatFriendlyName: 'Flex Custom Chat',
      target: chatUserName
    })
    .then(channel => {
      console.log(`Created new channel ${channel.sid}`);
      return client.chat
        .services(flexChatService)
        .channels(channel.sid)
        .webhooks.create({
          type: 'webhook',
          'configuration.method': 'POST',
          'configuration.url': `${webhookUrl}/new-message?channel=${channel.sid}`,
          'configuration.filters': ['onMessageSent']
        });
    })
    .then(webhook => webhook.channelSid)
    .catch(error => {console.log(error)})
}

Al crear un nuevo canal, asegúrese de configurar la propiedad target correctamente. Esta representa la identidad del contacto de destino (p. ej., el número de teléfono de destino para un SMS). Si ya existe un canal de chat con el mismo valor target, Flex utilizará el canal existente en lugar de crear uno nuevo. Esto también significa que el flujo de Studio no se activa y no se crea una nueva tarea.

El valor target también se utiliza en la interfaz de usuario de Flex como nombre de la nueva tarea. Este es el aspecto de una nueva tarea para un canal con un valor target establecido como “custom-chat-user” (usuario de chat personalizado).

Nombre de la tarea en la interfaz de usuario de Flex

sendChatMessage()

Esta función envía el mensaje real al chat de Flex. Para que esta función active la creación de una nueva tarea, debemos asegurarnos de que se llame al webhook cuando se agrega un mensaje nuevo.

Como se explica en esta sección de la documentación de Flex, “sólo las acciones de los clientes basados en el SDK (como los teléfonos móviles o los navegadores) provocarán los webhook sin necesidad de realizar otras acciones por su parte”. Así que, en este caso, tenemos que construir la API REST de forma manual, asegurándonos de que la cabecera HTTPX-Twilio-Webhook-Enabled esté establecido como true en la solicitud HTTP:

const fetch = require('node-fetch');
var base64 = require('base-64');
...

function sendChatMessage(serviceSid, channelSid, body) {
  const params = new URLSearchParams();
  params.append('Body', body);
  params.append('From', chatUserName);
  return fetch(
    `https://chat.twilio.com/v2/Services/${serviceSid}/Channels/${channelSid}/Messages`,
    {
      method: 'post',
      body: params,
      headers: {
        'X-Twilio-Webhook-Enabled': 'true',
        Authorization: `Basic ${base64.encode(`${ process.env.TWILIO_ACCOUNT_SID}:${process.env.TWILIO_AUTH_TOKEN}`)}`
      }
    }
  )
}

Probar la solución

Para probar la solución, vamos a desarrollar un webchat mediante el uso del chat de ejemplo de socket.io (consulte aquí una guía paso a paso sobre cómo crear este chat). Para hacer la integración con Flex, necesitamos agregar lo siguiente:

  • Un nuevo punto final POST (/new-message) que manejará el mensaje proveniente de Flex. Esta es la URL del webhook que configuramos en la función createNewChannel() definida anteriormente:
app.post('/new-message', function(request, response) {
  console.log('New message from Flex');
  if (request.body.Source === 'SDK' ) {
    io.emit('chat message', request.body.Body);
  }
  response.sendStatus(200);
});
  • Una función para enviar un mensaje a Flex una vez que se envíe un nuevo mensaje de chat desde el navegador. Para decidir si se necesita un nuevo canal (es decir, si es un nuevo chat), utilizaremos la variable global . Esto funciona bien para esta demostración específica, pero es posible que quiera implementar una lógica diferente para eso en una instancia de producción.
...
async function sendMessageToFlex(msg) {
  if (!flexChannel) {
    flexChannel = await createNewChannel(process.env.FLEX_FLOW_SID, process.env.FLEX_CHAT_SERVICE, targetName, chatUserName);
  }
  sendChatMessage(process.env.FLEX_CHAT_SERVICE, flexChannel, msg);
}
...
io.on('connection', function(socket) {
  console.log('User connected');
  socket.on('chat message', function(msg) {
    sendMessageToFlex(msg);
    io.emit('chat message', msg);
  });
});

Finalizar un chat

Para asegurarse de que el usuario recibe una notificación cuando un agente termina un chat, es posible que quiera agregar un webhook para el evento flexChannel. Puede hacerlo agregando un nuevo webhook en la función createNewChannel():

function createNewChannel(flexFlowSid, flexChatService, chatUserName) {
  return client.flexApi.channel
    .create({
     ...
    })
    .then(channel => {
      console.log(`Created new channel ${channel.sid}`);
      return client.chat
        .services(flexChatService)
        .channels(channel.sid)
        .webhooks.create(...)
        .then(() => client.chat
        .services(flexChatService)
        .channels(channel.sid)
        .webhooks.create({
          type: 'webhook',
          'configuration.method': 'POST',
          'configuration.url': '`${process.env.WEBHOOK_BASE_URL}/channel-update',
          'configuration.filters': ['onChannelUpdated']
        }))
    })
    .then(webhook => webhook.channelSid)
    .catch(error => {
      console.log(error);
    });
}

Cuando se llama a este webhook, el middleware debería comprobar el valor Attributes en la solicitud POST. Este es un objeto JSON que contiene una clave status. Cuando el agente termina el chat, el status se establece como “INACTIVE” (Inactivo). Debe controlar este cambio de estado para asegurarse de que cierra el chat correctamente y realiza las operaciones de limpieza necesarias en el middleware y en la actividad en segundo plano.

Próximos pasos con el nuevo canal de chat de Flex

El código de trabajo completo para esta demostración está disponible en este repositorio, con instrucciones sobre cómo configurarlo, ejecutarlo y utilizarlo.

Todavía existen varias características que es posible que quiera explorar a continuación, como el indicador de escritura en el chat, la presencia del usuario y el componente de interfaz de usuario de Flex para el webchat. Este tutorial y el código del repositorio deberían proporcionarle un punto de partida para construir e integrar el canal personalizado en Flex.

Giuseppe Verni es un ingeniero de soluciones principales en Twilio. Actualmente, ayuda a las empresas de EMEA a diseñar importantes soluciones de interacción con el cliente con Twilio. Puede comunicarse con él en gverni@twilio.com, o puede colaborar con él en GitHub en https://github.com/vernig.

Este artículo ha sido traducido del original "Add a Custom Chat Channel to Twilio Flex". Mientras continuamos con los procesos de traducción, nos encantaría recibir sus comentarios en help@twilio.com - Buenas contribuciones pueden generar regalos de Twilio.