カスタムスキルをAWS Lambda関数としてホスティングする



カスタムスキルをAWS Lambda関数としてホスティングする

カスタムAlexaスキル用のクラウドベースのサービスを構築する最も簡単な方法は、AWS Lambdaを使用することです。この アマゾンウェブサービスが提供するサービスは、必要な場合にのみコードを実行し、自動的にスケールするため、サーバーをプロビジョニングしたり、連続実行したりする必要がありません。Alexaスキル用のコードをLambda関数にアップロードすれば、後はLambdaが処理します。Alexa音声対話に応答してコードを実行し、自動的にコンピューティングリソースを管理します。

Lambda関数とカスタムスキルについて

サービスにLambda関数を使用することで独自のエンドポイントをセットアップしたり管理する手間を一部省くことができます。

  • サービス用のコンピューティングリソースを管理する必要がありません。
  • SSL証明書が必要ありません。
  • Alexaサービスからリクエストが届いたかどうかを自身で確認する必要がありません。AWS内の権限によって関数を実行するためのアクセスが制御されるためです。
  • AWS Lambdaは、必要な場合にのみコードを実行し、使用状況に合わせてスケールするため、サーバーをプロビジョニングしたり、連続実行したりする必要がありません。
  • AlexaがTLSを使用してLambdaとの通信を暗号化します。AWSセキュリティのベストプラクティス(英語)も参照してください。
  • ほとんどの開発者にとって、Alexaスキルをサポートする関数にはLambdaの無料利用枠で十分です。毎月のリクエストが100万件まで無料になります。Lambda無料利用枠は自動的に期限が切れることはなく、永久に使用できます。

AWS Lambdaは、Node.js、Java、Python、C#のコードをサポートします。Node.jsまたはPythonコードをAWS Lambdaコンソールのインラインコードエディターでコピーして編集することも、コードをzipファイルでアップロードすることもできます。基本的なテストでは、LambdaコンソールでJSONリクエストを送信することにより、関数を手動で呼び出すことができます。

AWS Lambdaの概要については、AWS Lambdaとはを参照してください。

Lambda関数は、同じサービスインターフェースに準拠し、Alexaから送信される3種類のリクエストを処理する必要があります。Alexaリクエストの処理方法の詳細については、Alexaから送信されたリクエストを処理するを参照してください。JSONインターフェースの詳細については、カスタムスキルのJSONインターフェースのリファレンスを参照してください。

カスタムスキル用のLambda関数は、次のいずれかの地域でホストできます。

  • アジアパシフィック(東京)
  • EU(アイルランド)
  • 米国東部(バージニア北部)
  • 米国西部(オレゴン)

このドキュメントでは、カスタムスキル用の新しいLambda関数の作成方法について説明します。スマートホームスキルAPIを使用する場合は、Lambdaを使用してスキルアダプターを作成します。スマートホームスキルの作成手順を参照してください。

Alexaスキル用のLambda関数を作成する

Lambdaコンソールを使用して新しいLambda関数を作成し、基本的なテストを実施します。設計図を利用して、Node.jsまたはPythonで基本的な機能を実装したシンプルなスキルを作成することができます。もしくは、設計図の手順をスキップして、Lambda関数を一から作成することもできます。

Javaでサービスをコーディングしたいが、まだJavaプロジェクトをセットアップしていない場合は、サンプルのいずれかを自分の関数のひな形として使用することもできます。

Lambda関数を作成する前に、開発者コンソールでスキルを作成してスキルIDをコピーします。

新しいLambda関数を作成するには

  1. AWSのアカウントをまだお持ちでない場合は、アマゾンウェブサービスにアクセスしてアカウントを作成します。
  2. AWSマネジメントコンソールにログインして、AWS Lambdaに移動します。
  3. コンソールの右上隅にある地域のドロップダウンリストをクリックし、Alexaスキルでサポートされる地域を1つ選択します。 選択肢は、アジアパシフィック(東京)、EU(アイルランド)、米国東部(バージニア北部)、米国西部(オレゴン)のいずれかです。
  4. まだLambda関数がない場合は、今すぐ始めるをクリックします。または、関数の作成をクリックします。
  5. Node.jsまたはPythonのサンプルコードから始めるには、設計図をクリックし、Alexa Skills Kitのいずれかの設計図を選択してから設定をクリックします。
    • alexa-skill-kit-sdk-factskill
    • alexa-skill-kit-sdk-triviaskill
    • alexa-skills-kit-color-expert
    • alexa-skill-kit-sdk-howtoskill
    • alexa-skills-kit-color-expert-python

    Alexaの公式GitHubアカウントでこれらのサンプルの詳細を確認できます。

  6. 関数の名前を入力します。
  7. 関数のロールを選択します。ロールは、関数がアクセスできるAWSリソースを定義するものです。
    • 既存のロールを使用するには、既存のロールを選択でロールを選択します。
    • 新しいロールを作成するには、後述の関数の新しいロールを定義するを参照してください。
  8. ランタイムに使用する言語(Node.js、Java、Pythonのいずれか)を選択します。
    • Javaを選択する場合、Javaコードのzipファイルもアップロードする必要があります。
    • 関数をいったん保存すると言語を変更できなくなりますので注意してください。
    • 設計図を選択した場合、コードの言語はあらかじめ設定されています。
  9. 関数の作成をクリックします。
  10. こちらの手順に従い、関数のAlexa Skills Kitトリガーを設定します。
  11. こちらを参照して、コンソールで関数をテストします。

自分のコードを追加する準備ができたら、関数を編集して関数コードセクションまでスクロールします。ここから以下のいずれかを実行できます。

  • コードをLambdaコンソール内のコードエディターで直接記述します(Node.jsまたはPython)。
  • コードをオフラインで記述し、それをコピーしてLambdaコンソールエディターに貼り付けます(Node.jsまたはPython)。
  • コードをオフラインで記述し、zipファイルとしてLambda関数にアップロードします(C#、Node.js、Python、Java)。
  • Eclipse IDEとAWS Toolkit for Eclipseを使用します(Java)。詳細については、AWS Toolkit for Eclipseを使用したLambdaの使用を参照してください。

関数の新しいロールを定義する

ロールは、関数がアクセスできるAWSリソースを指定するものです。関数の設定時に新しいロールを作成するには、次の手順を実行します。

  1. ロールLambda関数のハンドラおよびロール内)で、テンプレートから新しいロールを作成を選択します。
  2. ロール名を入力します。
  3. ポリシーテンプレートリストで、シンプルなマイクロサービスのアクセス権限を選択します。

Alexa Skills Kitトリガーを設定する

関数を呼び出すために必要な呼び出し権限をAlexaに付与するため、関数には1つ以上のトリガーを設定する必要があります。

Alexa Skills Kitをトリガーとして追加した場合、関数でスキルIDの検証を有効にしてスキルID(アプリケーションIDとも呼ばれます)を提供することもおすすめします。これにより、Alexa Skills KitリクエストのスキルIDがトリガーに設定したスキルIDと一致する場合にのみ関数を呼び出せるようになります。

スキルIDの検証を使用する場合、サービスに対するリクエストの妥当性を検証するコードを含める必要はありません。検証できないスキルからのリクエストは関数を呼び出せません。

同じ関数を呼び出す複数のスキル

複数のスキルから同じLambda関数を呼び出す場合、複数のトリガーを設定できます。この場合、それぞれのトリガーを独自のスキルIDで設定する必要があります。

Alexa Skills Kitトリガーを追加する

トリガーを追加する前に、開発者コンソールからスキルIDをコピーします。

  1. developer.amazon.com/ja/alexaに移動します。
  2. あなたのAlexaコンソールSkillsをクリックします。開発者コンソールが開き、すでに作成したスキルがすべて表示されます。3. リストからスキルを見つけます。IDはスキル名の下に表示されます。

スキルIDを取得したら、トリガーを関数に追加します。

  1. AWSマネジメントコンソールにログインして、AWS Lambdaに移動します。
  2. リストで自分の関数をクリックして、設定の詳細を開きます。
  3. 設定ページにいることを確認します。
  4. Designerセクションのトリガーの追加で、Alexa Skills Kitをクリックしてトリガーを選択します。
  5. トリガーの設定で、スキルID検証有効を選択します。
  6. スキルIDボックスにスキルIDを入力します。
  7. 追加をクリックします。
  8. 保存をクリックして変更を保存します。

悪意のある呼び出し元から関数を保護するために、呼び出し権限をAlexaのみに制限し、スキルID検証を有効にすることを強くおすすめします。

Alexa Skills Kitトリガーを削除する

Lambdaコンソールで、関数からトリガーを削除できます。これにより、トリガーに含まれるすべてのスキルIDのスキルID検証も削除されます。

  1. AWSマネジメントコンソールにログインして、AWS Lambdaに移動します。
  2. リストで自分の関数をクリックして、設定の詳細を開きます。
  3. 設定ページにいることを確認します。関数の既存のトリガーは、ページ上部のDesignerセクションに表示されます。
  4. DesignerセクションのAlexa Skills Kitボックスをクリックして、スキルに追加されているAlexa Skills Kitトリガーを表示します。ページ下部のAlexa Skills Kitセクションに表示されます。
  5. 各トリガーの横にある削除ボタンをクリックして削除します。
  6. 保存をクリックして変更を保存します。

既存のトリガーを変更する

Lambda関数の既存のトリガーを編集することはできません。トリガーを変更する(スキルIDの追加や変更など)には、古いトリガーを削除してから新しいトリガーを追加します。

AWS CLIまたはLambda APIを使用してトリガーを設定する

AWS Lambdaでは、Lambda関数の管理にAPIコマンドラインインターフェース(CLI)の両方を利用できます。これらのツールを使用して、Alexa Skills Kitトリガーの追加や変更を行うこともできます。また、これらのツールでは関数の呼び出しに必要な権限をAlexa Skills Kitに付与するリソースベースのポリシーを追加できます。

Alexa Skills Kitトリガーには、以下を指定する必要があります。

  • Actionにはlambda:InvokeFunctionを指定します。
  • Principalにはalexa-appkit.amazon.comを指定します。
  • EventSourceTokenにはスキルのIDを指定します。

たとえば、このCLIコマンドではLambda関数hello_worldにトリガーを追加します。

aws lambda add-permission
    --function-name hello_world
    --statement-id 1
    --action lambda:InvokeFunction
    --principal alexa-appkit.amazon.com
    --event-source-token amzn1.ask.skill.xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

APIとCLIの詳細については、AddPermissionadd-permissionを参照してください。

APIまたはCLIで追加されたトリガーは、他のトリガーと同様Lambdaコンソールに表示されます。

スキルIDの検証を無効にする

スキルIDの検証が完全に不要な場合は、使用しないように関数を設定できます。たとえば、テスト目的で同じ関数を呼び出す大量のスキルがある環境では、検証をオフにすることができます。ただしその場合でも、スキルの公開前に再度検証を有効にされることをおすすめします。

LambdaコンソールでスキルIDの検証を無効にするには以下の手順を実施します。

  1. スキルIDの検証を使うよう設定した既存のトリガーをすべて削除します。
  2. 上記を参照して新しいAlexa Skills Kitトリガーを追加し、スキルID検証無効を選択します。

Lambda APIまたはCLIでスキルIDの検証を無効にするには以下の手順を実施します。

  1. スキルIDの検証を使うよう設定した既存のトリガーをすべて削除します。APIとCLIの詳細については、RemovePermission(API)とremove-permission(CLI)を参照してください。
  2. 関数の呼び出しに必要な権限をAlexa Skills Kitに付与するリソースベースのポリシーを追加します。ただし、EventSourceTokenは設定しません。

たとえば、このCLIコマンドではLambda関数hello_worldにトリガーを追加しますが、スキルID検証は含まれません。

aws lambda add-permission
    --function-name hello_world
    --statement-id 1
    --action lambda:InvokeFunction
    --principal alexa-appkit.amazon.com

Lambda APICLIの使用方法の詳細については、AWSのドキュメントを参照してください。

後でスキルIDの検証を再度有効にしたい場合(スキルの公開前を推奨します)、EventSourceTokenを含まないトリガーをすべて削除してからスキルIDを含む新しいトリガーを追加します。

コンソールでLambda関数をテストする

Lambdaコンソールで、Alexaから送信されたリクエストと同様の形式のサンプルJSONイベントを送信することにより、Lambda関数を手動でテストすることができます。コンソールには、テスト用にサンプルイベントが提供されています。これらのイベントをひな形として使用し、Alexaサービスから自分の関数に送信されたリクエストを表すように変更します。また、AWS CLIでもLambda関数にイベントを送信することができます。

Lambdaコンソールは関数のトリガーの条件を確認しません。そのため、テストイベントでスキルID検証を使用している場合に一致するスキルIDを持つ必要はありません。

JSONインターフェースの詳細については、カスタムスキルのJSONインターフェースのリファレンスを参照してください。

関数をテストするには、新しいテストインベントを作成する必要があります。

  1. 関数リストで、関数名をクリックして関数の詳細を開きます。
  2. 画面右上隅で、テストイベントの選択ドロップダウンリストをクリックし、テストイベントの設定をクリックします。
  3. 新しいテストイベントの作成を選択してから、イベントテンプレートリストからサンプルのAlexaリクエストを1つ選択します。
    • Alexa Start Session
    • Alexa Intent(サンプルが複数あります)
    • Alexa End Session
  4. イベント名を入力します。
  5. 作成をクリックします。
  6. メイン関数の設定ページで、イベントを選択してテストボタンをクリックします。

関数に異なるリクエストを送信するテスト用に複数のイベントを設定できます。

関数を実行すると、関数から返された応答がJSON形式で実行結果セクションに表示されます。サンプルイベントボックスに貼り付けたリクエストに適切な応答が表示されるはずです。たとえばLaunchRequestの場合、alexa-skills-kit-color-expert設計図から作成された関数が以下のような応答を返します。

{
  "version": "1.0",
  "sessionAttributes": {},
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "text": "Alexa Skills Kitサンプルへようこそ。「お気に入りの色は赤」などと言ってお気に入りの色を教えてください"
    },
    "card": {
      "type": "Simple",
      "title": "SessionSpeechlet - ようこそ",
      "content": "SessionSpeechlet - Alexa Skills Kitサンプルへようこそ。「お気に入りの色は赤」などと言ってお気に入りの色を教えてください"
    },
    "reprompt": {
      "outputSpeech": {
        "type": "PlainText",
        "text": "「お気に入りの色は赤」などと言ってお気に入りの色を教えてください"
      }
    },
    "shouldEndSession": false
  }
}

ログ出力セクションに、コードが生成したログメッセージが表示されます。サンプルは、リクエストの種類ごとにログメッセージを書き込むため、以下のように表示されるはずです。

2015-05-18T23:53:22.357Z    0f885f98-fdb9-11e4-80af-1b9f8363b496    onIntent requestId=amzn1.echo-api.request.6919844a-733e-4e89-893a-fdcb77e2ef0d, sessionId=amzn1.echo-api.session.abeee1a7-aee0-41e6-8192-e6faaed9f5ef

カラーエキスパート設計図のサンプル対話モデル

alexa-skills-kit-color-expert設計図とalexa-skills-kit-color-expert-python設計図のどちらかを使用してLambda関数を作成したら、Alexaが使えるデバイスとテストページのどちらかを使用してサンプルスキルをテストすることができます。これには、新しいスキルを作成してスキルに対話モデルを指定する必要があります。対話モデルのJSONをスキルに直接コピーできます。

  1. 新しいスキルを作成し、対話モデルとしてカスタムを選択します。
  2. カスタム > 対話モデル > JSONエディターに移動します。
  3. デフォルトのコードを削除し、以下のJSONを貼り付けてから、モデルを保存モデルをビルドをクリックします。
  4. カスタム > エンドポイントに移動し、AWS Lambda ARNを選択してから、Lambda関数のARMをデフォルトの地域ボックスに入力または貼り付けます。

以下はJSONバージョンの対話モデルです。

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "カラーエキスパート",
      "intents": [
        {
          "name": "MyColorIsIntent",
          "slots": [
            {
              "name": "Color",
              "type": "LIST_OF_COLORS"
            }
          ],
          "samples": [
            "お気に入りの色は{Color}"
          ]
        },
        {
          "name": "WhatsMyColorIntent",
          "slots": [],
          "samples": [
            "私のお気に入りの色は何",
            "私のお気に入りの色は何でしょう",
            "私の色は何色",
            "私の色は何",
            "私の色は",
            "お気に入りの色",
            "私の色を教えて",
            "お気に入りの色を教えて",
            "私のお気に入りの色を教えて",
            "私の色を聞かせて",
            "私の色はどの色",
            "お気に入りの色は何",
            "はい",
            "うん",
            "いいよ",
            "おねがい"
          ]
        },
        {
          "name": "AMAZON.HelpIntent",
          "samples": []
        }
      ],
      "types": [
        {
          "name": "LIST_OF_COLORS",
          "values": [
            {
              "name": {
                "value": "緑"
              }
            },
            {
              "name": {
                "value": "赤"
              }
            },
            {
              "name": {
                "value": "青"
              }
            },
            {
              "name": {
                "value": "オレンジ"
              }
            },
            {
              "name": {
                "value": "金"
              }
            },
            {
              "name": {
                "value": "銀"
              }
            },
            {
              "name": {
                "value": "黄色"
              }
            },
            {
              "name": {
                "value": "黒"
              }
            },
            {
              "name": {
                "value": "白"
              }
            }
          ]
        }
      ]
    }
  }
}

Lambdaと一緒に使用可能なその他のNode.jsサンプルとJavaサンプルについては、以下を参照してください。