Amazon Echo Dotで物忘れを克服する

こんにちは！
Leverages新卒エンジニアの[TTCMN](https://qiita.com/TTCMN)です。

この記事は[Leverages Advent Calender 2017](https://qiita.com/advent-calendar/2017/engineer)の17日目の記事です。
最近Amazon Echo Dotを買ったので、軽く遊んでみた話を記事にします。
業務とは全然関係ない話ですが、普段の生活を簡単に、少しだけ便利にするお話です。
カレンダーも後半に差し掛かったくらいですので箸休め的な感じで聞いていただければと思います。

## Amazon Echoシリーズとは
11月15日に日本で発売が開始されたAmazonのスマートスピーカー。購入するためにはAmazonに招待メールをリクエストし、Amazonから招待メールが届いたら購入できる、という形になってます。自分は11月9日にリクエストを送りましたが、招待メールが来たのは12月6日でした...。ネット上でも招待が来ない人が結構いたっぽくて中々すぐには買えない感じでした。
ちなみに何故Google HomeなどではなくAmazon Echoシリーズにしたのかというと、プライム会員かつ11月15日までに申し込めば、一番安い[Amazon Echo Dot](https://www.amazon.co.jp/Amazon-Echo-Dot-New%E3%83%A2%E3%83%87%E3%83%AB-%E3%80%81%E3%83%96%E3%83%A9%E3%83%83%E3%82%AF/dp/B072B5BTLK/ref=sr_1_1?ie=UTF8&qid=1513491581&sr=8-1&keywords=amazon+echo+dot)は2000円引きの3,980円で購入できたから、ただそれだけです。

## Skill開発について
Amazon EchoシリーズはAlexaというAIアシスタントを用いて色々な機能（スキル）を実現しています。スキルを追加することで天気を教えてくれたり、音楽を流したりしてくれます。
このSkillは自分でも開発可能で、結構ドキュメントやチュートリアルも豊富です。
今回は下記のチュートリアルを少し変更するだけで、日常の忘れ物を無くす試みをします。

・[Alexaスキル開発トレーニング](https://developer.amazon.com/ja/alexa-skills-kit/training/building-a-skill)

## 最近の悩み
日常的に忘れ物には気をつけていても、ついうっかり忘れてしまうモノってありませんか？
僕の場合、
・社員証（持ってるのが当たり前になってるので鞄を変えたりすると忘れる）
・替えの靴下（ジムに行くときに本当によく忘れる）
この2つをよく忘れます。
なので出かける前にAlexaに注意してもらいましょう。

## 開発の流れ
今回はAlexaスキル開発トレーニングの第1回の内容に沿って開発しました。基本的にはこの内容通りに進めればちゃんと動くので、変更した点やちょっと気をつけるところを書いていきます。

### スキル情報の設定
ここではスキルの種類や使用する言語などを設定します。
チュートリアルでは宇宙の豆知識を教えてくれるスキルでしたが今回は忘れ物を教えてほしいので呼び出し名は「忘れ物」に設定しました。

### 対話モデルの設定
ここではユーザーの音声に対する設定を行います。
実際にたくさんの人に使ってもらうスキルを作る場合はユーザーが使いそうな言葉をできるだけたくさん網羅する必要がありますが、今回は私用のため簡単に自分が使いそうな単語を設定しました。

```GetNewFactIntent 忘れ物
GetNewFactIntent 忘れ物を教えて
GetNewFactIntent 忘れ物を開いて
GetNewFactIntent 忘れ物リストを教えて
GetNewFactIntent 持ち物
GetNewFactIntent 持ち物を教えて
GetNewFactIntent 持ち物リストを教えて
```

### AWS Lambdaの設定
Alexaスキルを実行するためにLambdaを使用します。Lambdaでは実行するプログラムを「関数」という単位で管理するのですが、チュートリアルから以下のコード（一部）がダウンロードできます。

```index.js
'use strict';
var Alexa = require('alexa-sdk');

//=========================================================================================================================================
//TODO: このコメント行より下の項目に注目してください。
//=========================================================================================================================================

//Replace with your app ID (OPTIONAL).  You can find this value at the top of your skill's page on http://developer.amazon.com.  
//Make sure to enclose your value in quotes, like this: var APP_ID = "amzn1.ask.skill.bb4045e6-b3e8-4133-b650-72923c5980f1";
var APP_ID = undefined;

var SKILL_NAME = "豆知識";
var GET_FACT_MESSAGE = "知ってましたか？";
var HELP_MESSAGE = "豆知識を聞きたい時は「豆知識」と、終わりたい時は「おしまい」と言ってください。どうしますか？";
var HELP_REPROMPT = "どうしますか？";
var STOP_MESSAGE = "さようなら";

//=========================================================================================================================================
//「TODO: ここから下のデータを自分用にカスタマイズしてください。」
//=========================================================================================================================================
var data = [
    "水星の一年はたった88日です。",
    "金星は水星と比べて太陽より遠くにありますが、気温は水星よりも高いです。",
    "金星は反時計回りに自転しています。過去に起こった隕石の衝突が原因と言われています。",
    "火星上から見ると、太陽の大きさは地球から見た場合の約半分に見えます。",
    "木星の<sub alias='いちにち'>1日</sub>は全惑星の中で一番短いです。",
    "天の川銀河は約50億年後にアンドロメダ星雲と衝突します。",
    "太陽の質量は全太陽系の質量の99.86%を占めます。",
    "太陽はほぼ完璧な円形です。",
    "皆既日食は一年から二年に一度しか発生しない珍しい出来事です。",
    "土星は自身が太陽から受けるエネルギーの2.5倍のエネルギーを宇宙に放出しています。",
    "太陽の内部温度は摂氏1500万度にも達します。",
    "月は毎年3.8cm地球から離れていっています。"
];
//=========================================================================================================================================
//この行から下のコードに変更を加えると、スキルが動作しなくなるかもしれません。わかる人のみ変更を加えてください。  
//=========================================================================================================================================
exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.APP_ID = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();
};
...
```
親切ですね。
今回は決まった言葉を返すだけなので、以下のように自分の状況に合わせてカスタマイズすればOKです。簡単...!

```index.js
'use strict';
var Alexa = require('alexa-sdk');

//=========================================================================================================================================
//TODO: このコメント行より下の項目に注目してください。
//=========================================================================================================================================

//Replace with your app ID (OPTIONAL).  You can find this value at the top of your skill's page on http://developer.amazon.com.  
//Make sure to enclose your value in quotes, like this: var APP_ID = "amzn1.ask.skill.bb4045e6-b3e8-4133-b650-72923c5980f1";
var APP_ID = undefined;

var SKILL_NAME = "忘れ物";
var GET_FACT_MESSAGE = "お出かけですか？";
var HELP_MESSAGE = "忘れ物を聞きたい時は「忘れ物」と、終わりたい時は「おしまい」と言ってください。どうしますか？";
var HELP_REPROMPT = "どうしますか？";
var STOP_MESSAGE = "さようなら";

//=========================================================================================================================================
//「TODO: ここから下のデータを自分用にカスタマイズしてください。」
//=========================================================================================================================================
var data = [
    "社員証と替えの靴下は持ちましたか？"
];
```
### ちょっと注意点
ダウンロードしたzipファイルを展開し、上記のようにindex.jsを変更するだけでいいのですが、そのままFinder上で再度zip化すると後々エラーになります。なので、ターミナルなどを使ってindex.jsを含むディレクトリ内でzipコマンドを叩いてzip化します[[参考]](https://stackoverflow.com/questions/41750026/aws-lambda-error-cannot-find-module-var-task-index)。

## たったこれだけ
以上が主に加えた修正点で、あとはチュートリアルどおりに行えば動きます。
「Alexa、忘れ物を開いて」(若干違和感ですが)
などと話しかけると、
「お出かけですか？社員証と替えの靴下は持ちましたか？」
と返してくれます。

## 今後
実際、持ち物をAlexaに聞くのを覚えてたら、そもそも忘れ物しないわけなので出かける前に自動的に実行できるようにしたいですね。これは今後アップデートしようと思います。

## まとめ
以上のように、リクエストに対してレスポンスが決まってるスキルの場合は簡単に作成することができました。
リクエストの言葉によってレスポンスを変えたりもできるので、色々遊べそうですね。


## 参考
Alexaの基本的な仕組みや他に詰まった部分は以下の記事を参考にしました。

- [Amazon Echo (Alexa) のSkillの開発に必要な基本概念を押さえる
](https://qiita.com/chroju/items/3f30fe424df36e4b4d80)

- [開発中のAlexaスキルを実機テストする方法](https://qiita.com/hayao_k/items/a13b0c9327c49934eda3)

## おまけ
今回Lambdaの設定をしようとしてAWSにログインしたらアカウントが停止してました。
昔遊びで使ったインスタンスを停止し忘れていて、いつのまにか料金発生していたようですが、ずっと支払いのメールに気づかなかったのが原因...6000円...orz