1
7

More than 1 year has passed since last update.

FlaskでLINEBotを作成してみる

Posted at

Python 3.7.8
Flask 2.1.1
heroku 7.53.0

作成手順

1.LINE developersへ登録
2.コーディング
3.herokuへの配置

1.LINE developerへの登録

https://developers.line.biz/ja/へアクセス
サイト右上のログインから自分のラインアカウントを使用しLINE developersへ登録
LINE_Developersホーム画面.png
ここでは今回作成したproductというチャネルが表示されています。

プロバイダーの作成を押し、プロバイダー名を入力します。
その後Messaging APIを選択し、チャネルを作成しておきます。

2.コーディング

タイトルにもあるように今回はPythonのフレームワークであるflaskを使用して実装を行います。

私はローカルの環境には極力ライブラリはインストールしたくないので

python -m venv env

上記のコマンドで仮想環境を作成し、その中でflaskなどのライブラリをインストールするようにします

仮想環境を作成したら

.\env\scripts\activate

で仮想環境をアクティブにし、今回使用するライブラリをインストールします。

pip install flask
pip install line-bot-sdk
pip install gunicorn

LINEBotを作成するにあたり必要なファイルは以下です。
1.main.py
2.Procfile
3.runtime.txt
4.requirements.txt
5..gitignore

/
├ Product/ # 今回の仮想環境、運用には必要ないので.gitignoreでcommitしないようにする
├ main.py
├ Procfile
├ runtime.txt
├ requirements.txt
├ .gitignore

main.py

LINEBotのメインの動きです。

from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import os

#Token取得

YOUR_CHANNEL_ACCESS_TOKEN = "チャネルアクセストークン"
YOUR_CHANNEL_SECRET = "チャネルシークレット"

app = Flask(__name__)
app.debug = False

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

@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:
        abort(400)

    return 'OK'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    df_list = [
        ['Google','https://www.google.com/'],
        ['yahoo','https://www.yahoo.co.jp/'],
        ]

    for i in range(len(df_list)):
        url = None
        if event.message.text == df_list[i][0]:
            url = df_list[i][1]
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text=url)
                )
        else:
            continue

        if url == None:
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text='そのようなサイトは存在しません')
                )


if __name__ == "__main__":
    port = int(os.getenv("PORT"))
    app.run(host="0.0.0.0", port=port)

細かく区切って解説します。

YOUR_CHANNEL_ACCESS_TOKEN = "チャネルアクセストークン"
YOUR_CHANNEL_SECRET = "チャネルシークレット"

app = Flask(__name__)
app.debug = False

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

ここではLINE developersで作成したMessaging APIの
アクセストークン(Messaging APIを呼び出すときに使用するチャネルアクセストークン)と
チャネルシークレット(アプリに対して、チャネルへのアクセスを許可したことを示す秘密鍵)を取得します。

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'

LINE DevelopersのWebhookでURLを指定してWebhookからURLにイベントが送られるようにし、LINEアプリを通して送られてきたリクエストかを検証し、問題なければ処理関数を呼び出す。

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    df_list = [
        ['Google','https://www.google.com/'],
        ['yahoo','https://www.yahoo.co.jp/'],
        ]

    for i in range(len(df_list)):
        url = None
        if event.message.text == df_list[i][0]:
            url = df_list[i][1]
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text=url)
                )
        else:
            continue

        if url == None:
            line_bot_api.reply_message(
                event.reply_token,
                TextSendMessage(text='そのようなサイトは存在しません')
                )

メインの処理。今回はチャットでユーザが
「Google」と送信するとhttps://www.google.com/が返信され、
「yahoo」と送信するとhttps://www.yahoo.co.jp/が返信され、
それ以外だと'そのようなサイトは存在しません'というメッセージが返信される。

if __name__ == "__main__":
    port = int(os.getenv("PORT"))
    app.run(host="0.0.0.0", port=port)

Pythonのおまじない。
今回の話の本筋ではないため説明は記載しません。
詳細を知りたい方は以下のサイトが分かりやすく解説してくださっています。
https://blog.pyq.jp/entry/Python_kaiketsu_180207

Procfile

herokuでアプリを動かすために必要となるファイル。
使用するWSGIを記載する。今回はgunicornを使用するので以下のような記述になる

web: gunicorn main:app --log-file -

main:appはメイン処理のファイル名によって適宜変えてください。
--log-file -はherokuのログでWSGIの挙動をログ出ししてくれる(省略可)

runtime.txt

このファイルがないとデフォルトで指定されているPythonのバージョン(投稿時ではPython3.9.10)が使用されてしまう。

python-3.7.8

※必ずpythonのpは小文字で記載すること。

requirements.txt

herokuでのビルド時にpip install -r requirements.txtが実行されて必要なライブラリがインストールされる。

開発終了時にpip freeze > requirements.txtで作成する。

.gitignore

不要なファイル・フォルダを記載する。
今回はPython仮想環境が必要ないのでProduct¥を追記する。

herokuへの配置

事前にherokuのサイトでアカウントを作成し、SSH接続できるように公開鍵を登録します。
サイトでログイン後New ⇒ Create new appでアプリを作成します。

gitコマンドでローカルリポジトリへコミットします。

git init
git add .
git commit -m "コミットメッセージ"

herokuへログインしリモートリポジトリへpushします。

heroku login
heroku git:remote -a アプリ名
git push heroku master

もう一度LINE developersへ戻り、Webhookの設定を行う。
Webhook送信:利用する
Webhook URL:https://<アプリ名>.herokuapp.com/callback

ここまで出来ればLINE developersの今回の作成物の設定ページにあるQRコードを読んで友達追加し、動作確認を行うことが出来る。

1
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
7