LINEボット1　ボットの作成

[Aidemy](https://aidemy.net/)　2020/12/12
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、LINEボットの投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。

今回学ぶこと
・LINE-MessagingAPIについて
・APIの準備


#LINE-MessagingAPIについて
##LINE-MessagingAPIとは
・__LINE-MessagingAPI__とは、botアプリとLINEプラットフォームの間で__データのやり取りができる機能__のことである。ユーザーがチャットボックスにメッセージを送ると__Webhook__が呼び出され、応答リクエストが送信される。この応答リクエストは__JSON形式__で、__HTTPS__というものを使って送信される。
・pythonでこれを使うことにより、__LINE上でのメッセージの送受信__が行えるようになる。

##開発者登録
・LINE-MessagingAPIを使用するには、__開発者登録__というものを行う必要がある。
・ <a href='https://developers.line.biz/console/' target='_blank'>LINE Developers</a>にアクセスしログインしたら、後は流れで登録できる。登録後、__新規プロバイダー__（組織名）を作成し、__新チャネル__（アプリ）を作成したら、雛形は完成する。

#APIの準備
##APIの仕組み
・__API__とは、__Application Programing Interface__の略である。すなわち、何らかのプログラム上の機能を持ったアプリケーションのことであり、Webを介して動作を行うAPIを__WebAPI__という。
・今回のAPIについては、__HTTPリクエスト__というもので__データを送信__し、__HTTPレスポンス__によって__データを取得__するものである。これは他の一般的なWebAPIも同様である。

##Webhookの仕組み
・登録したLINEDevelopersの項目の一つに__「Webhook有効化」__という項目がある。これは、サーバーに対し、__POSTリクエストが来たときの動作__を定めるものである。リクエストがデータを送信するものであるので、例えばユーザーがメッセージを送ってきた時に、「こんにちは」と返すということをWebhookに定めておくと、この処理が実現される。

#メッセージ送受信について
##HTTPリクエスト
・このリクエストは、何らかのアクションを始めるためにクライアントからサーバーに送られるものである。HTTPリクエストには、__開始行、ヘッダー、本文__がふくまれる。さらに、その開始行には実行するアクション（GETやPOSTなど）である__「HTTPメソッド」__、URLを指定する__「リクエスト対象」__、メッセージの残りの部分の構造を示す__「HTTPバージョン」__が含まれる。

##HTTPレスポンス
・__HTTPレスポンス__は、上記リクエストの応答を行うものである。こちらは__「ステータス行」「ヘッダー」「本文」__を含む。
・このレスポンスを使用できるライブラリは__「urllib」__や__「requests」__がある。今回は後者を使う。使うときは__Flask__をインポートすれば良い。また、ヘッダーには__「X-Line-Signature」__を指定する。

##メッセージの種類
・開発者がユーザーに送信できるメッセージは大きく分けて2つある。一つが__「プッシュメッセージ」__といって、__任意のタイミングでユーザーに送信できるメッセージ__である。よくある公式LINEのお知らせのようなものである。もう一つが__「応答メッセージ」__であり、こちらがユーザーからのメッセージに対して応答するものである。
・また、メッセージそのものの種類としては、__テキスト__メッセージ、__画像__メッセージ、動画、音声、ファイル、位置情報、スタンプなどがある。

#メッセージの送受信
##応答メッセージの送信
・ここからは実際に実装を行っていく。最初は応答メッセージを送信するコードを記述していく。まずは、__「何のイベントが発生した時の処理であるか」__を明記する。具体的には__「@handler.add()」__のなかで、今回のように__「ユーザーからメッセージが送られた時」__の処理を指定したい場合は__「MessageEvent」__を指定する。他にも、友だち登録された時に処理を行う__「FollowEvent」__、グループに他のメンバーが参加した時に処理を行う__「JoinEvent」__などがある。
・これを指定したら、以下にはイベント発生時の処理を定義する。今回はメッセージを送ってきたユーザーに応答メッセージを送信したいので、関数__「handle_message()」__において、__「reply_message()」__メソッドを使用する。この第一引数にはメッセージの送信先を指定する。この場合、__「event.reply_token」__と指定することで、__送信してきたユーザー__を宛先に指定できる。第二引数には__返信内容__を__「TextSendMessage(text='')」__で指定する。

・コード![スクリーンショット 2020-12-10 18.35.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/8e2ca8e8-4b41-5e45-c3af-e80afef5459d.png)

・ちなみに、この動作確認は__heroku__上で行う。コードを記述するのは__「main.py」__というファイルとする。また、各ファイルを一つのフォルダにまとめたら、__ターミナルで以下のコードを実行__し、デプロイを行う。
・また、このコマンドを実行することで、「https」から始まるURLが取得できる。このURLに__「/callback」__をつけたものを、LINEDevelopersの__Webhook__というところにこれに編集しておく。これで、実際にコード通りに動作してくれるようになる。

![スクリーンショット 2020-12-10 18.45.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/0dd92bb4-514b-8cd9-e32c-4450a05a186e.png)


・（自分は上記コマンドでエラーが出たため、以下のコマンドを使用した。）![スクリーンショット 2020-12-13 18.01.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/56259653-0507-7582-c090-5b648ca6edf8.png)


##キーワード応答メッセージ
・今回は、特定のメッセージが送信された時に特定の文字列を返すように設定する。やり方は、先程の__「reply_message()」__をif文ごとに分けて記述すれば良い。

また、この時のif文では送信されたテキストをコード上で取得する必要があるが、これは__「event.message.text」__で取得できる。これを行った例が以下のようになる。

・コード![スクリーンショット 2020-12-10 19.00.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/83411752-6258-bf1e-2a6d-b898377d2411.png)

##画像メッセージの送信
・今度は、ユーザーから、テキストではなく__画像が送信された場合の処理__を記述する。これは、@handler.add()の第二引数に__「ImageMessage」__と指定すれば良い。

・コード![スクリーンショット 2020-12-10 21.46.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/90afcbe2-200a-d000-5f49-0dfd8d346a16.png)


##フォローイベント時の処理の実装
・友だち追加された時の処理は@handler.add()の引数に__「FollowEvent」__と指定すれば良い。今回はメッセージを取得するわけではないので、message引数も必要ない。実際の処理としては__「handle_follow」__という関数を作成し、その中で定義する。
・まずは友だち追加された人の情報を取得する。__「get_profile()」__メソッドに登録した人の__user\_id__を渡すことで、これを行える。
・user_idの取得について、前提から話すと、関数の引数を__「event」__とすると、実際渡されるeventには__登録された（あるいはメッセージを送信した）ユーザーの情報__がjson形式で格納されている。今回のjson形式のデータは二重の辞書型のデータと似て__「{key1:{key2:value}}」__というように格納されており、今回のuser_idは__key2__の部分に格納されている。ここでのkey1は__source__である。この時のデータの取り出し方が辞書型と異なり、__「event.key」__のように取り出すので、__「event.source.user_id」__とすれば、user_idを取得できる。
・実際の処理について、まずは、__誰が登録したのか__についての情報を開発者（自分）のトークルームに送信するようにする。これは__「push_message()」__メソッドの第一引数に__自分のuser\_id__を指定することで行える。そして第二引数には、実際に送信するメッセージを__TextSendMessage(text=)__に記述すれば良い。
・登録情報は__profile__の各keyに格納されている。詳しくは以下のコードを参照。
・次に、登録してくれたユーザーに対するメッセージを指定する。こちらは__reply_message__で送信できる。

・コード（user_id部分は架空のもの）![スクリーンショット 2020-12-10 21.46.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/5f8cd86c-2d6b-cb54-fd7f-e62bb218d041.png)

今回は以上です。最後まで読んでいただき、ありがとうございました。