Alexa Skill 開発してみた

mediba advent calendar 2017 22日目担当の山子澤です。
インフラストラクチャー部で主にAWSをやってます。

今回は「Alexa Skill Kit」を使って簡単な占いSkillを作ってみたいと思います。
ちなみに書いている時点で私はAmazon Echo持っていません。
リクエスト出してますが返信メールがきてないので開発だけでも進めておきましょう。

### 今回必要なもの
- Amazon Developerアカウント
    - アプリ登録をします。
    - アカウント無い方はこちらから(https://developer.amazon.com/ja/)
- AWSアカウント
    - Lambdaでプログラムを書きます。
    - アカウント無い方はこちらから(https://aws.amazon.com/jp/register-flow/)

### Amazon Developerでアプリ登録をする

- Amazon Developerアカウントがあるのであればログインして
以下のリンクからスキルを開発するを押しアプリを登録していきます。

https://developer.amazon.com/ja/alexa-skills-kit

<img width="1099" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/148125/8a5b7c9e-2d7d-e006-8eba-aa74bc8a4a01.png">

今回は１２星座うらないをつくりたいので以下のように
スキル名、呼び出し名を入力して保存をおしてください。
ここの時点でアプリ登録されます。


![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3134383132352f63646137313637342d393063642d303161332d666233652d3035626536373937623864392e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/148125/408748ca-849a-76f3-b3e5-d36a683fb46a.png)

次はアプリに必要なデータを入力していきます。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3134383132352f38353564353633612d363736362d303932662d623764342d6261373032636536376536352e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/148125/a3119c00-69fb-9806-c7f1-9505b5d27e33.png)


インテントスキーマに以下のデータを入力してください。

```
{
  "intents": [
    {
      "slots": [
        {
          "name": "SlotName",
          "type": "SlotList"
        }
      ],
      "intent": "TestIntent"
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    }
  ]
}
```

カスタムスロットタイプ に 「SlotList」
値を入力のところには以下のデータを入れます。
追加ボタンを押すのをわすれないでください。

```
おひつじ座
おうし座
ふたご座
かに座
しし座
おとめ座
てんびん座
さそり座
いて座
やぎ座
みずがめ座
うお座
```

サンプル発話のところには以下のデータを入力してください。
終わったら次へをおしてください。

```
TestIntent {SlotName} の 運勢 を 教えて
TestIntent {SlotName} の 運勢 は
```

イメージとしては
「サンプル発話」で呼び出し方法を定義して
「インテントスキーマ」でアプリケーションとデバイスを橋渡しする部分の定義、
「カスタムスロットタイプ」ではインテントスキーマで定義したスロットと呼ばれるものの種類の定義をしています。

スロットを使うと呼び出し方法を増やせますし
その部分をLambdaで変数として受け取ることができます。


次に必要になるのはAWS LambdaのARN(Amazon リソースネーム)です。
なのでAWSにログインしてLambdaを作っていきます。
その前にプログラム(Node.js 6.10)を書いてアップロードできるように準備します。

ローカル(私はMac)で以下ように作りました。


```
$ mkdir ~/Desktop/TestSkill
$ cd ~/Desktop/TestSkill
$ npm install --prefix=~/Desktop/TestSkill alexa-sdk
$ vim index.js
```

index.jsは以下になります。


```index.js

"use strict";
const Alexa = require('alexa-sdk');

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.registerHandlers(handlers);
    alexa.execute();
};

var handlers = {

    // 起動時
    'LaunchRequest': function () {
      this.emit('AMAZON.HelpIntent');
    },
    // 使い方
    'AMAZON.HelpIntent': function () {
        this.emit(':tell', '今日の運勢を占います。たとえば、テストでいて座の運勢はと聞いてください');
    },
    // 実行部分
    'TestIntent': function () {
        var moji = "";
        var slot = this.event.request.intent.slots.SlotName.value;
        
        if(slot == "やぎ座") {
          moji = "かなりいいです";
        }else if(slot == "てんびん座") {
          moji = "わるいです";
        }else if(slot == "みずがめ座") {
          moji = "いいです";
        }else if(slot == "いて座") {
          moji = "かなりわるいです";
        }else if(slot == "おとめ座") {
          moji = "いいです";
        }else if(slot == "うお座") {
          moji = "わるいです";
        }else if(slot == "ふたご座") {
          moji = "いいです";
        }else if(slot == "おうし座") {
          moji = "かなりわるいです";
        }else if(slot == "おひつじ座") {
          moji = "いいです";
        }else if(slot == "しし座") {
          moji = "わるいです";
        }else if(slot == "さそり座") {
          moji = "かなりいいです";
        }else if(slot == "かに座") {
          moji = "わるいです";
        }

        // 返す
        var message = '今日の' + slot + 'の運勢は' + moji;
        this.emit(':tell', message);
        console.log(message);
    }
};

```

zipにしてLambdaにアップロードできる準備をします。

```
zip -r TestSkill.zip index.js node_modules
```

###  Lambdaを作る

Amazon Developerの管理画面から一旦離れて
AWSにログインしてLambdaを作って行きます。

<img width="1058" alt="スクリーンショット_2017-12-19_14_47_03.png" src="https://qiita-image-store.s3.amazonaws.com/0/148125/0291cadb-cd3b-b95c-c75d-4261700c37e8.png">


関数名を「TestSkill」、
ランタイムを「Node.js 6.10」
ロールはなければ新規で作っても大丈夫です。

![スクリーンショット_2017-12-19_14_49_27.png](https://qiita-image-store.s3.amazonaws.com/0/148125/a75d2258-53fb-a631-eb2c-ed96935fcd52.png)

トリガーは 「Alexa Skill Kit」にして
zipのアップロードから先程作った「TestSkill.zip」を選択
保存でデプロイできます。

最後にARNをメモしてください。
Amazon Developerの管理画面から入力してアプリを紐付けます。

![スクリーンショット_2017-12-19_13_52_23.png](https://qiita-image-store.s3.amazonaws.com/0/148125/9b6ca8e5-c7e4-a879-7e6e-5d8c6f6cfbdf.png)

先程メモしておいたARNをAmazon Developerの管理画面に戻ってきて
入力して次へを押します。

![スクリーンショット_2017-12-19_14_55_05.png](https://qiita-image-store.s3.amazonaws.com/0/148125/5f5f277b-3d88-bdf5-1ef3-95f0f7cf1cc5.png)

### 最後にテスト

![スクリーンショット_2017-12-19_16_19_50.png](https://qiita-image-store.s3.amazonaws.com/0/148125/a2747332-ec29-1544-6449-74aaaf012c53.png)

「発話を入力してください」のところに「いて座の運勢は？」と入力して
 テストを呼び出すボタンを押すとサービスレスポンスを返します。

```
{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "ssml": "<speak> 今日のいて座の運勢はかなりわるいです </speak>",
      "type": "SSML"
    },
    "speechletResponse": {
      "outputSpeech": {
        "ssml": "<speak> 今日のいて座の運勢はかなりわるいです </speak>"
      },
      "shouldEndSession": true
    }
  },
  "sessionAttributes": {}
}
```

聴くを押すと音声を聴くこともできます。
音声でテストしたい場合は公式でサポートしているサイトがあるようですね。
https://echosim.io/

実機がないのでここまでとなりますが
私はLambdaを改造して占いサイトからデータを取るようにしてみました。
これで毎朝占いを気軽に聞けるはずです(実機はない。。。)

いろいろと便利に使えそうなのでアイディア次第で面白くなりそうです。