【alexa カスタムスキル】アレクサに給食メニューを教えてもらう

## 概要
Amazon Echoに保育園の今日の給食を聞いてみます。
保育園でつかっているシステムではログイン後のカレンダー
で給食のメニューがみえるようになっているのでそれをひっぱってきてしゃべってもらいます。

## カスタムスキルの作りどころ
趣味で作るものとしては以下のようなものがよさそう
・スマホやアプリで確認できるけれどたびたび確認するほどでもない (でも、簡単に聞けるなら聞いておきたい)
・公式のカスタムスキルが提供されていない(提供されていればそれを入れればよい)
・普通にググってもでてこない(個人のログインが必要)

前までは月ごとに印刷されたメニューを配ってくれましたが
保育園でのシステム導入後配られなくなりました。
ログインして数ステップ遷移しないとみられないので、みないままの日が続いていました。
ログインしてスクレイピングするだけなので題材としてはお手頃と思います。


## Alexaのカスタムスキル登録
ほかのサイトでも紹介されているので詳細は省略
以下で、Amazon開発者の登録(AWSアカウントとは別)をして、Alexa Skills Kit開発者コンソールからカスタムスキルを作ります
https://developer.amazon.com/ja/alexa

実体はAWS Lambdaで作るのでここでは呼び出し名の登録などのみです。
エンドポイントにAWS LambdaのARNを入力する欄がありますが、ここはLambda作成後にあとで入力します

## AWS Lambda Fucntion作成
AWS ConsoleにログインしてLambdaを作成します。

Lambda > 関数 > 関数の作成 > 設計図 に
alexa-*
のテンプレートがいくつかあるので好きなのを選びます
pythonで作りたかったので
alexa-skills-kit-color-expert-python
を選択
Python2.7とありますが、python3.6でも問題なく動作します

```
def build_speechlet_response(title, output, reprompt_text, should_end_session):
def build_response(session_attributes, speechlet_response):
```
はそのまま使えるはずなので流用

Alexa skill kitのトリガーにスキルIDを入力する欄があるのでIDをコピペ
一度仮ビルドしたら、LambdaのARNをスキル登録の方にも登録
これであとは、Lambdaを修正すればテストできるようになります

### Pythonでのログイン～スクレイピング

ブラウザの操作を確認しながらrequestsとBeautifulSoap4を利用して実装します。
ひとまずローカルのJupyterNotebookで文字列を切り出せることを確認

ログイン情報は本当は、アカウントリンクを使ってalexaアプリ上で入れるのがよいのだけど
個人用プロトタイプなのでひとまず埋め込みで
あと、対象のメニューは今日(呼び出し日のみ)としました

コードの抜粋は以下のとおり

```
session = requests.session()

r = session.get(host)
...
r = session.post(login_url, data=login_info) # ユーザー名、パスワードを指定
...
menu_url = menu_url?page=' + str(i)
r = session.get(menu_url)
soup = BeautifulSoup(r.text, 'html.parser')

...
_dt = datetime.datetime.strptime(date.text.strip(), '%Y/%m/%d %H:%M') # サイト上での日時表記にあわせて取得
_d  = datetime.date(_dt.year, _dt.month, _dt.day)
...
JST = datetime.timezone(datetime.timedelta(hours=+9), 'JST')

today = datetime.datetime.now(JST).date()
...
today_menu_rul = host + link.get('href') # 今日のメニューURLを取得
res = get_lunch_menu(today_menu_rul) 
res = res + "〇〇ちゃん、たくさんたべてね"
return build_response({}, build_speechlet_response('lunch', res, 'none', True))
```

### AWS lambdaへのアップロード
pyファイルだけでなくてrequests、bs4などを利用しているのでこれらも合わせたzipファイルのアップロードが必要
pip install requests -t .
などでワークフォルダ上に保存してlambda_function.pyと一緒にzipにします。
このときフォルダを指定してzipファイルにしてはだめで
フォルダ内のファイルとサブフォルダを選択してzipファイルにする必要があります。

圧縮後のサイズが3MB以下であれば、その後の編集がlambdaコンソール上でできるので便利
3MBを超えている場合は圧縮とアップロードをCLIでできるツールがあるみたい

### テスト~実機確認
AWS Lambdaのコンソールにテスト設定があるのでまずはこれで確認します
Alexa Skills Kit開発者コンソールの方には呼び出し用語を指定してのテストができるのでここでも確認しておきます。
「給食」だと一般名詞としての用語説明が始まる場合があったので呼出し語を「今日の給食」に変更

同じアカウントであれば、この時点で実機確認できるようにも書いてあるのですが、スマホのアレクサアプリから検索しても出てこないのでベータ版公開で自分のアカウントを招待
スマホアプリから検索できるようになったので、アプリ上で有効化すると実機でも動作するようになりました。
「今日の給食教えて」と聞くと2~3秒チカチカしたあと読みあげてくれました

## その他
今日の取得はローカルでの確認時はdatetime.date.today()でできましたが
AWS Lambdaで動作させると昨日の給食を読み上げてくれて、「昨日食べた」と言われちゃいました。タイムゾーン指定しましょう
アレクサが給食を教えてくれることについては、まったく驚かない(普通に受け入れている)ようです。
残念ながらがんばりが伝わってはいませんが、たぶんそれが当然な世代になっていくんでしょうね。

## 参考
AWS Lambda Pythonをlambda-uploaderでデプロイ
https://dev.classmethod.jp/cloud/deploy-aws-lambda-python-with-lambda-uploader/

Alexaユーザーとシステムユーザーを関連付ける
https://developer.amazon.com/ja/docs/custom-skills/link-an-alexa-user-with-a-user-in-your-system.html