DialogflowとLINE Botで元号ジェネレーターを作ってみた

新元号がまもなく発表されるので、LINE Botで元号ジェネレーターを作ってみました。
LINE Botに「元号作って」と言うと今までに使われた元号の漢字からランダムで画像を生成します。

# 完成動画
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">元号ジェネレーターをLINE Botで作ってみた<a href="https://twitter.com/hashtag/LINEBot?src=hash&amp;ref_src=twsrc%5Etfw">#LINEBot</a><a href="https://twitter.com/hashtag/%E5%85%83%E5%8F%B7%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC?src=hash&amp;ref_src=twsrc%5Etfw">#元号ジェネレーター</a> <a href="https://t.co/2DMs7XCca5">pic.twitter.com/2DMs7XCca5</a></p>&mdash; がおまる@スマートスピーカーアプリ開発入門発売中！ (@gaomar) <a href="https://twitter.com/gaomar/status/1105626189392076800?ref_src=twsrc%5Etfw">March 13, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# LINE Bot
こちらから友だちになると元号ジェネレーターを試すことができます。
<a href="https://line.me/R/ti/p/iYXOLVU_0j"><img height="36" border="0" alt="友だち追加" src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png"></a>

QRコードはこちら

![linebot_qr.png](https://qiita-image-store.s3.amazonaws.com/0/154355/7504aae9-78ec-f93c-e11c-6ff0ca0d79cc.png)

# 1. AWS Lambdaで関数を作成しよう
AWSにBotの処理を記述します。Lambdaページへ行って関数を新規で作成しましょう。
LambdaのロールはS3のフルアクセス権限とCloudWatchのフルアクセス権限を付与しています。

<img width="1544" alt="s100.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/8c9a5847-dcfd-6668-2781-cbe89efe412d.png">

## 1-1. プログラムをアップする
Lambdaにプログラムをアップします。こちらに完成したファイルがあるので、参考にしてください。
https://github.com/gaomar/gengo-generator-bot/raw/master/lambda.zip

Lambdaの環境変数にS3のバケット名を指定します。最後に右上の［保存］ボタンをクリックします。

<img width="1539" alt="s101.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/d56134db-c5e2-7bc7-7ff3-fa11f343c71e.png">

プログラムの中身は特に解説しません。興味ある方はこちらから確認してみてください。
https://github.com/gaomar/gengo-generator-bot/blob/master/index.js

## 1-2. Lambda Layerをアップする
Lambda Layerという便利な機能があります。これを使えばLambdaに全部圧縮して上げなくても良くなります。
[Jimp](https://github.com/oliver-moran/jimp)というJavascriptで画像編集できるライブラリがあるので、これをLambda Layerにアップします。

https://github.com/oliver-moran/jimp

Lambda Layerのフォルダ構成が決まっているので、その通りに作成します。
ローカルPCで規定のフォルダに保存します。

```
$ mkdir nodejs
$ cd nodejs
$ npm init
$ npm install --save jimp
$ cd ..
$ zip -r nodejs.zip nodejs
```

左メニューから`Layers`をクリックして、［レイヤーの作成］ボタンをクリックします。

<img width="1605" alt="s102.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/1c31052b-cfcf-bfbe-cb38-a3e9b4086e1f.png">

これで生成された`nodejs.zip`ファイルをLambda Layerにアップします。
<img width="1543" alt="s103.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/96c1131d-65c8-2388-7efe-7fddd0050a26.png">

Layersをクリックして、［レイヤーの追加］ボタンをクリックします。

<img width="1547" alt="s104.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/18faaec3-09e4-ace8-c085-4bca7e11b932.png">

先程作成したLambda Layerを選択します。最後に右上の［保存］ボタンを押せばLayerが追加されます。
<img width="1542" alt="s105.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/3910a943-3d49-e08c-b192-6cd5ffd2e9f2.png">

## 1-3. API Gatewayを適用する
左メニューからAPI Gatewayを選択します。

<img width="1536" alt="s106.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/e42265c5-4858-f114-50a9-367b5c4fa2f8.png">

新規APIの作成を選択して、セキュリティは`オープン`を選択します。
最後に［追加］ボタンをクリックします。
<img width="1536" alt="s107.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/c3e09619-cc12-0d09-5f7e-9e15254c6fc2.png">

右上の［保存］ボタンを押せば、アクセスURLが発行されます。これは後ほど使うのでメモしておきましょう。
<img width="1542" alt="s108.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/3780c746-88c1-b31d-3e03-da771a11f31f.png">

## 1-4. タイムアウト時間を伸ばしておく
画像の合成に時間がかかって、デフォルトの3秒だとタイムアウトしてしまいます。
少しタイムアウト時間を伸ばしておきます。

<img width="1541" alt="s109.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/7c1d659a-3322-2539-e48c-dd55610a6186.png">

# 2. Messaging APIでLINE Botを作成する
LINE DevelopersのサイトにアクセスしてMessagin APIのチャネルを作成します。
https://developers.line.biz/console/

必要事項を入力して下記のようなページまで進みます。
<img width="1677" alt="s200.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/958c4e01-22ec-b9c5-5b17-07f8d0c17d9b.png">

# 3. Dialogflowでプロジェクトを作成する
LINE Botとの連携のためDialogflowで新規エージェントを作成します。

<img width="1316" alt="s300.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/7fc414c8-fd0b-428c-354a-6bf7cc274f3d.png">

# 3-1. API GatewayのアクセスURLを指定する
Fulfillment部分をクリックして、API GatewayのアクセスURLを指定します。

<img width="1310" alt="s301.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/70d8e923-a3fd-be9a-3ced-7869df9ba8a6.png">

## 3-2. MainIntentを作成
Botが反応する言葉を登録します。Intentの右にある［＋］ボタンをクリックします。
Intent名に`MainIntent`と入力します。その下にあるTraining phrasesにBotが反応する言葉をたくさん登録します。

<img width="1311" alt="s302.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/17c80daf-3a11-3317-2da6-c049e053ecf8.png">

## 3-3. EndIntentを作成
Lambdaから返ってくる値を受けとるIntentを作成します。
左メニューのIntentsにある［+］をクリックして新規Intentを作成します。

Intent名は`EndIntent`と入力します。Events部分に`FINISH`と入力します。
Actions and parameters部分にパラメータ値を入力します。

<img width="1313" alt="s303.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/161ae26b-480e-63bd-9058-fc64be9ba7ce.png">

| PARAMETER NAME       |       ENTITY |    VALUE    |
|:----------------|:-----------------|:------------------|
| myURL             |             @sys.url |        #FINISH.myURL        |
| myMessage             |             @sys.any |        #FINISH.message        |


このパラメータはLambdaで返ってくる値を取得します。こちらの６７行目に書いている処理が該当箇所です。
https://github.com/gaomar/gengo-generator-bot/blob/master/index.js

## 3-4. Botにレスポンスを返す

Botに表示するレスポンスを指定します。
`DEFAULT`タブをクリックして、Text responseに`$myMessage`を指定します。
これで、Lambdaから返ってくるメッセージを表示することができます。

<img width="966" alt="s304.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/1a609ffd-54fc-359c-d76f-95a15b0f8211.png">

## 3-5. LINE用のレスポンスを返す
生成された画像のURLを渡して、Botに画像を表示させるようにします。
`$myURL`に画像のアクセスURLが返ってきます。

※システムの仕様で`https://`がついているとエラーになったので、Lambdaで返す際に除外しています。

<img width="962" alt="s305.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/4a944b15-f3c3-ac63-f97f-0586ea7233fc.png">

②を有効にするのは、3-4のレスポンス文言を表示してから画像が表示されるようにしているためです。

![s306.png](https://qiita-image-store.s3.amazonaws.com/0/154355/465ef005-c9ae-2051-c89e-667926ca7804.png)


# 4. LINE Botと連携する
Botと連携する設定を行います。左メニューから`Integrations`をクリックします。
その中にあるLINEをクリックします。

<img width="1298" alt="s400.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/aa5a78dd-0eff-d827-7469-e2139bff3f22.png">

LINE Botのチャネル基本情報にかかれている`Channel ID` `Channel Secret` `Channel Access Token`をそれぞれコピペします。

<img width="811" alt="s401.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/6775cbbc-b07b-3725-4ac2-36fed0a77132.png">

`Webhook URL`はLINE DevelopersにあるWebhook URLへコピペします。

<img width="1387" alt="s402.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/f72ec364-a114-edd0-143d-363df0a21f8b.png">

右下の`START`ボタンを押せばBotが動き出します。

# まとめ
Dialogflowと連携すれば画像合成してBot上に表示できるものが簡単に作れます。
アイデア次第で面白いBotができるので、ぜひチャレンジしてみてはいかがでしょうか？

システム化のご検討やご相談は弊社までお問い合わせください。
https://i-enter.co.jp/contact/