Python（Flask）で作るLINE bot（＋ngrokで公開する方法）

# 概要

Flaskでオウム返しするLINE botを実装する
今回は、デプロイはせず、ngrokで一時的にローカル環境にあるプログラムを外部に公開する

![システム構成イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784580/26c8ee75-3732-d409-0636-a400216dbfbe.jpeg)

本記事では、こちらの記事を参考にさせていただきました
[『FlaskでLINE botを実装し，herokuにdeployするまで』](https://qiita.com/suigin/items/0deb9451f45e351acf92)
[『ngrokが便利すぎる』](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)

# 開発環境

- Windows10
- VScode
- Windows PowerShell
- Python 3.10.4
    - pip 22.0.4
    - Flask 3.0.0
    - line-bot-sdk 3.5.0
    - python-dotenv 1.0.0
- ngrok 3.3.5
- Messaging API

# LINE Developersの設定

Messaging APIを使うための設定を行う

## LINE botのチャネルを作成
[Messaging API公式サイト](https://developers.line.biz/ja/docs/messaging-api/getting-started/)の「1. LINE Developersコンソールでチャネルを作成する」の手順でチャネルを作成する

チャネル作成後、チャネル基本設定に記載されているチャネルシークレットと作成したチャネルアクセストークンをメモしておく


## Messaging APIの設定
今回のLINE bot用にMwssaging APIの設定を変更する

作成したチャネル ＞ Messaging API設定 から「応答メッセージ」と「あいさつメッセージ」の編集を開き、設定を無効にする

# FlaskでLINE botを作成


## パッケージのインストール

ターミナルでPythonのパッケージをインストールする

- flask
    - PythonのWebアプリケーションフレームワーク
- Line-bot-sdk
    - Line botを作成するためのSDK
- python-dotenv
    - 環境変数を呼び出すためのパッケージ

```bash
$ pip install flask
$ pip install line-bot-sdk
$ pip install python-dotenv
```

## 環境変数の作成

.envを作成して、Massaging APIのアクセストークンとシークレットキーを保存する

YOUR_CHANNEL_ACCESS_TOKENをMassaging APIのアクセストークンに変更する
YOUR_CHANNEL_SECRETをMassage APIのシークレットキーに変更する

```.env
CHANNEL_ACCESS_TOKEN='YOUR_CHANNEL_ACCESS_TOKEN'
CHANNEL_SECRET='YOUR_CHANNEL_SECRET'
```

## サンプルプログラムを作成

app.pyでサンプルプログラムを作成する

```Python:app.py
import os
from dotenv import load_dotenv
from flask import Flask, request, abort

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

load_dotenv()

CHANNEL_ACCESS_TOKEN=os.environ["CHANNEL_ACCESS_TOKEN"]
CHANNEL_SECRET=os.environ["CHANNEL_SECRET"]

app = Flask(__name__)

line_bot_api = LineBotApi('CHANNEL_ACCESS_TOKEN')
handler = WebhookHandler('CHANNEL_SECRET')

@app.route("/")
def hello_world():
    return "hello world!"

@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):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))


if __name__ == "__main__":
    app.run()

```
hello_world()はflaskでパスが通っているか確認するためのデバッグ用

callback()で、LINEのユーザからの情報（メッセージなど）を受け取り、handle_message()にeventとして渡す
hadle_message()で、eventに入っているユーザからのメッセージ（event.message.text）をbotの返信にする

# flaskの実行

ローカル環境でflaskを実行する

```bash
$ export FLASK_APP=app.py
$ export FLASK_DEBUG=1
$ flask run --host=0.0.0.0
```

ブラウザで http://localhost:5000 にアクセス
→ hello world!と出力されれば成功

# ngrokの導入・設定

今はローカル環境上で実行しているが、
LINEと繋げて実行するにはローカル環境上のWebサーバを外部に公開する必要がある

ngrokはローカル環境のサーバを一時的に外部に公開できるサービスらしい！さらにhttpsで通信できる！

## ngrokの導入

1. [ngrok公式サイト](https://dashboard.ngrok.com/user/signup)でユーザー登録する
1. [ngrokダウンロードサイト](https://ngrok.com/download)から、ngrokのツールが入ったzipファイルをダウンロード
1. エクスプローラーでダウンロードしたzipファイルを展開
1. 展開したファイル内にあるngrok.exeを開く
1. [ngrok公式サイト](https://dashboard.ngrok.com/user/signup)のlogin後の画面にある「2. Connect your account」に記載されている```$ ngrok config add-authtoken <YOUR AUTHTOKEN>```をコピーして、コマンドプロンプトにペーストして実行
→ 認証トークン情報が登録される
**※コマンドプロンプトでngrokコマンドが使えない時 → [『Windowsの環境パスを通す（path）』](http://realize.jounin.jp/path.html)の手順で、環境変数を設定する**

## ローカルサーバとngrokの接続

1. ローカル上でサーバを立ち上げる
    ```bash
    $ flask run --host=0.0.0.0
    ```
1. ngrokでローカルサーバを外部に公開
    ローカルサーバのポート番号5000をngrokを使って、外部に公開する
    ```Bash
    $ ngrok http 5000
    ```
1. [ngrok公式サイト](https://dashboard.ngrok.com/user/signup)のlogin後の画面にある Cloud Edge ＞ Endpoints に記載されているURL ```https://XXXXXXXX.ngrok-free.app/```（"XXXXXXXX"は人によって異なる）にアクセス
→ hello world!と出力されれば成功

# ngrokとLINE botの接続

1. [LINE Developersコンソール](https://developers.line.biz/console/)の Messaging API設定 > Webhook設定 にあるWebhook URLにngrokのURL ```https://XXXXXXXX.ngrok-free.app/callback``` を入力
    - ```https://XXXXXXXX.ngrok-free.app```：デバック用でhello_world()を実行するためのURL
    - ```https://XXXXXXXX.ngrok-free.app/callback```：LINE botで使用するURL
1. 「検証」をクリックして、「成功」と表示されればOK

# 実行

自分のLINEで[LINE Developersコンソール](https://developers.line.biz/console/)の Messaging API設定 > ボット情報 にあるQRコードから作成したLINE botを友達追加する
LINE botにメッセージを送信し、オウム返ししてくれば完成！

# まとめ

今回はFlaskとngrokでオウムウ返しするLINE botを作成した

実際にサーバにアップロードしていないので一時的にしか使えないですが、開発用の参考になれば幸いです！

## 参考資料

- [ngrok公式サイト](https://ngrok.com/)
- [Messaging API公式サイト](https://developers.line.biz/ja/docs/messaging-api/getting-started/)
- [『FlaskでLINE botを実装し，herokuにdeployするまで』](https://qiita.com/suigin/items/0deb9451f45e351acf92)
- [『ngrokが便利すぎる』](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)
- [『Windowsの環境パスを通す（path）』](http://realize.jounin.jp/path.html)