カスタムスキルを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など、複数の言語で記述されたコードをサポートします。一部の言語では、AWS Lambdaコンソールのインラインコードエディターでコードを編集できます。基本的なテストでは、LambdaコンソールでJSONリクエストを送信することにより、関数を手動で呼び出すことができます。

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

Lambda関数は、Alexaからスキルに送信されたリクエストを処理する必要があります。次の項目を参照してください。

カスタムスキル用のLambda関数は、任意のAWS Lambdaリージョンでホストできます。詳細についてはAWS Lambda関数に最適なリージョンを選択するを参照してください。

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

AWS Lambda関数に最適なリージョンを選択する

AWS Lambda関数を作成する際には、選択するリージョンについて考慮してください。ほとんどの場合、スキルで使用されるAWS Lambda関数を作成または変更するときは、一般的に推奨される以下のリージョンを使用する必要があります。最適な選択をすることで、Alexaとスキルサービス間のレイテンシーを減らすことができます。ただし、スキルがDynamoDB、Amazon S3、外部サービスなど、異なるリージョンでホストされている他のリソースを使用している場合、スキルの全体的なレイテンシーを減らすには、この表の推奨事項と異なる場合でも、それらのリソースに最も近いリージョンを選択することをお勧めします。Alexaとスキルサービスのレイテンシーを、スキルサービスと他のホストされているリソースのレイテンシーと比較してトレードオフを判断してください。利用可能なAWS Lambdaリージョンを参照し、AWS Lambda関数に対して選択するリージョンを決定します。

Alexaスキルサービスのリージョン AWSリージョンコード リージョン名
北米 us-east-1 米国東部(バージニア北部)
ヨーロッパまたはインド eu-west-1 欧州(アイルランド)
極東 us-west-2 米国西部(オレゴン)

利用可能なAWS Lambdaリージョン

利用可能なAWS Lambdaリージョンは以下のとおりです。これらのいずれもスキルのAWS Lambda関数に利用可能ですので、最適なリージョンを選択してください。

利用できるAWS Lambdaリージョン
米国東部(オハイオ) 欧州(フランクフルト) アジアパシフィック(香港)
米国東部(バージニア北部) 欧州(アイルランド) アジアパシフィック(ムンバイ)
米国西部 (北カリフォルニア) 欧州(ロンドン) アジアパシフィック(ソウル)
米国西部(オレゴン) 欧州(パリ) アジアパシフィック(シンガポール)
カナダ(中部) 欧州(ストックホルム) アジアパシフィック(シドニー)
南米(サンパウロ) 中東(バーレーン) アジアパシフィック(東京)

テンプレートを使用してLambda関数を作成する

Alexa Skills Kit SDK for NodeまたはAlexa Skills Kit SDK for Pythonを使用している場合、AWS Serverless Application Repositoryで提供されるテンプレートを使用して関数を作成できます。これにより、関数がAlexaと連携するために必要となる、次のリソースが自動的に作成されます。

  • Lambda関数。対応するGitHubリポジトリから開始用のサンプルコードが作成されます。これを使用して、サンプル機能を試すことができます。独自のコードで置き換えることもできます。
  • コードに必要なSDK依存関係。これにより、依存関係(node_modulesなど)を自分でアップロードする必要がなくなります。
  • 関数に必要な呼び出し許可をAlexaに付与するトリガー。
  • 関数のロール。ロールは、関数がアクセスできるAWSリソースを定義するものです。

Serverless Application Repositoryを使うと、デプロイするアプリケーションを見つけることができます。ここで言う「アプリケーション」とは、Lambda関数を作成するためのテンプレートのことです。

アプリケーションをデプロイして、AWS CloudFormationスタックでアプリケーションに関連付けられたリソースを作成します。デプロイすると、Lambda関数を正常に使用できます。この方法でLambda関数を設定する場合は、CloudFormationの詳細を理解する必要はありません。

Serverless Application Repositoryには現在、ASK SDK for Node v2およびASK SDK for Python用のアプリケーションが含まれています。

AWSのアカウントをまだお持ちでない場合は、まずアマゾンウェブサービスにアクセスしてアカウントを作成します。

これらのリンクのいずれかを使用して、Serverless Application RepositoryのAlexaサンプルのページを開きます。これらのいずれかを使用するには、リンクをクリックして、後述のアプリケーションをデプロイして関数を作成するの手順に従います。

Alexaサンプルを検索する

Serverless Application Repositoryで、Alexaサンプルを検索することもできます。

  1. AWSのアカウントをお持ちでない場合は、アマゾンウェブサービスにアクセスしてアカウントを作成します。
  2. AWSマネジメントコンソールにログインして、AWS Lambdaに移動します。
  3. 関数の作成をクリックします。
  4. Serverless Application Repositoryの参照を選択します。
  5. Public applicationsの下で、検索ボックスに「Alexa」と入力します。公式に提供されているリポジトリでは、カードの左下の提供者名が「Alexa Skills Kit」と表示されます。
  6. 使用するアプリの名前をクリックします。すると、アプリについての詳細ページが表示されます。作成されるリソースについての詳細は、「Template」で確認できます。
  7. 後述のアプリケーションをデプロイして関数を作成するの手順に従います。

アプリケーションをデプロイして関数を作成する

  1. デプロイするサーバーレスアプリケーションのページを開きます。提供リンクのいずれかを使用するか、またはリポジトリでサンプルを検索して参照することができます。
  2. コンソールの右上隅にある地域のドロップダウンリストをクリックし、利用可能なリージョンを1つ選択します。

    リージョンについてはAWS Lambda関数に最適なリージョンを選択するを参照してください。

  3. アプリケーションの設定セクションで、オプションとして、次のものを変更します。
    • アプリケーション名
    • SkillDescription
    • SkillFunctionName

    SkillDescriptionSkillFunctionNameが含まれていないテンプレートもあります。

    同じテンプレートを使って複数回デプロイすることができますが、毎回一意のアプリケーション名を使用する必要があります。

  4. ページ下部のデプロイボタンをクリックします。
  5. すべてのリソースのステータスがCREATE_COMPLETEに変わるのを待ちます。
  6. Lambdaコンソールのリソースの下でリンクをクリックして、新しく作成された関数を開きます。

以下のいずれかを実行できます。

Lambda関数を一から作成する

Lambdaコンソールを使用して、新しいLambda関数を一から作成することができます。ASK SDK for Node v2またはASK SDK for Pythonを使用しない場合には、この方法を使います。

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

  1. AWSのアカウントをまだお持ちでない場合は、アマゾンウェブサービスにアクセスしてアカウントを作成します。
  2. AWSマネジメントコンソールにログインして、AWS Lambdaに移動します。
  3. コンソールの右上隅にある地域のドロップダウンリストをクリックし、利用可能なリージョンを1つ選択します。

    リージョンについてはAWS Lambda関数に最適なリージョンを選択するを参照してください。

  4. まだLambda関数がない場合は、今すぐ始めるをクリックします。または、関数の作成をクリックします。
  5. 関数の名前を入力します。
  6. 関数のロールを選択します。ロールは、関数がアクセスできるAWSリソースを定義するものです。
    • 既存のロールを使用するには、既存のロールを選択でロールを選択します。
    • 新しいロールを作成するには、後述の関数の新しいロールを定義するを参照してください。
  7. ランタイムに使用する言語を選択します。Alexa Skills Kit SDKのいずれかを使用している場合には、Node、Python、またはJavaを選択します。Lambdaでサポートされている言語のリストについては、AWS LambdaドキュメントのAWS Lambdaランタイムを参照してください。
  8. 関数の作成をクリックします。

以下のいずれかを実行できます。

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

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

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

Lambda関数のコードを表示して編集する

コードを表示して編集するには、Designerの下で関数の名前をクリックして、関数コードセクションまでスクロールします。

ここから、選択したランタイムに応じて、次のいずれかを実行できます。

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

関数の作成に使用できるツールの詳細については、AWS LambdaドキュメントのLambda関数のコードを作成するを参照してください。

Lambda関数をスキルに接続する

関数をスキルに接続するには、スキルのエンドポイントフィールドを関数のAWS Lambda ARNに更新する必要があります。

  1. Lambda関数の右上隅に表示されているARNをコピーします。
  2. 開発者コンソールでスキルを開くか、または作成します。
  3. カスタム>エンドポイントに移動します。
  4. サービスのエンドポイントの種類で、AWS LambdaのARNを選択してから、Lambda関数のARNをデフォルトの地域ボックスに貼り付けます。

Lambda関数のトリガーを設定する

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

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

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

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

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

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

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

  1. 開発者コンソールを開き、スキルを作成していない場合は作成します。
  2. リストでスキルを見つけ、スキル名の下のスキルIDの表示をクリックします。ポップアップから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を指定します。
  • event-source-tokenにはスキルの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-nodejs-premium-facts-skillテンプレートから作成された関数が以下のような応答を返します。

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak>プレミアム豆知識サンプルへようこそ。ランダムに豆知識を聞く場合は、「豆知識を教えて」と言ってください。購入できるプレミアムカテゴリーを知りたい場合は、「何を買えるの」と言ってください。 ヘルプが欲しい場合は、「どうすればいいの」と言ってください。それでは何をしましょうか?</speak>"
    },
    "reprompt": {
      "outputSpeech": {
        "type": "SSML",
        "ssml": "<speak>すみません、わかりませんでした。何をしましょうか?</speak>"
      }
    },
    "shouldEndSession": false
  },
  "userAgent": "ask-node/2.3.0 Node/v8.10.0",
  "sessionAttributes": {}
}

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

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

セットアップできる追加のサンプルスキルについては、以下を参照してください。