Internacionalización y Localización de Respuestas de Componentes Personalizados

Si tiene componentes personalizados que devuelven contenido en conversaciones, también deseará asegurarse de que devuelvan ese contenido en el idioma de destino del usuario.

Hay varias formas de lograr esto:
  • Cree entradas de grupos de recursos en la aptitud y haga referencia a ellas directamente desde el componente personalizado. Este enfoque permite manejar traducciones de mensajes de componentes personalizados en el mismo lugar que para otros mensajes de la aptitud.
  • Utilice un componente del sistema y entradas del grupo de recursos para ensamblar las cadenas traducibles que incorporan la salida de datos del componente personalizado. Este enfoque permite manejar traducciones de mensajes de componentes personalizados en el mismo lugar que para otros mensajes de la aptitud, al tiempo que fomenta un acoplamiento más flexible entre el componente personalizado y esa aptitud concreta.
  • Si desea utilizar el servicio de traducción de la aptitud para traducir las respuestas del componente, defina la propiedad translate del componente personalizado en true.
  • Si el componente recupera y devuelve datos de backend que se deben incorporar en un mensaje y desea utilizar el servicio de traducción de la aptitud para traducir las respuestas del componente, almacene los datos devueltos en una variable del flujo de diálogo. A continuación, puede hacer referencia a esta variable en un componente del sistema.

Grupos de recursos de referencia desde el componente personalizado

Del mismo modo que puede utilizar grupos de recursos para mensajes en componentes incorporados, intenciones de respuesta, etc., también puede utilizar grupos de recursos para sus componentes personalizados. Para ello, debe hacer lo siguiente:

  1. Defina entradas de grupo de recursos en la aptitud para el mensaje. Consulte Create Resource Bundle Keys.
  2. Mediante el método context.translate() del SDK del nodo de bots, haga referencia a las claves del grupo de recursos desde el código de componente personalizado.

    context.translate() toma un nombre de clave de grupo de recursos especificado (y cualquier parámetro especificado en la entrada del grupo de recursos) y genera la plantilla FreeMarker adecuada necesaria para cargar la cadena de idioma del grupo de recursos con nombre cuando la conversación se devuelve al usuario mediante el método context.reply().

  3. Utilice el método de ayuda context.reply para imprimir la respuesta traducida. Por ejemplo:
    context.reply(translate('date.message', dateToday, dayOfWeek ));
  4. Documente todas las claves de grupo de recursos a las que hace referencia el componente personalizado, así como las cadenas por defecto esperadas. (Dado que el componente personalizado hace referencia directamente a la clave del grupo de recursos dentro de la aptitud, debe haber un alto grado de coordinación entre el desarrollador del componente personalizado y los que crean la aptitud para garantizar que las claves a las que se hace referencia sean válidas dentro de la aptitud).

En este ejemplo, date.message es una clave de grupo de recursos, dateToday y dayOfWeek son variables, y se devuelve una expresión FreeMarker como la siguiente:

${rb('date.message', 'Monday', 'July 12, 2021')}

Nota

El método context.translate() solo admite valores de grupos de recursos que no tienen parámetros o que utilizan parámetros posicionales (numerados). Por ejemplo, en el caso de la clave date.message de ejemplo, su valor puede ser similar a “Today is {0}, {1}”. Los parámetros con nombre y los formatos de mensajes complejos no están soportados.

Uso de un componente del sistema para hacer referencia a un grupo de recursos

Puede utilizar un componente del sistema para ensamblar mensajes mediante las entradas y los datos del grupo de recursos que se han devuelto de un componente personalizado. Las cadenas de mensajes base se definen en las entradas del grupo de recursos. Las entradas del paquete pueden incluir parámetros para los datos (como números y fechas) que se generan desde el componente personalizado. Dado que las cadenas de mensajes base se definen en el flujo de diálogo, este enfoque garantiza que los componentes personalizados no dependan de un código de implantación específico y sigan siendo reutilizables.

Estos son los pasos generales:

  1. Para el componente personalizado, incluya un parámetro de entrada necesario para el nombre de la variable de contexto en la que almacenar los datos devueltos.
  2. Puesto que el desarrollador de componentes personalizados y el desarrollador de flujos de diálogo pueden no ser la misma persona o incluso del mismo equipo, documente cuidadosamente los datos que devuelve el componente personalizado en esa variable y ponga la información a disposición de los consumidores de componentes personalizados para que comprendan cómo presentar los datos devueltos al usuario en un mensaje.
  3. En el flujo de diálogo, cree una variable para almacenar los datos devueltos del componente personalizado y transfiera su nombre al parámetro de entrada necesario.
  4. Defina entradas de grupo de recursos en la aptitud para el mensaje. Consulte Create Resource Bundle Keys.
  5. En el flujo de diálogo, haga referencia a la entrada del grupo de recursos y rellene los parámetros necesarios.

El siguiente ejemplo de una aptitud desarrollada en el modo de diálogo YAML hace referencia a un componente personalizado en el estado initializeReceipt y transfiere el nombre de la variable (receipt) que contiene la respuesta del componente, y purchaseId como parámetros de entrada. A continuación, el estado printProduct incorpora el valor receipt como parámetro en una referencia a la entrada del grupo de recursos denominada receiptMessage.

  initializeReceipt:
    component: "sample.receipt.dataresponse"
    properties:
      dataVariable: "receipt"
      purchaseId: "${purchaseId.value}"
 ...
  printProduct:
    component: "System.CommonResponse"
    properties:
      keepTurn: true
      metadata:
        responseItems:        
        - type: "text" 
          text: "${rb('receiptMessage','${receipt.value}')}"

El código personalizado para acceder a estos parámetros de entrada puede tener un aspecto similar al siguiente:

module.exports = {
  metadata: () => ({
    name: 'myComponent',   
    properties: {
       dataVariable: { required: true, type: 'string' },    
       purchaseId: { required: true, type: 'string' },
    },
...
    // Retrieve the value of the 'dataVariable' component property.
    const { dataVariable } = context.properties();
    if (!dataVariable) {
      context.transition();
      done(new Error('The state is missing the dataVariable property.'));
    }
...
    // Retrieve the value of the 'purchaseId' component property.
    const { purchaseId } = context.properties();
    if (!purchaseId) {
      context.transition();
      done(new Error('The state is missing the purchaseId property.'));
    }
...
    context.setVariable(dataVariable, data);      
    context.transition();
    done();
  }
}

Enviar respuestas directamente al servicio de traducción

Si no tiene una forma de saber cuál será el texto de respuesta del componente (por ejemplo, si se consulta desde un backend remoto), puede utilizar el servicio de traducción de la aptitud para traducir las respuestas. Para ello:

  1. Asegúrese de que el componente está configurado para que su salida se envíe al servicio de traducción definiendo la propiedad translate en el componente y definiéndola en true.
  2. En el componente personalizado, utilice el método helper context.reply para devolver la respuesta.

Este enfoque solo funciona con aptitudes que se configuran en el modo de idioma del servicio de traducción.

Uso de un componente del sistema para transferir el mensaje al servicio de traducción

Los componentes personalizados que consultan servicios de backend pueden devolver datos en un formato complejo, como un objeto o una matriz de objetos. Si utiliza un servicio de traducción, estos objetos de datos no se pueden enviar al servicio de traducción tal cual. En su lugar, debe formar un mensaje que haga referencia a los atributos necesarios del objeto de datos de forma individual.

  1. Para el componente personalizado, incluya un parámetro de entrada necesario para el nombre de la variable de flujo de diálogo en la que almacenar los datos devueltos.
  2. Puesto que el desarrollador de componentes personalizados y el desarrollador de flujos de diálogo pueden no ser la misma persona o incluso del mismo equipo, documente cuidadosamente los datos que devuelve el componente personalizado en esa variable y ponga la información a disposición de los consumidores de componentes personalizados para que comprendan cómo presentar los datos devueltos al usuario en un mensaje.
  3. En el flujo de diálogo, cree una variable para almacenar los datos devueltos del componente personalizado y transfiera su nombre al parámetro de entrada necesario.
  4. Mediante la información de la variable, ensamble la respuesta en un componente del sistema, como Respuesta común.
  5. Asegúrese de que la aptitud está configurada para la traducción automática.
    • Para las aptitudes desarrolladas en el modo de cuadro de diálogo visual, defina la propiedad Traducir mensaje de respuesta de bot en la página Configuración de la aptitud en true.
    • Para las aptitudes desarrolladas en el modo de diálogo YAML, puede manejar esto globalmente en la aptitud definiendo la variable de contexto autoTranslate. Por ejemplo:
        setAutoTranslate:
          component: "System.SetVariable"   
          properties:
            variable: "autoTranslate"     
            value:
             input: true
             output: true
En el siguiente ejemplo de la propiedad Metadata de un componente de respuesta común, la variable es dialogVar. El objeto del dato que se transfiere del componente personalizado a esta variable es {product: "an apple", type: "fruit", origin: "Spain" }.

responseItems:        
- type: "text" 
  text: "The product in your cart is a ${dialogVar.value.type}. It is
   ${dialogVar.value.product} from ${dialogVar.value.origin}"

El código personalizado para acceder a este parámetro de entrada puede tener un aspecto similar al siguiente:

module.exports = {
  metadata: () => ({
    name: 'myComponent',   
    properties: {
       dialogVar: { required: true, type: 'string' },    
    },
...
    // Retrieve the value of the 'dialogVar' component property.
    const { dialogVar } = context.properties();
    if (!dialogVar) {
      context.transition();
      done(new Error('The state is missing the dialogVar property.'));
    }
...
    context.setVariable(dialogVar, data);    
    context.transition();
    done();
  }
}

Detectar el idioma del usuario en un componente personalizado

Si el componente personalizado necesita que el idioma del usuario haga cosas como proporcionar formatos de fecha correctos, puede proporcionarlo al componente de una de estas maneras:

  • Acceda a las variables profile.locale y profile.languageTag desde el código de componente personalizado, como se muestra en el siguiente ejemplo:
    //detect user locale. If not set, define a default
    const locale = context.getVariable('profile.locale') ?
                   context.getVariable('profile.locale') : 'en-AU';
    //Make sure locale is returned with hyphen, not underscore. JavaScript requires a hyphen.
    const jsLocale = locale.replace('_','-'); 
    //when profile languageTag is set, use it. If not, use profile.locale
    const languageTag = context.getVariable('profile.languageTag')?
                        context.getVariable('profile.languageTag') : jslocale;
  • Transfiera los valores de profile.locale y/o profile.languageTag como parámetros de entrada al componente.
Nota

Si se establecen ambas variables, profile.languageTag tiene prioridad en la aptitud.