Amazon EchoのSkillで何かを作ってみて申請してみる

# Amazon EchoのSkillで何かを作ってみたい！(そして作ってみました！って言ってみたい)
先日届いたAmazon Echo Dot。
IFTTTを使用しての連携は[試してみた](https://qiita.com/ryo_naka/items/b6dc93c6f7c7fe94e8d0)ので、今度はSkillを作ってみることにしました。
ついでに申請までやってみました。



## 〇Amazon EchoのSkillの概念とか作り方とか
以下がすごく参考になりました。
・Amazon Echo (Alexa) のSkillの開発に必要な基本概念を押さえる
https://qiita.com/chroju/items/3f30fe424df36e4b4d80

ぶっちゃけこのページをしっかりと読み込んでTry&Errorで試してみれば作成できます。
ただ、それだと終わってしまうので、いろいろ試してみた結果を以下に書き残しておくことにする。


##〇目的
とりあえずAlexaのSkillを作成して申請してみる。

##〇作る人の前提
普段いろいろと開発をしてはいるが、Lambdaとかは全然使ったことない。
JavaScriptはかけるけど、Node.jsは触ったことない。

##〇準備
###・[developer.amazon.com]へのデベロッパー登録。
日本でEchoを購入している時点でco.jpへのアカウントはあると思われるが、
Skillを開発しようと思ったら[developer.amazon.com]のアカウントが必要とのこと。
https://developer.amazon.com/ja/

###・AWSアカウント
Skillを作成するだけなら不要だが、Skillで実際に動作する処理を実装する際には
AWS Lambdaを使用するのが連携的に一番楽そうなので。

>AWS Lambda とは
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html

アカウントが無ければ作っちゃいましょう。
Lambdaでちょっとしたスキルを使うぐらいであれば、無料枠の中におさまります(多分)

https://developer.amazon.com/ja/docs/custom-skills/host-a-custom-skill-as-an-aws-lambda-function.html
>ほとんどの開発者にとって、Alexaスキルをサポートする関数にはLambda無料利用枠で十分です。毎月のリクエストが100万件まで無料になります。Lambda無料利用枠は自動的に期限が切れることはなく、永久に使用できることに注意してください。

###・アイデア
どんなことをさせようかをざっくりとでもいいので考えておきましょう。
Echoに呼びかけたら「〇〇」と返答するとかのレベルでもとりあえず大丈夫です。
※ちなみに自分は完全にノープランで始めたのでここのアイデア出しで時間がかかりましたし、最終的には家人のアイデアを流用しました。。。

##〇今回作成する処理の大きな流れ
Echo→[Skill]→Dev→[Lambda関数]→AWS Lambda


##〇Skill側の作成
#### developer.amazon.comに[サインイン](https://developer.amazon.com/ja/)
<img width="948" alt="00.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/e0949617-829e-716f-7c05-8573d03efd75.png">
※developer用にアカウントを作成したばかりならサインインしたままになっているかもしれませんが。

左にそれっぽいものがあるので押したくなりますが、それではなく右上の[Developer Console]を押下します。
<img width="948" alt="01.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/a12a471f-7809-2841-fdda-60075b644e1d.png">
※ここでもう一回サインインを要求されるかも。。

#### サインインしたらALEXAを選択。
<img width="688" alt="02.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/575b3202-5982-16c2-5710-3a67e7ba643a.png">

#### ALEXA Skills Kitを選択
<img width="614" alt="03.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/a44fb3bb-54ea-aa18-7eab-7bd9122a2b59.png">
※右側のはEchoではなくAPIを使ってスピーカーそのものを自作するときに使うサービスです。ラズパイ＋マイクで似たようなものが作れるんじゃないかな。。

#### 新しいスキルを追加する
<img width="942" alt="04.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/0ba670ad-bbdd-1e54-df04-03faba4bd6c9.png">
スキルを新規作成する際にはここから。

### スキル初期設定
<img width="765" alt="05.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/87f0c47d-2cff-3f63-59aa-4d10a1f49c48.png">
ここでSkillの情報を設定していきます。

スキルの種類：今回は[カスタム対話モデル]
言語：[Japanese]
スキル名：スキル一覧に表示される名称。
呼び出し名(Invocation name)：アレクサに対する起動フレーズ。
※グローバルフィールドの部分はとりあえず全部「いいえ」でOK
設定したら「保存」を押下して「次へ」。

### 対話モデル
<img width="770" alt="06.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/7501913c-d20e-90c5-c36c-32d1dfaee697.png">
この辺はベータ版と書かれているのですぐに参考にならなくなりますが。。。

一から作成するのは割とめんどくさいのでスキルビルダーを使用したほうが楽だと思います。

<img width="859" alt="07.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/fa521282-d4ee-290b-8729-aff87777f296.png">
ここで作成するのは[Intent]
>Invocation name：Classみたいなイメージ
>Intent：クラス内の関数
>Sample utterance：Intentに対する呼び出し方(どう呼びかけたらそのIntentが動作するか>というサンプル)
>Slot：Intentに対する引数。utteranceの中から指定した一部分を引数として取得できるような感じ。

#### Intentの作成
<img width="582" alt="08.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/df702aff-62de-7992-29e3-606a8dbf89fe.png">
適当にIntentの名前を決めちゃいます。
後で使うけど、だれかにみられるものでもないので自分がわかる名称にしておけばOK

#### Sample utteranceの作成
<img width="408" alt="09.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/d34c7f0b-f16d-c9cb-0476-83c98584ad54.png">
Intent名とは逆にここはちゃんと作りましょう。

#### モデルの構築
<img width="957" alt="10.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/0d6f595d-841a-ff85-ed06-fdb118e43515.png">
IntentやSample utteranceを作成したら、SaveとBuildを順番に。

#### 残りの設定
<img width="957" alt="10.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/463d84e2-e6fa-c140-1acb-6be3a0a511a0.png">
モデルの構築が終わったらConfigurationを押下して、さっきまでの画面に戻る。

### 設定
<img width="760" alt="11.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/aabf43b0-b306-57e2-00d0-43e5a73c8ba9.png">
ここでこのSkillの実処理への呼び出しを記載する。
HTTPでURLを指定することもできるようだが、APIなどを作成するのはめんどくさいので
今回はAWS Lambdaにて作成し連携させることにする。

そのため、ここで一回Skillの作成は中断して、ここからの呼び出しを処理する部分を作成する。

##〇Lambda側の作成
参考サイト
・https://developer.amazon.com/ja/docs/custom-skills/host-a-custom-skill-as-an-aws-lambda-function.html

今回はある程度のひな型が存在するものを流用するので
AWS Lambdaから「関数の作成」→「設計図」→「alexa-skill-kit-sdk-factskill」
の順で選択。
<img width="918" alt="12.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/0aebb0d0-383f-88af-14d2-8c4ed4a81629.png">


#### Lambda関数の情報を記載。
<img width="658" alt="13.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/c05471da-57f2-fd8f-a2c1-b4a54db37342.png">
ここで悩んだのがRoleの選択ですが、以下にシンプルマイクロサービスでいいよと書いているのでそれに従っておきます。
※プルダウンにはなぜか「シンプルなマイクロハーネスのアクセス権限」とありますが、たぶんこれのことなんでしょう。
https://developer.amazon.com/ja/docs/custom-skills/host-a-custom-skill-as-an-aws-lambda-function.html#define-new-role
>From the Policy templates list, select Simple Microservice permissions

#### 処理記述
この辺を修正します。
<img width="668" alt="14.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/e672292a-7762-5dbc-f1d2-d8a4913ec81c.png">

テンプレート上にて[GetNewFactIntent]となっている部分をSkill側にて自作したIntent名に変更します。
その下の処理も一緒に修正しておきます。

```
this.emit(':tell', "今日は大吉です。");
```

<img width="433" alt="15.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/9c45b49b-61e1-b9ae-36f3-c240473e2949.png">

これで[SampleTestIntent]として呼び出されたら、『「今日は大吉です。」としゃべってください』と返す処理ができました。

ただ、このままだとまだSkill側から呼び出せる状態になっていないので、設定を追加します。

<img width="826" alt="16.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/7a70f0dc-7723-f818-88fe-895d976d12c2.png">
設定のトリガーの追加で[Alexa Skills Kit]を選択。

<img width="829" alt="17.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/11e409f2-f5bc-349e-e308-4040745205ac.png">
トリガーの設定で「追加」を押下

これでSkill側からの呼び出しをこのLambda関数が受け付けられるようになりました。
逆に、Skill側にこのLambda関数を呼び出せるためのIDとして、ARNをコピペします。
<img width="522" alt="18.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/52fed5fd-a355-b0ba-e525-a81dc841ff4f.png">


##〇Skill側の残りの設定
####残りの設定の記載
<img width="601" alt="19.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/f22366c7-0f9a-e330-a9da-29e4ee63be9d.png">

#### テスト
<img width="761" alt="20.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/c9b01fcf-00e1-38e9-2526-6ae23d9ec8c2.png">
この画面で接続先に対していろいろなリクエストを送信することができるので、
想定通りのレスポンスが返ってくるかをテスト。
また、デベロッパーとEchoのアカウントが同一の場合はこのタイミングでスキルとして試すことができるようになっている。

**デベロッパーとEchoのアカウントが異なっている場合はベータテストのところから
対象アカウントのメールアドレスに対してベータテストの招待メールを送信してテストができるようになる。
が、ここのベータテストができるようになるためには「公開情報」なども埋めないといけないみたいなので、まだ実施できない。
※.comと.co.jpで同じアカウントにしていてもダメな場合があるので、
その時はこの手順でメールを送信して有効化するとテストできるようになる。**

ここでテストを実施して、どういう風なInvocation nameやSample utteranceがよいか修正。
また、単語として認識されづらいフレーズもあったりするので、
アプリの方の履歴画面などでどういう風な認識をされているかを確認しながらということになると思われる。

#### 公開情報
スキルの説明やアイコンなどを設定する。
アイコンについてはサイズを厳密に合わせていないと即エラーになるので、
ペイントなどでサイズを決めてから作成するのが一番簡単だと思われる。
※自分は適当な有りものの画像を使おうと思ったら余計に時間がかかりました。

#### プライバシーとコンプライアンス
このスキルがどんなスキルかを設定します。
<img width="608" alt="21.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/6ed27f77-0414-d3a0-b5cd-0eb208c60c78.png">

上記をすべて設定し、保存し終えたら、申請できるようになっていると思います。
また、それと同時にベータテストもできるようになっていると思います。
<img width="163" alt="22.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/2524578a-6d88-2d9a-5ee2-9f1d71bd8993.png">

テストしたいEcho端末に紐づいているアカウントに対してメールを送信すると、招待メールが送信され、それに従ってスキルを有効化すると端末で遊ぶことができるようになります。
正直、公開せずに遊ぶだけなのであればこれで十分な気もします。

##〇申請
ただし、今回の目的は申請なので、申請ボタンも押下。
申請すると対象Skillはその間編集できなくなる模様。
自動メールでチェックリスト的なものが送られてくるのでそれを改めて読んでみるのもいいかと。
どれくらいで申請結果が返ってくるのかわからないですが、返ってきたら別途報告予定。
※このまま申請が承認される気もしませんし。。

##〇Skillを作ってみた感想として
なんとなく流れは分かった気がします。
「Skill」そのものを作るということはさほど難しくはないのかなという印象。
ポイントはトリガーとなるInvocation nameやSample utteranceのフレーズ。
これをAlexaが認識してくれないとそもそも起動できない。
※いくつか試してみたが、一般的な名称じゃないと認識力は落ちるなという感じ。

逆にSkillに対するバックエンド処理。こっちはまあまあめんどくさいなという印象。
といっても、お決まりのものを作るだけならテンプレートがあるのですぐにできる。
ただ、何かをやらせたかったらNode.jsもしくはPythonで作成しないといけなく、
この辺はAWSのlambdaの使い方を把握していれば楽なんだろうなと思うが、自分にはまだまだか。

Skillに限らずLambdaでいろいろできるようになるといろんなことができそうだなという気も。


##〇今後
・もう少しいろいろと他サービスを呼び出せるようにしたい。
→SlackやMail送信に接続させたいところ。
→Lambdaではなく、GAS(Google App Script)を直接呼び出せばGmailぐらいは簡単にイケる？
・Slotも使用してみる。
・セッションを作成してのCall&Responseもそのうちやってみたい。