応答のビルド



応答のビルド

応答ビルダー

SDKには応答を作成するためのヘルパーメソッドが含まれています。Responseには複数の要素が含まれる場合があり、ヘルパーメソッドによって、各応答の要素を初期化したり設定したりする必要がなくなり、応答を生成しやすくなります。

使用できるヘルパーメソッド

  • withSpeech(String speechText)
  • withSimpleCard(String cardTitle, String cardText)
  • withStandardCard(String cardTitle, String cardText, Image image)
  • withReprompt(String text)
  • withShouldEndSession(Boolean shouldEndSession)
  • addHintDirective(String hintText)
  • addVideoAppLaunchDirective(String source, String title, String subTitle)
  • addTemplateDirective(Template template)
  • addAudioPlayerPlayDirective(PlayBehavior playBehavior, Long offsetInMilliseconds, String expectedPreviousToken, String token, String url)
  • addAudioPlayerStopDirective()
  • addAudioPlayerClearQueueDirective(ClearBehavior clearBehavior)
  • addDirective(Directive directive)
  • withCanFulfillIntent(CanFulfillIntent canFulfillIntent)パブリックベータSDKでのみ使用可能)

目的の応答要素を追加したら、build()メソッドを呼び出してResponseを生成できます。

応答ビルダーの使用例

以下の例は、ResponseBuilderヘルパーメソッドを使用して応答を作成する方法を示しています。

@Override
public Optional<Response> handle(HandlerInput input) {
    return input.getResponseBuilder()
            .withSimpleCard("title", "cardText")
            .withSpeech("foo")
            .withReprompt("bar")
            .build();
}

テンプレートを使用して応答を作成する

SDKを使うと、テンプレートを使用してスキルの応答を作成できます。テンプレートは、動的なウェブページの作成によく使用される、モデルビューコントローラー(MVC)パターンのビューに似ています。テンプレートを使用した応答の作成には、次のメリットがあります。

  • プレゼンテーションロジックをリクエスト処理ロジックから分離して、Responseを生成できます。
  • たとえば、Alexa Presentation Languageを使用する際に、複雑な入れ子構造を持つResponseを簡単に生成できます。
  • 複数のスキルに共通のテンプレートを再利用して、コードの重複を減らすことができます。

1つのテンプレートに、outputSpeechcardshouldEndSessiondirectivesなどの複数の応答コンポーネントを含めることができます。これらのコンポーネントは、動的データのプレースホルダーや静的データを含むことができ、スキルの完全な応答に組み込まれます。

テンプレートを使用して応答を生成するには、スキルのビルド時にTemplate Factoryのコンフィギュレーションを行う必要があります。

Template Factory

Template Factoryインターフェースは、動的データを挿入して応答テンプレートを処理し、スキルの応答を生成します。これはRequestHandler内でスキルの応答をビルドするときに呼び出す必要があるエントリーポイントです。独自のテンプレートファクトリーを実装することも、SDKで提供されるBaseTemplateFactoryTemplate LoaderオブジェクトとTemplate Rendererオブジェクトのリストで構成されています)を活用することもできます。

Template Loader

Template Loaderインターフェースは、データストレージからテンプレートコンテンツを読み込みます。SDKは、ローカルファイルシステムからテンプレートファイルを読み込むLocalTemplateFileLoaderを提供します。独自のローダーを実装して、別のデータストレージの場所からテンプレートを読み込むことができます。

LocalTemplateFileLoaderを使用するには、テンプレートファイルのディレクトリパスとファイル拡張子を指定する必要があります。スキルをAWS Lambdaでホスティングする場合は、テンプレートファイルをリソースとしてスキルプロジェクトのJARに含め、Maven POMでリソースディレクトリのコンフィギュレーションを行う必要があります。

Mavenリソースのコンフィギュレーション

<resources>
  <resource>
    <directory>src/resources</directory>
  </resource>
</resources>

テンプレート列挙子

ロケールごとに異なる応答を生成できます。ロケールごとに異なるテンプレートファイルを使用するために、SDKはTemplateEnumeratorインターフェースとLocaleTemplateEnumerator実装を提供しています。これにより、スキルリクエストのロケールプロパティに基づいて、使用可能なテンプレートの場所と名前を列挙できます。たとえば、en-USは、template/en/USにあるテンプレートファイルまたはtemplate_en_USという名前のテンプレートファイルのロケールプロパティです。

前のスクリーンショットに示すように、テンプレートファイルにexample_responseという名前を付けたり、テンプレートファイルをbase_response_templateフォルダ内のロケール固有のフォルダに配置したりできます。LocaleTemplateEnumeratorは、まず最も固有性の高いテンプレートファイル(例:base_response_template/de/DE)を探し、より固有性の低いファイル(base_response_template/de)、グローバルなファイル(base_response_template)へとフォールバックしていきます。

ユーザー定義のテンプレート列挙子を実装して、好みに応じてテンプレートを列挙することができます。

Template Cache

テンプレートの読み込みプロセスを簡単にするため、SDKにはTemplateCacheインターフェースとConcurrentLRUTemplateCacheが用意されており、読み込んだテンプレートを後で利用できるようにキャッシュします。ConcurrentLRUTemplateCacheは、同時キャッシュをサポートしていて、容量は5MB、有効期限(TTL)はデフォルトで24時間です。必要に応じてこれらの値を変更したり、独自のテンプレートキャッシュを実装したりできます。

Template Renderer

Template Rendererインターフェースは、動的データを含む完全なテンプレートをレンダリングして、スキルのResponseに変換します。SDKはFreeMarkerテンプレートをレンダリングするためのFreeMarkerTemplateRendererを実装します。これにより、マクロインポートなどのFreeMarkerの機能を活用することができます。独自のテンプレートレンダラーを実装して、他のテンプレートエンジンをサポートすることもできます。

FreeMarkerTemplateRendererを使用するには、Mavenプロジェクトのask-sdk-freemarkerに依存関係を追加する必要があります。

<dependency>
  <groupId>com.amazon.alexa</groupId>
  <artifactId>ask-sdk-freemarker</artifactId>
  <version>${version}</version>
</dependency>

Template Factoryの使用例

以下は、Template Factoryの基本的なセットアップの例です。テンプレートのルートパスを指定するだけで、SDKがTemplate Factoryのデフォルト実装を生成します。

private static Skill getSkill() {

    // スキルをビルドします
    return Skills.standard()
            .withTemplateDirectoryPath("/com/amazon/ask/example/")
            .addRequestHandlers(
                    new LaunchRequestHandler(),
                    ... ...
                    new SessionEndedRequestHandler())
            .build();
}

Template Factoryのカスタム実装を提供することもできます。

private static Skill getSkill() {

    // LocalTemplateFileLoaderのコンフィギュレーション
    TemplateLoader loader = LocalTemplateFileLoader.builder()
            .withDirectoryPath("com/amazon/ask/example/")
            .withFileExtension("ftl")
            .build();

    // FreeMarkerTemplateRendererのコンフィギュレーション
    JacksonJsonUnmarshaller jacksonJsonUnmarshaller = JacksonJsonUnmarshaller
            .withTypeBinding(Response.class);
    TemplateRenderer renderer = FreeMarkerTemplateRenderer.builder()
            .withUnmarshaller(jacksonJsonUnmarshaller)
            .build();

    // BaseTemplateFactoryのコンフィギュレーション
    TemplateFactory templateFactory = BaseTemplateFactory.builder()
            .withTemplateRenderer(renderer)
            .addTemplateLoader(loader)
            .build();

    // スキルをビルドします
    return Skills.standard()
            .withTemplateFactory(templateFactory)
            .addRequestHandlers(
                    new LaunchRequestHandler(),
                    ... ...
                    new SessionEndedRequestHandler())
            .build();
}

テンプレートのディレクトリパスとTemplate Factoryのカスタムオブジェクトの両方を指定すると、例外がスローされます。

private static Skill getSkill() {

    // ローダーとレンダラーをビルドして、Template Factoryに渡します
    TemplateFactory templateFactory = BaseTemplateFactory.builder()
            .withTemplateRenderer(renderer)
            .addTemplateLoader(loader)
            .build();

    // 例外をスローします
    return Skills.standard()
            .withTemplateDirectoryPath("/com/amazon/ask/example/")
            .withTemplateFactory(templateFactory)
            .addRequestHandlers(
                    new LaunchRequestHandler(),
                    ... ...
                    new SessionEndedRequestHandler())
            .build();
}

リクエストハンドラーでテンプレートを使用して応答を生成する

@Override
public Optional<Response> handle(HandlerInput input) {
    String speechText = "テンプレート応答へようこそ。";

    // 動的データをテンプレートに提供します
    Map<String, Object> datamap = new HashMap<>();
    datamap.put("outputSpeechText", speechText);

    return input.generateTemplateResponse("base_response_template", datamap);
}

上記のコード例を使用すると、次のFreeMarkerテンプレートの例では、完全なリソースパスとして/com/amazon/ask/example/base_response_template/en/US.ftl、ディレクトリパスとして/com/amazon/ask/example/、ファイル拡張子としてftlLocalTemplateFileLoaderに渡され、ロケールプロパティとしてen-USRequestからLocaleTemplateEnumeratorに渡されます。

FreeMarkerテンプレートの例

以下は、スキルの応答のOutputSpeechコンポーネント用のFreeMarkerテンプレートの例です。

{
  "outputSpeech": {
      "type": "PlainText",
      "text": "${outputSpeechText}"
  }
}