Compatibilidad con varios idiomas con Google Traductor

Con las configuraciones regionales de Business Messages y la traducción inteligente y automatizada de Google Traductor, puedes ampliar el alcance de tu agente mediante la comunicación con los usuarios en el idioma que prefieran. En este instructivo, se explica la integración de la prueba de concepto de Google Traductor con un webhook de Business Messages.

Requisitos

Para comenzar, debes preparar lo siguiente:

Obtén el código

En este instructivo, se explica el código de webhook de muestra que se integra en Google Traductor. Para obtener el código, clona el repositorio desde GitHub:

git clone https://github.com/google-business-communications/bm-nodejs-translation-tutorial

Navega al directorio clonado y coloca la clave de tu cuenta de servicio en el directorio de recursos:

cp credentials.json bm-nodejs-translation-sample/resources/bm-agent-service-account-credentials.json

SUGERENCIA: Si necesitas ayuda para configurar o descargar la clave de servicio, consulta la guía de Google Cloud para administrar cuentas de servicio.

Una vez hecho esto, puedes implementar el código:

gcloud app deploy

Con tu dispositivo móvil, envía algunos mensajes al agente. Intenta enviar tus mensajes en diferentes idiomas y observa lo que sucede.

Configura la API de Translate

El código de muestra viene con el paquete de Node para la API de Translate ya instalada. Si te interesa saber cómo instalar el paquete Node o cómo instalar la API de Translate en un lenguaje de programación diferente, consulta los documentos de la API de Cloud Translate.

Para usar la API de Translate, debes importar la biblioteca y crear un cliente de la API de Translate. Abre el archivo routes/index.js. Las líneas relevantes son las siguientes:

// Import the Translate API library.
const { Translate } = require("@google-cloud/translate").v2;
// Create a new Translate API client.
const translate = new Translate();

A partir de ahora, puedes acceder a los métodos de la API de Traductor en el objeto de traducción.

Observa las variables creadas cerca de la parte superior del archivo:

const SERVER_LANGUAGE = "en";
let currentLanguage = SERVER_LANGUAGE;

El código de muestra almacena el idioma del servidor como una constante porque está relativamente reparado. Sin embargo, el idioma actual de la conversación puede cambiar, por lo que se hace un seguimiento en la variable currentLanguage.

Cómo detectar el idioma entrante

El código de muestra detecta si el idioma entrante ha cambiado y, de ser así, le solicita al usuario que elija el idioma que desea utilizar en la conversación. Para probar esta función en tu dispositivo móvil, escribe un mensaje al agente en un idioma que no sea inglés. Si no conoces ningún otro idioma, intenta escribir "Hola" (eso es un nombre en español para "Hola").

El agente responde con un mensaje en el que se le pregunta si el usuario desea cambiar de idioma. La solicitud incluye respuestas sugeridas en las que el usuario puede hacer clic para cambiar a ese idioma.

Primero, analicemos la función de detección de idioma.

/**
 * Detects input text language.
 *
 * @param {string} text The text received from the consumer.
 * @param {Context} context The user message request context.
 * @return A Promise with the detected language code.
 */
async function detectLanguage(text, context) {
  return new Promise(function (resolve, reject) {
    translate
      .detect(text)
      .then((result) => {
        if (result && result.length > 0) {
          if (result[0].confidence > CONFIDENCE_THRESHOLD) {
            resolve(result[0].language);
          }
          resolve(bcp47.parse(context.resolvedLocale).language);
        } else {
          reject("No language detected");
        }
      })
      .catch((err) => {
        console.error("ERROR:", err);
        reject(err);
      });
  });
}

Este método usa el método de detección en el cliente de traducción. Debido a que la API de Traductor puede detectar varios idiomas con diferentes niveles de confianza (y también porque admite varias entradas), este método muestra un arreglo de resultados. La muestra toma el primer resultado, que es el que tiene la mayor confianza.

Usando configuración regional resuelta

A veces, la API de Translate no puede determinar el idioma del mensaje con gran confianza. Por ejemplo, si tu gato se ejecuta por todo el teclado e ingresa una string sin sentido, la API de Translate aún intenta detectar el idioma, pero es probable que el idioma detectado sea incorrecto. (Después de todo, Google Traductor no admite idiomas felinos aún) La API de Translate indica esto mediante la configuración de un valor de confianza bajo en el resultado de translate.detect.

En este caso, el código de muestra recurre al idioma en la configuración regional de Business Messages resueltos, que es la mejor estimación de la API de Business Messages en el idioma según el contexto del mensaje. Debido a que la configuración regional resuelta está en formato BCP-47, puedes usar el paquete de Node.js correspondiente para analizar el código de idioma de la configuración regional.

Para probar este comportamiento, escribe una string larga de algarabía en el agente. En la mayoría de los casos, no deberías ver un aviso para cambiar el idioma (a menos que la configuración regional resuelta sea diferente del idioma actual). El agente solo dice que no comprende tu solicitud.

Solicitud para cambiar el idioma

Después de detectar que el idioma cambió, el agente envía un mensaje para cambiar el idioma.

if (detectedLanguage != currentLanguage) {
        translateText(
          "Which language would you like to use?",
          SERVER_LANGUAGE,
          currentLanguage
        ).then((normalizedTranslationNotice) => {
          sendResponse(
            normalizedTranslationNotice,
            conversationId,
            [
              ...new Set([detectedLanguage, currentLanguage, SERVER_LANGUAGE]),
            ].map((x) => createSuggestedReply(x))
          );
        });
      }

El código crea un mensaje, lo traduce al idioma actual (más información en la sección de traducción de mensajes salientes) y luego envía una respuesta con respuestas sugeridas. El usuario podría querer hablar en cualquiera de los siguientes idiomas:

  • El idioma entrante detectado.
  • El idioma de la conversación actual.
  • El lenguaje integrado del servidor

Dado que puede haber superposiciones en estos tres idiomas (por ejemplo, si el idioma actual ya es el del servidor), el servidor usa un objeto establecido para quitar los duplicados. Luego, crea una respuesta sugerida para cada idioma:

/**
 * Create a suggested reply for a language code.
 * @param {string} languageCode A ISO 6391 language code.
 * @return {Suggestion} The suggestion object for switching to the language.
 */
function createSuggestedReply(languageCode) {
  return {
    reply: {
      text: ISO6391.getNativeName(languageCode),
      postbackData: SWITCH_LANGUAGE_POSTBACK + languageCode,
    },
  };
}

En la respuesta sugerida, se muestra el nombre del idioma en su propio idioma. Por ejemplo, español aparece como &Español; " Para obtener información sobre un idioma a partir de su código de idioma de dos dígitos, puedes usar la biblioteca ISO-639-1 para Node.js.

Observa los datos de notificación, que se envían al servidor cuando el usuario hace clic en esta sugerencia. Los datos de notificación le indican al servidor cómo responder y proporcionan contexto sobre la sugerencia.

El método sendResponse adjunta estos objetos de sugerencias a la respuesta:

let messageObject = {
    …
    suggestions: suggestedReplies,
  };

Cambiando el idioma de la conversación

Ahora regresa a tu dispositivo móvil e intenta hacer clic en una nueva opción de idioma en el mensaje anterior. Por ejemplo, si escribiste "Hola", intenta hacer clic en "Español" en las respuestas sugeridas.

El agente responde en el idioma nuevo. Analizaremos cómo traducir respuestas salientes en un paso posterior. Por ahora, observa el código que recibe y procesa la respuesta sugerida en la que hiciste clic.

if (requestBody.suggestionResponse !== undefined) {
    let postbackData = requestBody.suggestionResponse.postbackData;
    if (postbackData.startsWith(SWITCH_LANGUAGE_POSTBACK)) {
      let languageCode = postbackData.substr(SWITCH_LANGUAGE_POSTBACK.length);
      currentLanguage = languageCode;
      translateText(
        "The language was set to " +
          ISO6391.getName(languageCode) +
          ". Please repeat your request.",
        SERVER_LANGUAGE,
        languageCode
      ).then((translationNotice) => {
        sendResponse(translationNotice, conversationId, []);
      });
    }
  }

Si la solicitud contiene una respuesta a una sugerencia, el servidor usa los datos de notificación para determinar qué hacer. En este caso simple, el servidor solo admite un tipo de datos de notificación, el SWITCH_LANGUAGE_POSTBACK, que significa que la conversación debe cambiar al idioma en el siguiente código de idioma. Después de analizar este código de idioma, el servidor envía un mensaje para notificar al usuario que el idioma ha cambiado.

Traducción de mensajes entrantes

Con el idioma cambiado, puedes enviar una solicitud al agente en ese idioma en tu dispositivo móvil. Intenta enviar la palabra "&help" en el nuevo idioma. Si cambiaste el idioma a español, escribe "ayuda" y envía el mensaje.

El servidor comprende tu solicitud de ayuda y responde con el menú de opciones. Prueba cualquiera de estos para ver una respuesta de muestra codificada.

El código de muestra usa el método translateText para traducir mensajes entrantes y salientes. Mírala ahora:

/**
 * Translates text to a given target language. No translation if source and
 * target language match.
 *
 * @param {string} text the text to translate
 * @param {string} sourceLanguage The language of the source text.
 * @param {string} targetLanguage The target language.
 * @return A Promise with the translated text.
 */
async function translateText(text, sourceLanguage, targetLanguage) {
  if (sourceLanguage === targetLanguage) {
    return new Promise(function (resolve, reject) {
      resolve(text);
    });
  }
  return new Promise(function (resolve, reject) {
    translate
      .translate(text, targetLanguage)
      .then((result) => {
        if (result && result.length > 0) {
          resolve(result[0]);
        } else {
          reject("Could not translate message");
        }
      })
      .catch((err) => {
        console.error("ERROR:", err);
        reject(err);
      });
  });
}

Si el idioma de origen es el mismo que el de destino, no hay nada que hacer. De lo contrario, el servidor llamará al método de traducción en el cliente de la API de Traductor. Al igual que el método de detección, el método de traducción puede tomar varias entradas. Dado que el servidor solo proporciona una entrada, toma el primer resultado de la API de Translate.

Consulta la sección del método de devolución de llamada que responde a los mensajes entrantes en el idioma actual:

translateText(incomingMessage, currentLanguage, SERVER_LANGUAGE).then(
          (normalizedMessage) => {
            let serverResponse = chooseResponseMessage(normalizedMessage);
            …
          }
        );

El servidor usa el resultado de translateText para elegir un mensaje de respuesta. En la siguiente sección, se profundiza en el proceso de elegir el mensaje de respuesta y traducirlo.

Traducción de mensajes salientes

Después de que el servidor traduce tu mensaje entrante a su inglés nativo, tiene que elegir, traducir y enviar una respuesta adecuada a la solicitud del usuario. El código de muestra utiliza un esquema muy simple que asigna palabras clave a las respuestas. Consulta el método chooseResponseMessage.

/**
 * Select a topically appropriate response based on the message
 * content that the user sent to the agent.
 *
 * @param {string} incomingMessage The content of the message that the user typed in.
 * @param {string} conversationId The unique id for this user and agent.
 * @return {string} A response message.
 */
function chooseResponseMessage(incomingMessage) {
  let responseMapping = {
    balance: "Your current balance is $500.",
    deposit: "Please enter your deposit amount.",
    transfer:
      "Please enter the account number where you wish to transfer the funds.",
    withdraw: "Please enter the amount you wish to withdraw.",
    help: "Please choose what you'd like to do: balance, deposit, transfer, or withdraw.",
  };

  for (const [key, value] of Object.entries(responseMapping)) {
    if (incomingMessage.toLowerCase().includes(key)) {
      return value;
    }
  }

  return "I didn't understand your request. Please try again.";
}

Este esquema solo admite inglés en el servidor, lo que significa que el servidor debe traducir todos los mensajes entrantes y salientes. Un sistema más sofisticado puede admitir varios idiomas y responder de forma nativa a las solicitudes en otros idiomas. Por ejemplo, si tu agente admite español, es posible que ya tenga una clave para ayuda en el mapa de respuesta. Los sistemas más sofisticados también pueden depender de otras metodologías para elegir una respuesta adecuada, como el AA o los algoritmos de puntuación. Una forma de crear respuestas más inteligentes con Business Messages es integrarlas en Dialogflow.

Ahora, observe el código que envía el mensaje seleccionado al usuario.

let serverResponse = chooseResponseMessage(normalizedMessage);
            translateText(
              serverResponse,
              SERVER_LANGUAGE,
              currentLanguage
            ).then((normalizedResponse) => {
              sendResponse(normalizedResponse, conversationId, []);
            });

El código de muestra reutiliza el método translateText para traducir la respuesta elegida al lenguaje de conversación actual. Luego, el método sendResponse se encarga de crear el nuevo objeto Message y enviarlo al usuario.

Resumen

En este instructivo, aprendiste a crear una integración simple con la API de Cloud Translate y a usar las funciones regionales de Business Messages para llegar a más usuarios. Si lo deseas, puedes usar el código de muestra de este instructivo como punto de partida para tu propia integración o puedes probar algo nuevo. A continuación, le proponemos algunas ideas:

  • Envía mensajes bilingües que contengan contenido de mensaje original y contenido traducido automáticamente.
  • Presentar al usuario un menú completo de idiomas compatibles cuando comience una conversación
  • Usa funciones avanzadas de la API de Translate, como los glosarios para traducir de forma confiable palabras específicas de tu empresa.

Si integras las API de Translate, puedes aprovechar la traducción automática de alta calidad para comunicarte con más usuarios en su lenguaje más cómodo. Tu agente puede tener conversaciones más productivas y eficientes, lo que aumenta la satisfacción del cliente y la finalización de las tareas.