Internazionalizzare e localizzare le risposte dei componenti personalizzati

Se si dispone di componenti personalizzati che restituiscono contenuto nelle conversazioni, è necessario assicurarsi che restituiscano tale contenuto nella lingua di destinazione dell'utente.

Ci sono diversi modi per farlo:
  • Creare voci bundle di risorse nello skill e fare riferimento a tali voci direttamente dal componente personalizzato. Questo approccio consente di gestire le traduzioni dei messaggi dei componenti personalizzati nello stesso luogo in cui vengono eseguiti gli altri messaggi dello skill.
  • Utilizzare le voci di un componente di sistema e di un bundle di risorse per l'assemblaggio delle stringhe traducibili che incorporano l'output dati del componente personalizzato. Questo approccio consente di gestire le traduzioni dei messaggi dei componenti personalizzati nello stesso luogo in cui vengono utilizzati per altri messaggi dello skill, promuovendo al contempo un accoppiamento più flessibile tra il componente personalizzato e lo skill specifico.
  • Se si desidera utilizzare il servizio di traduzione dello skill per tradurre le risposte del componente, impostare la proprietà translate del componente personalizzato su true.
  • Se il componente recupera e restituisce i dati backend che devono essere incorporati in un messaggio e si desidera utilizzare il servizio di traduzione dello skill per tradurre le risposte del componente, memorizzare i dati restituiti in una variabile nel flusso della finestra di dialogo. È quindi possibile fare riferimento a questa variabile in un componente di sistema.

Bundle di risorse di riferimento dal componente personalizzato

Proprio come puoi utilizzare i bundle di risorse per i messaggi in componenti integrati, intenti di risposta e così via, puoi utilizzare anche i bundle di risorse per i tuoi componenti personalizzati. A tale scopo, eseguire le operazioni riportate di seguito.

  1. Definire le voci del bundle di risorse nella competenza per il messaggio. Vedere Crea chiavi bundle risorse.
  2. Utilizzando il metodo context.translate() dell'SDK del nodo bot, fare riferimento alle chiavi del bundle di risorse dal codice del componente personalizzato.

    context.translate() assume un nome chiave del bundle di risorse specificato (e qualsiasi parametro specificato nella voce del bundle di risorse) e genera il modello FreeMarker appropriato necessario per caricare la stringa della lingua del bundle di risorse denominato quando la conversazione viene inviata di nuovo all'utente tramite il metodo context.reply().

  3. Utilizzare il metodo dell'applicazione di supporto context.reply per stampare la risposta tradotta. Ad esempio:
    context.reply(translate('date.message', dateToday, dayOfWeek ));
  4. Documentare tutte le chiavi del bundle di risorse a cui fa riferimento il componente personalizzato e le stringhe predefinite previste. Poiché il componente personalizzato fa direttamente riferimento alla chiave del bundle di risorse all'interno della competenza, è necessario un elevato grado di coordinamento tra lo sviluppatore del componente personalizzato e quelli che sviluppano la competenza per garantire che le chiavi di riferimento siano valide all'interno della competenza.

In questo esempio, date.message è una chiave bundle di risorse, dateToday e dayOfWeek sono variabili e viene restituita un'espressione FreeMarker simile alla seguente:

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

Nota

Il metodo context.translate() supporta solo i valori del bundle di risorse che non dispongono di parametri o che utilizzano parametri posizionali (numerati). Ad esempio, nel caso della chiave date.message di esempio, il valore potrebbe essere simile a “Today is {0}, {1}”. I parametri denominati e i formati di messaggio complessi non sono supportati.

Utilizzare un componente di sistema per fare riferimento a un bundle di risorse

È possibile utilizzare un componente di sistema per assemblare i messaggi utilizzando voci e dati del bundle di risorse restituiti da un componente personalizzato. Definire le stringhe dei messaggi di base nelle voci del bundle di risorse. Le voci del bundle potrebbero includere parametri per i dati (ad esempio numeri e date) che vengono generati dal componente personalizzato. Poiché le stringhe di messaggio di base sono definite nel flusso della finestra di dialogo, questo approccio garantisce che i componenti personalizzati non siano dipendenti da un codice di implementazione specifico e rimangano riutilizzabili.

Ecco i passaggi generali:

  1. Per il componente personalizzato, includere un parametro di input obbligatorio per il nome della variabile di contesto in cui memorizzare i dati restituiti.
  2. Poiché lo sviluppatore del componente personalizzato e lo sviluppatore del flusso di finestre di dialogo potrebbero non essere la stessa persona o anche nello stesso team, documentare attentamente quali dati il componente personalizzato restituisce in tale variabile e rendere le informazioni disponibili a tutti i consumer di componenti personalizzati in modo che comprendano come presentare i dati restituiti all'utente in un messaggio.
  3. Nel flusso della finestra di dialogo, creare una variabile per memorizzare i dati restituiti del componente personalizzato e passarne il nome nel parametro di input richiesto.
  4. Definire le voci del bundle di risorse nella competenza per il messaggio. Vedere Crea chiavi bundle risorse.
  5. Nel flusso della finestra di dialogo, fare riferimento alla voce del bundle di risorse e immettere eventuali parametri obbligatori.

L'esempio seguente di uno skill sviluppato in modalità finestra di dialogo YAML fa riferimento a un componente personalizzato nello stato initializeReceipt e passa il nome della variabile (receipt) che contiene la risposta del componente e purchaseId come parametri di input. Lo stato printProduct incorpora quindi il valore receipt come parametro in un riferimento alla voce del bundle di risorse denominata 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}')}"

Il codice personalizzato per l'accesso a questi parametri di input potrebbe essere simile al codice seguente:

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();
  }
}

Invia risposte direttamente al servizio di traduzione

Se non si dispone di un modo per sapere quale sarà il testo di risposta del componente (ad esempio se viene sottoposto a query da un backend remoto), è possibile utilizzare il servizio di traduzione dello skill per tradurre le risposte. A tale scopo, procedere come segue.

  1. Assicurarsi che il componente sia impostato in modo che il relativo output venga inviato al servizio di traduzione definendo la proprietà translate sul componente e impostandola su true.
  2. Nel componente personalizzato, utilizzare il metodo dell'applicazione di supporto context.reply per restituire la risposta.

Questo approccio funziona solo con le competenze impostate nella modalità lingua del servizio di traduzione.

Utilizzare un componente di sistema per passare il messaggio al servizio di traduzione

I componenti personalizzati che eseguono query sui servizi backend potrebbero restituire i dati in un formato complesso, ad esempio un oggetto o un array di oggetti. Se si utilizza un servizio di traduzione, questi oggetti dati non possono essere inviati al servizio di traduzione così com'è. È invece necessario creare un messaggio che faccia riferimento a qualsiasi attributo necessario dell'oggetto dati singolarmente.

  1. Per il componente personalizzato, includere un parametro di input obbligatorio per il nome della variabile di flusso della finestra di dialogo in cui memorizzare i dati restituiti.
  2. Poiché lo sviluppatore del componente personalizzato e lo sviluppatore del flusso di finestre di dialogo potrebbero non essere la stessa persona o anche nello stesso team, documentare attentamente quali dati il componente personalizzato restituisce in tale variabile e rendere le informazioni disponibili a tutti i consumer di componenti personalizzati in modo che comprendano come presentare i dati restituiti all'utente in un messaggio.
  3. Nel flusso della finestra di dialogo, creare una variabile per memorizzare i dati restituiti del componente personalizzato e passarne il nome nel parametro di input richiesto.
  4. Utilizzando le informazioni contenute nella variabile, assemblare la risposta in un componente di sistema, ad esempio Risposta comune.
  5. Assicurarsi che lo skill sia configurato per la traduzione automatica.
    • Per gli skill sviluppati in modalità finestra di dialogo Visual, impostare la proprietà Translate Bot Response Message nella pagina Impostazioni dello skill su true.
    • Per le competenze sviluppate in modalità finestra di dialogo YAML, è possibile gestirle a livello globale impostando la variabile di contesto autoTranslate. Ad esempio:
        setAutoTranslate:
          component: "System.SetVariable"   
          properties:
            variable: "autoTranslate"     
            value:
             input: true
             output: true
Nell'esempio seguente della proprietà Metadati di un componente Risposta comune, la variabile è dialogVar. L'oggetto dati passato dal componente personalizzato a questa variabile è {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}"

Il codice personalizzato per l'accesso a questo parametro di input potrebbe essere simile al codice seguente:

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();
  }
}

Rileva la lingua utente in un componente personalizzato

Se il componente personalizzato richiede la lingua dell'utente per eseguire operazioni quali fornire formati di data corretti, è possibile fornirlo al componente in uno dei seguenti modi:

  • Accedere alle variabili profile.locale e profile.languageTag dal codice del componente personalizzato come mostrato nell'esempio seguente:
    //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;
  • Passare i valori di profile.locale e/o profile.languageTag come parametri di input al componente.
Nota

Se entrambe le variabili sono impostate, profile.languageTag ha la precedenza nello skill.