Amazon Alexa Skills Kitを調べてみる


先日AWSで公開されたBlogで興味深いエントリーがありました。

「[Create New Voice-Driven Capabilities for Alexa with AWS Lambda](https://aws.amazon.com/jp/about-aws/whats-new/2015/06/create-new-voice-driven-capabilities-for-alexa-with-aws-lambda/)」
TechCrunchの紹介記事はこちら
[Amazon、AlexaとEchoをアンバンドル、それぞれをサードパーティーに公開―1億ドルの支援ファンドも](http://jp.techcrunch.com/2015/06/26/20150625amazon-unbundles-alexa-virtual-assistant-from-echo-with-new-dev-tools/)

先のブログで発表されたのは、以下の3つのこと。

* [Alexa Skills Kit](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit)
* [Alexa Voice Services](https://developer.amazon.com/public/solutions/alexa/alexa-voice-service)
* [1億ドルのファンド立ちあげ](https://developer.amazon.com/appsandservices/solutions/alexa/alexa-fund)

今回はこの内の[Alexa Skills Kit](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit)について、調べてみた。

## そもそもAlexaって何って？
Alexaは[Amazon Echo](http://www.amazon.com/gp/product/B00X4WHP5E/)に採用されているクラウドベースの音声認識サービスです。

## どのようにしてユーザーがAlexa Skillを使うか
[Getting Started with the Alexa Skills Kit](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/getting-started-guide)の図によれば、ユーザーが「Alexa, ask Greeter to say hello world.」と質問すると、Alexaがこの文脈を以下のように解析します。

* `Alexa` はセッションの開始を意味します
* `ask 〜1〜 to 〜2〜`は、Alexaがサポートしているフレーズの文脈
* `〜1〜`には`invocation name`と呼ばれる機能を識別する名称が入る
* `〜2〜`は`invocation name`という機能に対して渡される質問やコマンド

このように、Alexaが対応しているフレーズに沿って話しかけることで、特定の機能に対して指示をだすことが出来ます。

## Amazon Alexa Skills Kitはどのように使うか

### Lambdaファンクションの作成
発表ではLambdaを使えるということだったので、こちらのドキュメントを参考に進めます
[Developing an Alexa Skill as a Lambda Function](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-an-alexa-skill-as-a-lambda-function)

Lambdaファンクションを`us-east-1`に作成します。
（Amazon Alexa Skillsが対応しているリージョンは`us-east-1`だけです）
作成するLambdaファンクションの`Code Template`は`Alexa Skills Kit Color Expert`を選択します。
![スクリーンショット 2015-06-28 22.13.59.png](https://qiita-image-store.s3.amazonaws.com/0/36184/9b01ede5-6538-acc5-d3a0-1776f7dc349d.png "スクリーンショット 2015-06-28 22.13.59.png")

Lambdaファンクションの編集画面で`Sample Event`としてドロップダウンに`Alexa`用のサンプルが３つ追加されています。
![スクリーンショット 2015-06-28 22.23.13.png](https://qiita-image-store.s3.amazonaws.com/0/36184/97994a26-9f54-682b-7a5a-825b5f65e8e6.png "スクリーンショット 2015-06-28 22.23.13.png")

Sample Eventで`Alexa Intent - MyColorls`を実行してみます。

```
  "request": {
    "type": "IntentRequest",
    "requestId": "request5678",
    "intent": {
      "name": "MyColorIsIntent",
      "slots": {
        "Color": {
          "name": "Color",
          "value": "blue"
        }
```
サンプルのJSONでは、request typeが`IntentRequest`となっているので、ファンクションのソースを覗くと、以下の判定によりonIntentが呼び出されるのがわかります。

```
}  else if (event.request.type === "IntentRequest") {
  onIntent(event.request,
           event.session,
           function callback(sessionAttributes, speechletResponse) {
              context.succeed(buildResponse(sessionAttributes, speechletResponse));
  });
} else if (event.request.type === "SessionEndedRequest") {

```

onIntentの中では、Sample Eventで指定されているintent nameの`MyColorIsIntent`が実行されるようになっています

```
function onIntent(intentRequest, session, callback) {
    console.log("onIntent requestId=" + intentRequest.requestId
                + ", sessionId=" + session.sessionId);

    var intent = intentRequest.intent,
        intentName = intentRequest.intent.name;

    // Dispatch to your skill's intent handlers
    if ("MyColorIsIntent" === intentName) {
        setColorInSession(intent, session, callback);
    } else if ("WhatsMyColorIntent" === intentName) {
```

setColorInSessionの中では、Sample Eventで指定されている、slots Colorがある場合は、`I now know your favorite color is〜`とEventで指定した色が含まれた返事が生成されます。

つまり、Alexaに対して`Alexa, my favorite color is blue`と問いかけるとSample EventのようなデータがLambdaファンクションに渡されてきます。
Lambdaで処理した結果、`I now know your favorite color is blue. You can ask me your favorite color by saying, what's my favorite color?`が呼び出し元（Amazon Echoなど）に返されます。

### Alexa Skillsを登録する

実際に作成したLambdaファンクションをAmazon Echoから実行するには、Alexa Skillsを登録する必要があります。
Alexa Skillsを作るには[developer portal](https://developer.amazon.com/home.html)にアカウントが作られている必要があります。


[ダッシュボードのAlexa](https://developer.amazon.com/edw/home.html#/)から`Add a New skill`ボタンをクリックします。
![スクリーンショット 2015-06-28 21.48.21.png](https://qiita-image-store.s3.amazonaws.com/0/36184/e4bca399-f1dd-0e65-5704-d3554912d250.png "スクリーンショット 2015-06-28 21.48.21.png")

Skillの情報を入力します![スクリーンショット 2015-06-28 22.01.43.png](https://qiita-image-store.s3.amazonaws.com/0/36184/abebac5e-4f4e-ec92-4f09-c98581d0f69b.png "スクリーンショット 2015-06-28 22.01.43.png")

* `Name`：Echo Appに表示される名称
* `Invocation Name`：Alexaに対して実行させる機能を識別するための名称
  * 名称は重複してはなりません。[ガイドライン](https://developer.amazon.com/appsandservices/solutions/alexa/alexa-skills-kit/docs/choosing-the-invocation-name-for-an-alexa-skill)
* `Version`：バージョン
* `Endpoint`：LambdaファンクションのARNを入力します

Skillが登録されるとApplication IDが発行されるので、このIDをLambdaファンクションに書きます。
さっきのサンプルはLambda上で動かすだけだったので、ソース上でコメントアウトされていましたが、実際に外部から呼び出す場合は、Application IDが必須となります。

```
exports.handler = function (event, context) {
    try {
        console.log("event.session.application.applicationId=" + event.session.application.applicationId);

        /**
         * Uncomment this if statement and populate with your skill's application ID to
         * prevent someone else from configuring a skill that sends requests to this function.
         */
        /*
        if (event.session.application.applicationId !== "amzn1.echo-sdk-ams.app.[unique-value-here]") {
             context.fail("Invalid Application ID");
         }
        */

```

これでテスト用のAmazon Echoを登録して、実行できるようになるみたいですが、、、
Amazon Echoを持っていないので、試すことが出来ません。。
ほしいな〜〜


## あとがき

Amazon Alexaを利用することで、音声から新しいサービスを利用できるようになるわけですが、現状はAmazon EchoとEcho Appしか対応していません。
しかし、今回の発表では音声入力するデバイス側に対してもAlexa Voice Servicesとして提供されるので、Alexaを使うデバイスと、Alexaを介してオリジナルのサービスを提供する事が可能な環境が出来上がります。

新しいスタートアップが登場して、今までにないサービスが提供されるかもしれませんね。