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

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

これを実行するにはいくつかの方法があります。
  • スキルにリソース・バンドル・エントリを作成し、カスタム・コンポーネントから直接参照します。この方法を使用すると、スキルからの他のメッセージの場合と同じ場所で、カスタム・コンポーネント・メッセージの翻訳を処理できます。
  • システム・コンポーネントおよびリソース・バンドル・エントリを使用して、カスタム・コンポーネントのデータ出力を組み込んだ翻訳可能な文字列を組み立てます。このアプローチでは、カスタム・コンポーネントとその特定のスキルの間の疎結合を促進しながら、スキルからの他のメッセージの場合と同じ場所でカスタム・コンポーネント・メッセージの翻訳を処理できます。
  • スキルの翻訳サービスを使用してコンポーネントのレスポンスを変換する場合は、カスタム・コンポーネントの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. 変数の情報を使用して、共通レスポンスなどのシステム・コンポーネントでレスポンスを組み立てます。
  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が優先されます。