LINE Messaging APIを使ってしゃべり相手(LINE Bot)を作ってみた

# サマリ
LINE Messaging APIを使ってしゃべり相手（LINE Bot）を作りました。

# 背景
リモートやコロナ禍でコミュニケーションが減る中、
少しでもリフレッシュするためにしゃべり相手が欲しかった（さみしすぎだろ）

# ゴール
今回は、自分のメッセージに対して事前に設定した返事を返すBotを作成
（一部は用意された選択肢の中からランダムに応答、また[天気予報API](https://weather.tsukumijima.net/)でその日の天気を取得・応答）
**AIチャットボットではなく、いわゆるシナリオ型です。**

# 対象読者
- さみしい方
- LINE MessagingAPIに興味がある方

# 前提
- プログラミングがなんとなくわかること
（今回実施したのはおおまかに、Bot用LINEアカウント作成・ngrok・Node.jsの導入になりました。
　参考記事をベースにさせていただいたこともあり、
　自分はすべて初見でしたが本記事のレベルをやるには何とかなりました）
- コマンドラインの操作が初学者レベルに可能
　（`cd`,`mkdir`,`ls`など使えるレベル）

# 環境
- ホストOS：Window10 Home
- JavaScript実行環境：Node.js（バージョン：16.17.0）
- Node.jsパッケージ管理：npm（バージョン：8.15.0）
- トンネリングツール：ngrok（バージョン：2.3.40）
- コマンドライン環境：PowerShell（バージョン：5.1.19041.1682）

**※Windows10以外はすべて本記事にてインストールするので、事前の導入は不要です。**

# 手順
大きな流れは以下です。

1. LINEアカウントを作る（Bot用アカウント作成）
1. Node.jsを入れる（JavaScript実行環境の導入）
1. server.jsを作る（実際にBotの挙動を決めるJSファイルの作成）
1. ngrokを入れる（外部からチャットできる環境の作成）
1. 自分の使いたいように各種設定する（自分好みにカスタマイズ）

**基本的には各手順で参考にさせていただいた記事があり、**
**そちらをベースに進めていきますのでご注意ください。**

### 手順1.LINEアカウントを作る


LINEアカウントから基本的な流れ（手順3，4）は**以下の記事を参考にさせていただきました**。
（記事内項番「1.Botアカウントを作成する」）
（非常にわかりやすく丁寧で助かりました）

https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d



本手順のざっくりサマリです。
- 個人アカウントをBot化はできないため、専用のアカウントを作る必要がある
- 専用のアカウントは[LINE Developersサイト](https://developers.line.biz/ja/)に個人アカウント（あるいはビジネスカウントでログインすることで作成可能）
- Botに必要な初期設定を行う
- サイトでQRコードを表示、スマホで読み取ることでBotと友達に（感動）

### 手順2.Node.jsを入れる

Node.jsについては[Progateさんの記事](https://prog-8.com/docs/nodejs-env-win)があったので、そちらを参考にしました。

本手順のざっくりサマリです。
すべて上記の記事を参考にすればまとめてできます。（横着すな）

- JavaScriptの実行環境であるNode.jsがインストール
　（今回はJSをベースにしていますが、Pythonで作る方法もあるようなので
　　あくまで今回のやり方でやるため必要になります）
- Node.jsのパッケージ管理システムであるnpmのインストール
- PowerShell（マイクロソフトが開発した拡張可能なコマンドラインインターフェイス シェルおよびスクリプト言語）のインストール

PowerShellについての概要は以下です。
この後、JSのファイルを実行したり、ngrokを起動する際にPowerShellを使いました。
（使わなくてもいけるとは思いますが）
[こちら(Wiki)を参照](https://ja.wikipedia.org/wiki/PowerShell)


### 手順3.server.jsを作る

Botの基盤の導入まで（アカウント作成・JS実行環境）が完了しました。
さて、いよいよBotに命を吹き込んでいきます。

本項も手順1同様[こちらの記事](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)を参考にさせていただきました。
（記事内項番「2.Node.jsでBot開発」）

本手順のざっくりサマリです。
- `npm -init`コマンドにてpackage.jsonファイルを作成
- SDKを入れる
- メインとなるファイル（server.js）の作成
- ChannelSecretとChannelAccessTokenをLINE Developersサイトから取得、server.jsに記載
- `Localhost:3000`でHelloWorldの確認

すべてはpackage.jsonの作成から始まるようで、以下の記事が非常に勉強になりました。

https://qiita.com/righteous/items/e5448cb2e7e11ab7d477

また、server.jsの追記に当たって、
ChannelSecret（チャネルシークレット）とChannelAccessToken（チャネルアクセストークン）は[LINE Developersサイト](https://developers.line.biz/ja/docs/line-things/getting-started/#workflow)に以下の説明があります。
※ちょっと自分は理解が怪しいので、現時点では個人的な解釈は省かせていただきます。（おい）
※また、アクセストークンは短期と長期があるようで、それぞれ期間と作成数が異なるようなので、気になる方は[こちら](https://developers.line.biz/ja/docs/messaging-api/channel-access-tokens/)参考にご覧ください。
※とりあえずはこれらを取得してserver.jsに書き込んでおく必要がある、と覚えておけばいいかと思います。

|  情報  |  説明  |
| ---- | ---- |
|  チャネルシークレット  |  ボットアプリがWebhookイベントを受信したときに、LINEプラットフォームから送られたことを確認するための秘密鍵です。  |
|  アクセストークン（ロングターム）  |  Messaging APIのチャネルを特定するためのトークンです。  |

チャネルシークレットはLINE Developersサイトのチャネル基本設定ページにあります。
チャネルアクセストークン（長期）はLINE DevelopersサイトのMessaging API設定ページにあります。

`node server.js`コマンドにて以下の通り起動していることが確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/f6524e6a-e1d6-1c41-efbe-b71f256933ee.png)


また、`Localhost:3000`でメッセージも確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/b9494556-f4cb-1bc7-e39a-96f5f7646d09.png)



### 手順4.ngrokを入れる

何とかローカル環境にてserver.jsが正常に動作していることが確認できましたので、
自分のスマートフォンからBot向かいにメッセージを送信できるよう
外部に公開できる環境を作っていきます。

こちらも相変わらず手順1，3同様[こちらの記事](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d#3-ngrok%E3%81%A7%E3%83%88%E3%83%B3%E3%83%8D%E3%83%AA%E3%83%B3%E3%82%B0)を参考に実施していきます。
（記事内項番「3.ngrokでトンネリング」）

npmコマンドでngrokをインストールしたのち、
`ngrok http ポート名`（今回は3000番）でトンネリングサーバを起動します。

このような形で画面が立ち上がるので、`https://`で始まる部分のURLを`.io`までをコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/7893f4ab-7855-91a9-ec0f-09cd5344c1b8.png)

そして、LINE Developersのサイトにて貼り付け（.ioのあと/webhookをつけるのを忘れずに）

`ngrok http 3000`でトンネリングサーバが起動しており、`node server.js`でアプリも起動していれば、
Botに話しかければ返事が来るはずです！
（参考にさせていただいた記事の通り`server.js`を作成していれば、オウム返しになるはずです）

やった～！

### 手順5.自分の使いたいように各種設定する

ということで、ここからは**以下の記事を参考にさせていただき**、
より自分用にカスタマイズをしていきます。
（めちゃくちゃ参考になりますし、単純に記事が面白いです。）

https://qiita.com/mnana/items/3836aee1b749670804dc?utm_source=Qiita%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9&utm_campaign=1840d6bc92-Qiita_newsletter_485_10_27_2021&utm_medium=email&utm_term=0_e44feaa081-1840d6bc92-34495181#%E5%BD%BC%E6%B0%8F%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F

#### やったこと１：シンプルに返事
部分一致or完全一致したときに、固定のメッセージを返す。
（例.”こんにちは”と打ち込んだら、”こんにちは”と返す）

#### やったこと２：ランダムに返事
部分一致or完全一致したときに、返事候補のうち１つをランダムに返す。
（例.”れた”が含まれるメッセージ（疲れたなど）を受信したら、”お疲れ様”・”ゆっくり休んで”・”明日はいいことある”のうち1つをランダムで返す）
（参考にさせていただいた記事の//部分一致３のところですね。）


#### やったこと３：天気を取得
[天気予報API](https://weather.tsukumijima.net/)を利用して、今日の天気を取得します。

参考にさせていただいた記事に記載のコードの以下の部分の130010を自分の地域のコードに置き換えました。
地域ごとのコードは[こちら](https://weather.tsukumijima.net/primary_area.xml)

```
            const res = await axios.get('https://weather.tsukumijima.net/api/forecast/city/130010');
```

#### やったこと４：絵文字で返事を返してもらう
返事には絵文字とかついてほしいタイプなので、
こちらから絵文字コピーさせていただきました。

https://lets-emoji.com/emojilist/emojilist-1/

上記のページのコピーボタンを押して、そのまま`server.js`のメッセージ部分にペーストすればいけました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/997027ee-2de0-3ac7-3863-bb0f172e9095.png)


# 個人的にハマった穴と対処
- **一定時間たつとngrokが切れる**ので、定期的に`ngrok http 3000`コマンドを実施する必要がある。
（だいたい最大でも8時間で切れるようですね。[参考](https://www.public.ne.jp/2021/01/07/ngrok-%E3%82%A8%E3%83%B3%E3%82%B0%E3%83%AD%E3%83%83%E3%82%AF-%E3%82%92%E3%82%82%E3%81%86%E5%B0%91%E3%81%97%E8%A9%B3%E3%81%97%E3%81%8F%E3%81%94%E7%B4%B9%E4%BB%8B/#:~:text=%E6%9C%AA%E7%99%BB%E9%8C%B2%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%A0%E3%81%A8,%E6%99%82%E9%96%93%E5%88%B6%E9%99%90%E3%81%8C%E3%81%AA%E3%81%8F%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)）
※本記事の手順4で張り付けた画面キャプチャ上はSession Expiresが2時間になっているなので、実際に確認してみるのがよさそうです。

それゆえに`ngrok http 3000`で再起動が必要で、その際WebhookURLが変更になるので**その都度LINE Developersサイトにて書き換える必要がある**


- PowerShellで`ngrok http 3000`コマンド打った際以下のようなエラーが出ることがあり、起動できない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/649f3f87-50a3-a191-e669-925453de60a3.png)


下記の記事を参考にすれば解決しました。

https://qiita.com/ponsuke0531/items/4629626a3e84bcd9398f

そもそもですが、ざっとみた感じPowerShell独自のポリシーに起因するもののようです。
（PowerShellでなくコマンドプロンプトで`ngrok http 3000`で実行すれば問題なくいけました。）
MacとかLinuxなら出ないかもしれないですね。

# 結果
一応それっぽく返事をくれるようにできました！（おぉ～）
（メッセージとスタンプのセンスはご容赦ください…）

![RPReplay_Final1664094008.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/0e3fca18-15e7-e39b-44a7-45d21f0392fc.gif)



やっていることは参考記事の二番煎じのような形ですが、
それでも自分で何か形にできると嬉しいものです。
参考にさせていただいた記事の著者の皆さん、本当にありがとうございました。

# 学び
- LINE Botができるまでの過程と大まかな仕組みの理解

# まとめ

今回できたこと
- LINEのBotアカウントの作成

- Node.jsを用いたBotの作成（ベースは他記事をかなり参考にさせていただきましたが…）
    - 決まった返事を応答
    - 用意された返事の候補からランダムに応答 
    - 天気のAPIからその日の天気を応答

- nrgokを用いた外部からのアクセス

そもそもJSやNode.js自体の理解がまだまだ浅いため
今後も何か作りながらさらに理解を深めていきたいです。

また、本Botの今後ついては、
[おじさん構文](https://ja.wikipedia.org/wiki/%E3%81%8A%E3%81%98%E3%81%95%E3%82%93%E6%A7%8B%E6%96%87)で返してくれるBotを作ったり、
しりとりができるようなBotにしたり、もっとしゃべっていて楽しいものにカスタマイズしていきたいです。

さらには自然言語学習も勉強して、自作で[LaMDA](https://wired.jp/article/plaintext-lamda-soul-machine-learning-system/
)を超える相棒を作りたいなぁ～（白目）