6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[python] 簡単な応答ができるLineBotを作ってみた(Flask+ngrok)

Last updated at Posted at 2023-11-04

はじめに

Line Messaging API, line-bot-sdkを使ってPythonで簡単なLineBotを実装した際の備忘録。
今回はユーザーのチャットへの自動返答、Flaskとngrokを用いたサーバーの実装と公開までをやります。
以前はHerokuを使って実装していましたが、無料プランの終了に伴い、Flask + ngrokで実装しました。

開発環境

  • Ubuntu 20.04
  • python 3.9.13
  • Flask 1.1.2
  • line-bot-sdk 3.5.0
  • ngrok-v3-stable-linux-amd64

大まかな流れ

FlaskとLINEBotSDKでPythonプログラム(main.py)を実装
→ ngrokでローカルサーバーを外部公開
→ Webhookを利用してLINE Messaging APIを介してやり取り

スクリーンショット 2023-11-05 015737.png

LINE Developersの登録とBotの設定

まずはBotを利用するために開発者コンソールへのログインと、Botの作成・設定をしていきます。

1. コンソールへログイン & Bot作成

LINE Developers へアクセスし、コンソールにログインをクリック
image.png

ビジネスアカウントでも普通のアカウントどちらでも良いのでお持ちのアカウントでログイン(万が一ない場合はアカウントを作成)
image.png

右画面下部、プロバイダー欄の作成ボタンを押してプロバイダー名を入力
image.png

チャネル設定でMessagingAPIを選択し、各種項目を入力して作成
image.png

これでBotが作成できました。

2. Botの各種設定

ではBotの設定をしていきます。

まず、画面下部にチャンネルシークレットという項目があるので、そこに記載されている文字列を確認します。後で必要になりますので確認方法を覚えておきます。
image.png

画面上部に行き、Messaging API設定タブをクリックします。
image.png

最下部にチャンネルアクセストークンの項目があるので、発行を押してトークンを発行します。
APIのアクセストークンは外部に知られると悪用される恐れがあるので慎重に扱います。
こちらも後で必要になります。
image.png

チャネル基本設定タブに移動
基本情報の下にLINE Official Account Managerへのリンクがあるのでクリックして移動
image.png

アカウント設定の画面が表示されるかと思います。
画面左側の応答設定をクリックして応答設定の画面を開き、画像内の上から三番目の項目『Webhook』をオンにします。
その他3つの項目は今回は必要ないのでオフにしておきます。
image.png

ここで一旦Botの設定は終了です。

Botの実装

Pythonのインストール、必要であれば仮想環境の準備等は終わっているものとします。

1. 各種ライブラリのインストール

Flask, LINEBotSDKをインストール

pip install flask
pip install line-bot-sdk

2. Pythonプログラム

こちらが今回使用したプログラムになります。
じゃんけんの技を送ると後出しで必ず勝ってくるだけの簡単なBotです。
プログラムはSDKのGitHubに記載されていたサンプルコードを少しだけ改変したものになります。

main.py
import os
from flask import Flask, abort, request
from linebot.v3.webhook import (
    WebhookHandler
)
from linebot.v3.exceptions import (
    InvalidSignatureError
)
from linebot.v3.messaging import (
    Configuration,
    ApiClient,
    MessagingApi,
    ReplyMessageRequest,
    TextMessage
)
from linebot.v3.webhooks import (
    MessageEvent,
    TextMessageContent
)


app = Flask(__name__)

handler = WebhookHandler('YOUR_CHANNEL_SECRET')
configuration = Configuration(access_token='YOUR_CHANNEL_ACCESS_TOKEN')


@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:
        app.logger.info("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessageContent)
def handle_message(event):
    with ApiClient(configuration) as api_client:
        #相手の送信した内容で条件分岐して回答を変数に代入
        if event.message.text == 'グー':
            msg = 'パー'
        elif event.message.text == 'チョキ':
            msg = 'グー'
        elif event.message.text == 'パー':
            msg = 'チョキ'
        else:
            msg = 'ごめんね。\nまだ他のメッセージには対応してないよ'

        line_bot_api = MessagingApi(api_client)
        line_bot_api.reply_message_with_http_info(
            ReplyMessageRequest(
                reply_token=event.reply_token,
                messages=[TextMessage(text=msg)]
            )
        )


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

'YOUR_CHANNEL_SECRET'の部分は先程確認したチャンネルシークレット、
'YOUR_CHANNEL_ACCESS_TOKEN'はチャンネルアクセストークンに置き換えます。

注意
※ソースコードにこれらの情報を記載するのはセキュリティ上あまりよろしくない為、心配な方は環境変数を用いるなど適宜対応して下さい。
参考 → 【Python】トークンなどの認証情報は環境変数で管理しよう

ngrokのインストールと設定

1. インストール

※Ubuntu環境でのインストール方法になります。Windows等でのインストール方法は下記の記事を参考に進めて下さい。


ngrokをダウンロードし、解凍した中身を/usr/binに配置します。
そのままでは実行時に権限のエラーが出たので権限も変更します。
下記のコマンドを実行することで行なえます。

wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz #ダウンロード
tar -zxvf ngrok-v3-stable-linux-amd64.tgz #解凍
sudo mv ngrok /usr/bin #/usr/binへ移動
sudo chmod +x /usr/bin/ngrok #権限の変更

下記コマンドで起動確認します。
下記の様にバージョンが表示されればインストールは完了です。

ngrok version
> ngrok version 3.4.0

2. アカウント認証

ngrokに移動します。
ログインしていない場合はログインします。アカウントがなければ作成してログインします。
画面下部の『Connect your account』という欄に記載されているコマンドを実行して認証を行います。
image.png

3. 固定ドメインの設定

このままでも利用はできますが、ngrokを起動するたびにWebhook用のURLが変わってしまいます。
後々設定しますが、Webhookを利用するために先程の開発者コンソール画面でWebhook用のURLを入力しなければいけません。
今のままではngrokを再起動する度にそのURLを変更しに行かなければならず、とても面倒です。
そこで、ngrokのドメインを固定します。これで毎回URLを更新しに行く必要がなくなります。

Domains-ngrokへ移動し、画面右の『New Domain』をクリックして、出てきたポップアップの『Create Domain』をクリックして作成します。
その後出てくる画面に下記の様なコマンドが記載されているかと思います。こちらは生成したドメインに指定して実行する際のコマンドです。

ngrok http --domain=<生成された固有文字列>.ngrok-free.app 80

上記の<生成された固有文字列>がドメインの固定部分になります。
上記コマンドではポートの指定が80になっていますが、今回はポートを5000にしてプログラムを実装しているので、今回使用する起動コマンドは以下になります。

ngrok http --domain=<生成された固有文字列>.ngrok-free.app 5000

<生成された固有文字列>の部分はご自身のものに置き換えて実行して下さい。

実際に動かしてみる

では実際にプログラムの起動とサーバーの公開をしていきます。

ngrokの起動

まずはngrokを起動します。

ngrok http --domain=<生成された固有文字列>.ngrok-free.app 5000

すると下記のような画面が出るかと思いますので、『Forwarding』の https://<生成された固有文字列>.ngrok-free.app の部分をコピーします。

ngrok                                                                                               (Ctrl+C to quit)
                                                                                                                    
Introducing Always-On Global Server Load Balancer: https://ngrok.com/r/gslb                                         
                                                                                                                    
Session Status                online                                                                                
Account                       Naru (Plan: Free)                                                                     
Version                       3.4.0                                                                                 
Region                        Japan (jp)                                                                            
Latency                       -                                                                                     
Web Interface                 http://127.0.0.1:4040                                                                 
Forwarding                    https://<生成された固有文字列>.ngrok-free.app -> http://localhost:5000               
                                                                                                                    
Connections                   ttl     opn     rt1     rt5     p50     p90                                           
                              0       0       0.00    0.00    0.00    0.00

BotにWebhookURLを設定

LINE Developers コンソール へアクセスし、作成したBotをクリックして先程の設定画面まで行きます。
MessagingAPI設定タブへ移動し、Webhook URLの『編集』をクリック。
先程コピーしたURLを貼り付け、末尾に『/callback』を付け加えたら、『更新』をクリックします。
その後、Webhookの利用をオンにします。
image.png

main.pyの起動

最後にmain.pyを起動します。

python main.py

すると下記のような出力が得られると思います。

 * Serving Flask app "main" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://xxx.xxx.xxx.xxx:5000/ (Press CTRL+C to quit)

LINEで送ってみよう

全て準備が整ったので実際にLINEでチャットを送信してみます。
まず、先程のLINE Developers コンソール のMessagingAPI設定タブにQRコードがあるので、それを読み取ってBotを友達に追加します。
追加できたらトーク画面で実際にチャットを送信してみましょう。
何も問題が無ければ下記画像のように後出しで勝ち続けてきます。

最後に

今回はPythonでLineBotを実装してみました。
結構簡単に実装できますね。
気が向いたらChatGPTと組み合わせてChatBotでも作ってみたいです。

参考

6
3
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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?