マルチモーダルなAlexaスキルの作り方

バックエンドを変更してLaunchRequestの視覚要素を追加する

目次

このセクションでは、バックエンドを変更して、応答にAPLの視覚要素を安全に追加する方法を学びます。最終的には、前のセクションで作成したAPL視覚要素をCake TimeスキルのLaunchリクエストに追加して拡張したものができあがります。さらに、Alexa-hosted環境のS3を使用して自分のアセットをホストし、これを使用してスキルに背景画像を追加する方法も学習します。

このセクションでは、Cake Timeのコードを使用します。Alexaの開発が初めての方で、魅力的なスキルを開発するコースを学習していない場合は、この入門コースを終えてからこのモジュールに戻ってきてください。スキルの開発経験を既にお持ちの方で、Node.jsの基礎を理解されている場合は、入門コースをスキップしてクイックセットアップ手順に進み、Cake Timeスキルのコードを取得して概要を把握いただいても構いません。

1.スキルに視覚要素を追加する

AlexaデバイスでAPLドキュメントを安全にレンダリングするには、デバイスがAPLをサポートしている場合にのみ、Renderディレクティブを使って応答する必要があります。このディレクティブは、 Alexa.Presentation.APL.RenderDocumentの形式になります。ディレクティブは、Node.js SDKを使って簡単に追加できます。これには、handlerInput.responseBuilder.addDirective({…​});を呼び出します。

Renderディレクティブはどの応答にも追加できますが、すべてのデバイスがそれに対応できるとは限りません。 Alexa.Presentation.APL.RenderDocumentを使って安全に応答するには、まず、呼び出し元のデバイスが適切なリクエストオブジェクトを送信していることを確認する必要があります。この情報は、context.System.device.supportedInterfacesなどのsupportedInterfacesオブジェクトに含まれています。次のようなサンプルリクエストがあるとします。

{
...
"context": {
    "System": {
        ...
        "device": {
            "deviceId": "amzn1.ask.device.1...",
            "supportedInterfaces": {
                "Alexa.Presentation.APL": {
                    "runtime": {
                        "maxVersion": "1.1"
                    }
                }
            }
        }
        ...
    }
    }
}

SDKを使用している場合、サポートされるインターフェースの確認は簡単です。

 

A. In your LaunchRequestHandler.handle() で、応答を作成する前に、次のコードを追加します。

if (Alexa.getSupportedInterfaces(handlerInput.requestEnvelope)['Alexa.Presentation.APL']) {
    // Renderディレクティブを作成します。
}

このif文で、APLインターフェースがリクエストエンベロープで送信されているかどうかをチェックします。送信されている場合にのみ、応答を追加します。では、応答を追加しましょう。

B. // Renderディレクティブを作成します コメントの下に、次のコードを追加します。

handlerInput.responseBuilder.addDirective({
    type: 'Alexa.Presentation.APL.RenderDocument',
    document: launchDocument,
    datasources: {
        text: {
            type: 'object',
            start: "Welcome",
            middle: "to",
            end: "Cake Time!"
        }
    }
});

画像に関する情報は省略しています。Alexa-hosted環境から画像を提供するにはもう少し作業が必要なので、これについては後ほど説明します。では、launchDocumentをインポートしましょう。汎用のLaunch RequestsのAPLドキュメントなので、ドキュメントにlaunchDocument.jsonという名前を付けます。

create launch screen gif

C. 左側のlambdaフォルダーを選択します。右クリックして、フォルダーを作成を選択します。lambda配下のフォルダーに、documentsという名前を付けます。さらにdocumentsフォルダー内に、新しい launchDocument.jsonファイルを追加します。

D. launchDocument.jsonファイルに、モジュール2でオーサリングツールを用いて作成したJSONを追加します(JSONドキュメントの完全版はモジュール2の最後にあります)。

E. index.jsプログラムの最初で、これを次のようにインポートします。

const launchDocument = require('./documents/launchDocument.json');

javascriptコードのlaunchDocument変数は、自分のjsonファイルのコンテンツを表します。

F. コードをデプロイします。テストも忘れずに実行しましょう。

2.開発者コンソールのシミュレーターを使用してテストする

APLの追加部分のテストで問題が発生しましたか? ドキュメントの変更をテストする前に、ビルドタブでAPLを有効にする必要があります。

A. ビルドタブをクリックします。左側のインターフェースをクリックします。

interfaces click image

B. 下にスクロールして、Alexa Presentation Languageをオンにします。ブロックが展開されるので、すべてのボックスをオンにします。

Hub RoundHub LandscapeTV Fullscreenはデフォルトでオンになっているので、サポートする必要があります。これらの各画面を公式にサポートします。コンテンツの拡大縮小はされないので、応答で送信するアセットやAPLレイアウトはどれもそのまま表示されます。また、サポートされていないviewportプロファイルの場合は、サポートしている中で最もサイズが近いviewportのコンテンツで拡大縮小されます。すべてのデバイスのプロファイルを確認しテストするので、すべてをオンにします。これらをオンにすることで、各プロファイルでレイアウトをテストしたことが示されます。viewportプロファイルの選択の詳細については、技術資料を参照してください。

toggle apl image

C. APLをオンにして、viewportプロファイルをすべて選択したら、対話モデルをビルドする必要があります。注意:これは、サポートされるプロファイルに変更があった場合、公開のために新たなスキルの認定申請が必要となることも意味します。

D. ビルドができたら、テストの準備は完了です。テストタブに移動し、デバイスの表示がオンになっていることを確認します。JSON入力およびJSON出力の下にスクロールすると、使用するデバイスを選択できます。スキルI/Oをオフにすると、下までスクロールしなくても視覚要素を表示できます。

S3にユーザーデータがある場合は、忘れずに削除してください。 コンテキストなしの起動ハンドラーを修正したので、この新しい画面のテストを行うには、S3から自分のユーザーデータを削除して実際にコンテキストがない状態にする必要があります。

E. ケークウォークを起動してと入力するなどして起動ハンドラーをトリガーし、中型デバイスの画面をテストします。

F. このテストをほかのすべての画面タイプで繰り返します。誕生日ケーキの画像はまだ含めていないので、表示されなくても心配はいりません。

3.アセットをS3にアップロードする

画像アセットを利用できるようにするには、それらの画像をホストする必要があります。コンテンツ配信ネットワーク(Amazon CloudfrontS3の併用など)を使用してアセットをユーザーに近い場所に提供するのが理想的ですが、この演習ではAlexa-hosted環境が提供するS3を使用します。

A. アセットをS3にアップロードするには、コードエディタタブで、左側の最下部にあるS3のメディアストレージにアクセスします。

s3 access image

B. 画面上部のパス表示が下記の例のようにMediaページが開いていることを確認します。

 Amazon S3 > amzn1-ask-skill-XXXXXXXXXXX > Media

C. ここで、このページにあるアセットをアップロードします。手間を省くため、zip形式のアセットファイルを用意しました。これらはすべてコースのモジュールで使用します。アップロードすると、S3にページのアセットがすべて表示されます。

s3 provision image

アセットのアップロードができたので、画像を加えてLaunch Requestを更新できます。

4.起動リクエストハンドラーを更新する

ここまではコンテキストなしの起動リクエストを使用していましたが、ここで、デフォルトの背景の代わりに背景画像を追加しましょう。

A. まず、オーサリングツールを開き、launchDocument.jsonの内容を貼り付けます。

B. オーサリングツールのDATAセクションで、以下を使用します。

{
    "text": {
        "start": "Welcome",
        "middle": "to",
        "end": "Cake Time!"
    },
    "assets": {
        "cake":"https://github.com/alexa/skill-sample-nodejs-first-apl-skill/blob/master/modules/assets/alexaCake_960x960.png?raw=true",
        "backgroundURL": "https://github.com/alexa/skill-sample-nodejs-first-apl-skill/blob/master/modules/assets/lights_1920x1080.png?raw=true"
    }
}

データのassetsオブジェクトの下に、新しいbackgroundURLフィールドが追加されていることにお気付きでしょうか?これは、デバイスが背景画像をどこから取得するかを示しています。画面作成の間は、公開リンクであるGithubリポジトリをホスティングに使用します。しかし、実際のコードではS3の署名付きURLのutil関数を使用します。この関数は、アセットをアップロードしたプライベートバケットへの有効期限付きの公開URLを生成するために必要です。次に、Backgroundコンポーネントを追加します。

C. オーサリングツールのAPLタブに戻ります。

D. AlexaBackgroundレスポンシブ対応コンポーネントを追加します。これを使用するには、既に作成してあるalexa-layoutsパッケージが必要になります。 AlexaBackgroundを使用するのは簡単です。以下をそれぞれのContainerのitems配列の最初に追加するだけです。

{
    "type": "AlexaBackground",
    "backgroundImageSource": "${assets.backgroundURL}"
},

背景が明るくなるはずです。 これで、 背景にライトが表示されました。

E. 背景にImageを使用しているので、テキストの色も変えましょう。すべてのTextオブジェクト用のスタイルがあるので、これは簡単です。 新しいプロパティとして、"color": "black"bigTextスタイルに追加するだけです。これは次のようになります。

"bigText": {
    "values": [
        {
            "fontSize": "72dp",
            "color": "black",
            "textAlign": "center"
        }
    ]
}

F. @hubRoundSmallについても同じ変更を適用して、オーサリングツールで機能するようにします。

Alexaについても同じ変更を適用して、オーサリングツールで機能するようにします。Backgroundレスポンシブ対応コンポーネントがほかのコンポーネントより上にあることを確認してください。下にある場合はすべてを覆ってしまいます。

各デバイスに対して、1つの1920x1080のpngファイルを使用していることにお気付きかと思います。こうすれば拡大縮小がうまくいきます。FireTVデバイスを考慮して、可能な限り最高の解像度を使用しています。縮小すると、画像の品質は向上します。ただし、この品質レベルに対応していない低解像度のデバイスでは、不要なデータをダウンロードすることになるというトレードオフもあります。最善策としては、さまざまなデバイスクラス向けに複数の異なる画像解像度を提供することをお勧めします。次のセクションでは、その方法を説明していきます。

5.画像を適用する

A. ドキュメントができたので、コードエディタタブのlaunchDocument.jsonのコンテンツを、オーサリングツールのJSONに置き換えます。

B. index.jsに戻ります。プライベートS3インスタンスへのリンクを追加しているので、utilモジュールをインポートする必要があります。このファイルの上部に、別のインポートを追加します。

const util = require('./util');

C. 新しいデータソースをindex.jsのコードに追加します。画像は非公開のS3バケットにあるので、これからutil関数を使用して、アセットへの有効期限付きの公開URLを取得します。この場合のS3オブジェクトキーは、 'Media/imageName.png'の形式になります。APLレンダリングブロックのデータに画像を追加しましょう。datasourcesブロックは次のようになります。

datasources: {
    text: {
        type: 'object',
        start: "Welcome",
        middle: "to",
        end: "Cake Time!"
    },
    assets: {
        cake: util.getS3PreSignedUrl('Media/alexaCake_960x960.png'),
        backgroundURL: util.getS3PreSignedUrl('Media/lights_1920x1080.png')
    }
}

D. 新しいドキュメントをデプロイし、各画面サイズでテストします。

E. うまくいきましたか? あともう少しです。 前のセクションで触れた最適化をここで行いましょう。このためにはもう1つアセットが必要です。lights_1280x800.pngは既にアップロードしました。条件に応じて適切なアセットを取得して、画像を変更する必要があります。backgroundURLの値を以下に置き換えます。

util.getS3PreSignedUrl(backgroundKey)

F. 条件に応じて適切なbackgroundKeyを設定するには、Alexaとしてインポート済のask-sdk-coreパッケージを使用する必要があります。viewportプロファイルを取得するには、APL条件部分に次のコードを追加します。 Alexaとしてインポート済のask-sdk-coreパッケージを使用する必要があります。viewportプロファイルを取得するには、APL条件部分に次のコードを追加します。

const viewportProfile = Alexa.getViewportProfile(handlerInput.requestEnvelope);

G. viewportProfile文の下に次の文を追加して、このロジックを実装できます。

const backgroundKey = viewportProfile === 'TV-LANDSCAPE-XLARGE' ? "Media/lights_1920x1080.png" : "Media/lights_1280x800.png";

H. テストコンソールで、TVとそのほかのデバイスを使用できることをシミュレーションして確認します。違いはあまりわからない可能性もあります。適切に機能しているかどうかを調べるには、TVと低解像度のデバイスそれぞれのテストで、正しいアセットが提供されているかどうかをテストコンソールのスキルI/Oセクションで確認します。

これで完成です。レスポンシブ対応コンポーネントを使用することで、フロントエンドが適切に拡大縮小されるようになりました。 次のモジュールに進んで、より高度なAPLドキュメントの概念を学びましょう。

Githubのコード(完全版)