カスタム・コンポーネントのレスポンスの国際化およびローカライズ

会話でコンテンツを返すカスタム・コンポーネントがある場合は、ユーザーのターゲット言語でそのコンテンツが返されるようにする必要もあります。

これを実行するにはいくつかの方法があります。
  • スキルにリソース・バンドル・エントリを作成し、カスタム・コンポーネントから直接参照します。このアプローチでは、スキルからの他のメッセージの場合と同じ場所でカスタム・コンポーネント・メッセージの翻訳を処理できます。
  • カスタム・コンポーネントのデータ出力を組み込んだ翻訳可能文字列を組み立てるには、システム・コンポーネントおよびリソース・バンドル・エントリを使用します。このアプローチでは、カスタム・コンポーネントと特定のスキルの間の緩い結合を育成しながら、スキルからの他のメッセージの場合と同じ場所でカスタム・コンポーネント・メッセージの翻訳を処理できます。
  • スキルの翻訳サービスを使用してコンポーネントのレスポンスを翻訳する場合は、カスタム・コンポーネントのtranslateプロパティをtrueに設定します。
  • コンポーネントで、メッセージに組み込む必要があるバックエンド・データを取得して返す場合で、スキルの翻訳サービスを使用してコンポーネントのレスポンスを翻訳する場合は、返されたデータをダイアログ・フローの変数に格納します。この変数は、システム・コンポーネントで参照できます。

カスタム・コンポーネントからのリソース・バンドルの参照

組込みコンポーネントやアンサー・インテントなどのメッセージにリソース・バンドルを使用できるのと同様に、カスタム・コンポーネントにもリソース・バンドルを使用できます。次のようにします。

  1. メッセージのスキルにリソース・バンドル・エントリを定義します。リソース・バンドル・キーの作成を参照してください。
  2. Bots Node SDKのcontext.translate()メソッドを使用して、カスタム・コンポーネント・コードのリソース・バンドル・キーを参照します。

    context.translate()は、指定されたリソース・バンドル・キー名(およびリソース・バンドル・エントリで指定されたパラメータ)を取得し、context.reply()メソッドを介して会話がユーザーに返送されたときに、指定されたリソース・バンドル言語文字列をロードするために必要な適切なFreeMarkerテンプレートを生成します。

  3. context.replyヘルパー・メソッドを使用して、変換されたレスポンスを出力します。例:
    context.reply(translate('date.message', dateToday, dayOfWeek ));
  4. カスタム・コンポーネントが参照するすべてのリソース・バンドル・キーおよび予想されるデフォルト文字列を文書化します。(カスタム・コンポーネントはスキル内のリソース・バンドル・キーを直接参照するため、参照キーがスキル内で有効であることを確認するために、カスタム・コンポーネントの開発者とスキルを構築する開発者との間に高度な調整が必要です)。

この例では、date.messageはリソース・バンドル・キー、dateTodayおよびdayOfWeekは変数で、次のようなFreeMarker式が返されます。

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

ノート

context.translate()メソッドは、パラメータがないか、定位置(番号付き)パラメータを使用するリソース・バンドル値のみをサポートします。たとえば、date.messageキーの例の場合、値は“Today is {0}, {1}”のようになります。名前付きパラメータおよび複合メッセージ形式はサポートされていません。

システム・コンポーネントを使用したリソース・バンドルの参照

システム・コンポーネントを使用して、カスタム・コンポーネントから返されたリソース・バンドル・エントリおよびデータを使用してメッセージをアセンブルできます。ベース・メッセージ文字列は、リソース・バンドル・エントリで定義します。バンドル・エントリには、カスタム・コンポーネントから出力されるデータ(数値や日付など)のパラメータが含まれる場合があります。ベース・メッセージ文字列はダイアログ・フローで定義されるため、この方法では、カスタム・コンポーネントが特定の実装コードに依存せず、再使用可能のままになります。

一般的なステップは次のとおりです:

  1. カスタム・コンポーネントの場合、返されるデータを格納するためのコンテキスト変数の名前に必要な入力パラメータを含めます。
  2. カスタム・コンポーネント開発者とダイアログ・フロー開発者は、同じ人物でも同じチームでもない可能性があるため、カスタム・コンポーネントがその変数で返すデータを慎重に文書化し、返されたデータをユーザーにメッセージで表示する方法を理解できるように、カスタム・コンポーネント・コンシューマがその情報を使用できるようにします。
  3. ダイアログ・フローで、カスタム・コンポーネントの返されたデータを格納する変数を作成し、その名前を必須入力パラメータに渡します。
  4. メッセージのスキルにリソース・バンドル・エントリを定義します。リソース・バンドル・キーの作成を参照してください。
  5. ダイアログ・フローで、リソース・バンドル・エントリを参照し、必要なパラメータを入力します。

YAMLダイアログ・モードで開発されたスキルの次のサンプルは、initializeReceipt状態のカスタム・コンポーネントを参照し、コンポーネント・レスポンスおよびpurchaseIdを入力パラメータとして保持する変数の名前(receipt)を渡します。printProduct状態では、receipt値が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}')}"

これらの入力パラメータにアクセスするためのカスタム・コードは、次のコードのようになります。

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

翻訳サービスへの応答の直接送信

コンポーネントのレスポンス・テキストが何であるかを知る方法がない場合は(リモート・バックエンドから問合せされた場合など)、スキルの翻訳サービスを使用してレスポンスを翻訳できます。手順は次のとおりです:

  1. コンポーネントでtranslateプロパティを定義し、trueに設定して、その出力を翻訳サービスに送信するようにコンポーネントが設定されていることを確認します。
  2. カスタム・コンポーネントで、context.replyヘルパー・メソッドを使用してレスポンスを返します。

このアプローチは、翻訳サービス言語モードで設定されたスキルでのみ機能します。

システム・コンポーネントを使用したメッセージを翻訳サービスに渡す

バックエンド・サービスを問い合せるカスタム・コンポーネントでは、オブジェクトやオブジェクトの配列などの複雑なフォーマットでデータを返すことがあります。翻訳サービスを使用している場合は、これらのデータ・オブジェクトをそのまま翻訳サービスに送信できません。かわりに、データ・オブジェクトの必要な属性を個別に参照するメッセージを作成する必要があります。

  1. カスタム・コンポーネントの場合、返されたデータを格納するためのダイアログ・フロー変数の名前に必要な入力パラメータを含めます。
  2. カスタム・コンポーネント開発者とダイアログ・フロー開発者は、同じ人物でも同じチームでもない可能性があるため、カスタム・コンポーネントがその変数で返すデータを慎重に文書化し、返されたデータをユーザーにメッセージで表示する方法を理解できるように、カスタム・コンポーネント・コンシューマがその情報を使用できるようにします。
  3. ダイアログ・フローで、カスタム・コンポーネントの返されたデータを格納する変数を作成し、その名前を必須入力パラメータに渡します。
  4. 変数内の情報を使用して、Common Responseなどのレスポンスをシステム・コンポーネントにアセンブルします。
  5. スキルが自動翻訳用に構成されていることを確認してください。
    • ビジュアル・ダイアログ・モードで開発されたスキルの場合、スキルの「設定」ページの「ボット・レスポンス・メッセージの翻訳」プロパティをtrueに設定します。
    • YAMLダイアログ・モードで開発されたスキルの場合は、autoTranslateコンテキスト変数を設定することで、これをスキルでグローバルに処理できます。例:
        setAutoTranslate:
          component: "System.SetVariable"   
          properties:
            variable: "autoTranslate"     
            value:
             input: true
             output: true
共通レスポンス・コンポーネントの「メタデータ」プロパティの次の例では、変数はdialogVarです。カスタム・コンポーネントからこの変数に渡されるデータ・オブジェクトは{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}"

この入力パラメータにアクセスするためのカスタム・コードは、次のコードのようになります。

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

カスタム・コンポーネントでのユーザー言語の検出

カスタム・コンポーネントで正しい日付書式の指定などを行うためにユーザーの言語が必要な場合は、次のいずれかの方法でコンポーネントに提供できます。

  • 次の例に示すように、カスタム・コンポーネント・コードからprofile.localeおよびprofile.languageTag変数にアクセスします。
    //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;
  • profile.localeまたはprofile.languageTag(あるいはその両方)の値を入力パラメータとしてコンポーネントに渡します。
ノート

両方の変数が設定されている場合は、スキルでprofile.languageTagが優先されます。