最近、1週間くらいかけてPythonのフレームワークflaskを用いてラインボットを作っていました。
flask自体触れるのははじめてでしたが、flaskやwebに関する知識を多く求められることもなかったため、特に苦労せず作ることが出来ました。
僕自身、これからラインボットを頻繁に作る機会はないと思われるものの、せっかくなのでいつでも思い出せるように記事に残しておきます。
本記事を最後まで読んでいただくと、初心者でもpythonを使って簡単なラインボットを作成できるようになるはずです!!
開発環境
- WSL2(Windows Subsystem for Linux)
- Python3.6.9
- LINEの個人アカウント取得済み(何の変哲もない普通のアカウントのこと)
LINE Develoversのアカウント作成・設定
実装する前に、LINE Developersでアカウントを作ったり、もろもろの設定をしておく必要があります。
LINE Developersのアカウントを作成
まず、LINE Developersのサイトからアカウントを作成してください。アカウント作成自体は何も難しいことはないので、詳しい手順はここでは省略します。
自分はLINEの個人アカウントを持っているだけで簡単に解説できました。
あと、ログインした後、言語設定が英語になっている場合があるので、右上または右下に言語を変えられる欄があるので「日本語」に設定しておきましょう。
プロバイダーの作成をする
アカウント作成・ログインをし終えたら、コンソールに移動し、左のメニューバーから「プロバイダー」をクリックしてください。
皆さんの画面にはおそらく「最近閲覧したチャネル」は出てこないと思いますが、プロバイダー「作成」ボタンは存在すると思いますので、迷わず「作成」をクリックしてください。
すると、こんな画面になるので、プロバイダー名を入力し、「作成」ボタンを押せばOKです。
今回作るラインボットがオウム返しをする簡単なラインボットなので、プロバイダー名は「オウム返しbot」としておきましたが、別になんでもOKです。
作成し終えると、プロバイダーの項目にさっき設定した名前でプロバイダーが表示されているはずです。これでプロバイダーの作成は完了です。
チャネルの作成
プロバイダーの作成が終わると、自動的に「チャネル設定」の画面に切り替わっていると思います。
もしくは、先ほど作成したプロバイダー欄に表示されている、自分で作ったプロバイダーをクリックすれば下のような画面に遷移します。
チャネル設定ではチャネルの種類を「Messaging API」を選択してください。
チャネルアイコンやチャネル名を設定する画面になりますので、必須項目を埋めていってください。
ちなみにチャネルアイコンはいわゆる「トプ画」に、チャネル名はLINEアカウントの名前になるっぽいです。
チャネル設定項目に記入が終われば「作成」からの「OK」でチャネルの作成ができます。
チャネル作成を終えると、このように先ほど作成したチャネルが「オウム返しbot」プロバイダ―の中に作れたことが確認できます。
コードを実装していく前の準備はいったんこれで終わりです。
Flaskでオウム返しLine Botを作ってみる【コード詳細を解説】
まずは、送信した内容をそのまま返してくれる、オウム返しLine Botを作っていきます。
あと、後々少し面倒だったりするので、ちゃんと仮想環境を作成してコードを書いてくださいね!
必要なライブラリをインストール
まず、flaskとline-bot-sdkをインストールする必要があるので、以下のコマンドをたたいてください。
$ pip install flask $ pip install line-bot-sdk $ pip install gunicorn
flaskとは
flaskとはPythonでwebアプリケーションを作成するためのフレームワークです。
フレームワークを用いると、用いない場合より簡単にwebサイトやwebアプリを作成することができます。
Pythonでwebアプリを作れるフレームワークは他にも有名なものだとDjangoなどがあり、それで作ることもできるのですが、今回は学習が容易であるflaskを採用しています。
ラインボット作成にflaskを使う理由
webアプリケーションというと、Twitterやfacebook、YouTubeのようなwebサイトやwebサービスを指すことが多いです。
「なぜラインボットにwebアプリケーションフレームワークを使うのか?」と疑問に思う方も多いのではないでしょうか?
結論から言うと、webアプリケーションの仕組みとラインボットの仕組みが同じだからです。以下ではこれを説明していきます。
webサイトをあなたがブラウザで閲覧できる仕組みは、厳密ではないですが以下のような感じです。
- あなたのPCからサーバーに「xxxxのサイトのファイルが欲しい!」のような要求である「リクエスト」を送ります(フォームを送信したり、URLをクリックすることでリクエストが勝手に送られています)
- リクエストを受け取ると、サーバー内でプログラムが動き、リクエスト毎にどのwebサイトのファイルを表示させるかを探したり、カスタマイズしたりします
- webサイトのファイルを「レスポンス」としてあなたのPCに送ります
一方で、ラインボットもよく似た仕組みで動きます。
- ラインにメッセージを送ると、ラインからサーバーへリクエストが送られます。
- リクエストを受け取ると、サーバー内でプログラムが動き、リクエスト毎にどんなメッセージを返信するかが決定されます
- ②で決まったメッセージをラインで送信(返信)します(この③の部分がレスポンス)
こんな感じで、webアプリやwebサイトとラインボットの仕組みが同じだから、ラインボットにもwebアプリケーションフレームワークであるflaskを使うんですね!
ラインボットもwebアプリケーションの1つだと言われればそれまでですが…(笑)
オウム返しLine Botを作ってみる
オウム返しLine Botのコード自体は実はLINEの公式の資料に載っているので、一部改変して載せただけです。「app.py」という名前で以下のコードを保存しましょう。
from flask import Flask, request, abort from linebot import ( LineBotApi, WebhookHandler ) from linebot.exceptions import ( InvalidSignatureError ) from linebot.models import ( MessageEvent, TextMessage, TextSendMessage, ) line_bot_api = LineBotApi('YOUR_CHANNEL_ACCESS_TOKEN') handler = WebhookHandler('YOUR_CHANNEL_SECRET') app = Flask(__name__) @app.route("/") def say_hello(): return "Hello" @app.route("/callback", methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: print("Invalid signature. Please check your channel access token/channel secret.") abort(400) return 'OK' @handler.add(MessageEvent, message=TextMessage) def handle_message(event): line_bot_api.reply_message( event.reply_token, TextSendMessage(text=event.message.text)) if __name__ == "__main__": app.run()
上から順番にコードを分かりやすく解説していきます。
必要なモジュールのインポート
コードの1~11行目では、flaskやline-bot-sdkなどのモジュールをインポートします。ここに関しては特に何も考えなくてもよいでしょう。
LineBotApiとWebHookHandlerのインスタンスの作成
13行目と14行目です。
line_bot_api = LineBotApi('YOUR_CHANNEL_ACCESS_TOKEN') handler = WebhookHandler('YOUR_CHANNEL_SECRET')
ここではLineBotApiのインスタンスを作るために「チャネルアクセストークン」、WebhookHandlerのインスタンスを作るために「チャネルシークレット」が必要です。
line_bot_apiインスタンスの様々なメソッドを用いることで、pythonのプログラムからメッセージや画像を送ったりなど、LINE操作ができます。
line_bot_apiインスタンスの作成にはチャネルアクセストークンというものが必要なのですが、作成したチャネルの「Messaging API設定>チャネルアクセストークン」発行・コピペしたらOKです。
また、Webhookとはアプリケーションの更新情報を、他のアプリケーションへリアルタイム提供する仕組みや概念のこと(なんか難しそう)で、ここではイベント発生時に指定したURLにPOSTリクエストを送る仕組みのことです。
ラインボットの場合だと、「ユーザーがメッセージを送信する」というイベントが発生すると、LINE Developersの「Webhook設定」で設定したURLにPOSTリクエストが送られるという訳です。
WebhookHandlerのインスタンス作成には「チャネルシークレット」が必要なのですが、作成したチャネルの「チャネル基本設定>チャネルシークレット」をコピペすればOKです。
Flaskの動作確認のためのコード
18~20行目ですが、ラインボットの動作自体には全く関係がなく、なくてもラインボットは動作します。
では、なぜわざわざ書いているかというと、Flaskの実行自体がうまくいっているか動作を確かめるためです。
@app.route("/") def say_hello(): return "Hello"
flaskのコードの解説となってしまいますが、@app.route(“/xxxx”)の後に関数がくると、https://(IPアドレス)/xxxxというURLと関数を結び付ける処理をしています。
上記のコードだとhttp://(IPアドレス)/にアクセスしてきた場合、say_hello関数が呼び出され、”Hello”という文字列が返されるのです。結果として、ブラウザにはHelloと表示されることになります。
$ export FLASK_APP=app.py $ export FLASK_DEBUG=1 $ flask run --host=0.0.0.0
試しにこのコマンドを実行した後、http://localhost:5000/にアクセスしてみてください。ページ左上にHelloと出ていればflask自体は問題なく動いているという証拠です。
ここは呪文だ!コピペでよし!
次に22~38行目です。
@app.route("/callback", methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request body as text body = request.get_data(as_text=True) app.logger.info("Request body: " + body) # handle webhook body try: handler.handle(body, signature) except InvalidSignatureError: print("Invalid signature. Please check your channel access token/channel secret.") abort(400) return 'OK'
先ほどと同じく、http://(IPアドレス)/callbackというURLとcallback関数が結び付けられています。
ただし、methods=[‘POST’]となっていますが、これはhttp://(IPアドレス)/callbackというURLにPOSTリクエストが来たらcallback関数が起動するということです。
callback関数の中身についてはいじったりする必要もなく、呪文だと思ってコピペしておくだけでOKなのですが、どうやらLINE側に「こういうラインボットがあるよ~」って知らせる処理を書いているらしいです。(知らんけど笑)
オウム返しをする処理を実装
41~45行目ですが、ここでやっとオウム返しをする処理を書いています。
@handler.add(MessageEvent, message=TextMessage) def handle_message(event): line_bot_api.reply_message( event.reply_token, TextSendMessage(text=event.message.text))
@handler.add()の下に関数が定義されていますが、WebhookHandlerのインスタンスにその下に定義した関数をメソッドとして加えている処理をしています。
もうちょっと分かりやすく言うと、LINEボットにメッセージを送ると、LINEボットは受け取ったメッセージをサーバーにPOSTリクエストとして送りますよね?
POSTリクエストを受けとったサーバーが、その受け取ったメッセージの情報をもとに、どのようなリプライを返すかという処理をhandle_message関数内で実装しているというわけです。
つまり、メッセージをうけとった後に、どんな処理をしてどんなリプライを返すか、という処理を書いているということです。
herokuにデプロイする
コードを書き終えたら、herokuにデプロイしていきましょう。
herokuとは、簡単に言うとwebアプリケーションを簡単に公開できるサービスです。
またデプロイとは「(プログラムなどを使える状態になるよう)配備する」という意味ですが、まぁ簡単に「公開・使用可能にするためにアップロード」する的な感じで捉えておいていいでしょう。
herokuに登録
herokuのアカウントを持っていない方はherokuのアカウントを作成してください。
また、コマンドラインからherokuを操作するために、heroku-cliのインストールが必要です。
heroku-cliのインストール方法ですが、OSによって異なるようなのでHeroku公式サイトをご覧ください。
herokuに必要なファイルを準備
- app.py
- .gitignore
- Procfile
- requrements.txt
- runtime.txt
app.pyは先ほどの「Flaskでオウム返しLine Botを作ってみる【コード詳細を解説】」で説明したapp.pyのことです。
(別になくてもよいですが、).gitignoreは以下のように記述しておけばOKです。
__pycache__
Procfileには以下のように書きます。Procfileはheroku上にあるアプリケーションがどんなコマンドで実行するのかを書くファイルです。
web: gunicorn app:app --log-file -
requirements.txtはこのアプリを動かすために必要なpythonのライブラリを書いていきます。自分の手で書いていく必要はなく、コマンドラインで
$ pip freeze > requirements.txt
とするだけでOKです。最後にruntime.txtですが、ここにはPythonのバージョンを書くだけです。
Python-3.6.15
自分が使っていた環境のPythonのバージョンは3.6.9だったのですが、heroku側がサポートしていないバージョンのようで、3.6.15に書き換えています。
herokuにデプロイする
まずは、コマンドラインからherokuにログインします。
$ heroku login
上記のコマンドを入力し、そののちにエンターキーを押すと、ブラウザが立ち上がりherokuのログイン画面になるので、メールアドレスやパスワードを入力してログインしてください。
また、ターミナル上ではapp.pyが存在するディレクトリに移動してください。
$ git init $ git add . $ git commit -m "first commit" $ heroku create [botの名前(何でもOK)] $ git push heroku master $ heroku ps:scale web=1
これでデプロイ完了です。最後に下のようにコマンドを打ってみてください。また、[botの名前]の部分は後から確認できますが、確認するの面倒なので一応覚えておきましょう。
$ heroku open
「Hello」と書かれたページが表示されたならデプロイは成功しています。
LINE DevelopersでWebhook URLの設定
デプロイを終えたら、LINE Developersからコード実装前に作成したチャネルのMessaging API設定を開き、Webhook設定を更新します。
Webhook URLにhttps://[botの名前].herokuapp.com/callbackを入力して更新したら完成です。[botの名前]はさきほどheroku create [botの名前]で作成したものと同じです。
実際に、作成したラインボットと友達になってメッセージを送ってみてください。
本記事はこれで終了になります。最後までご覧いただきありがとうございました。
記事内ではくどいくらい超基本的なことも解説します。慣れている方は適宜読み飛ばしてください。