【ngrok】LINE botとflaskアプリを連携する

# Goal

`LINE bot`と`flaskアプリ`を`ngrok経由`で連携する。
LINE botがいるスペースでメッセージ送信するとflaskアプリにHTTPリクエストが届くことを目指す。

# Environment

- LINE側
    - LINE Messaging API v2

- flaskアプリ側
    - OS: Raspbian GNU/Linux 10 (buster)
    - ngrok version 3.1.0
    - Python 3.8.13
    - Flask 2.2.2

# What ngrok

[ngrok](https://ngrok.com/
)はインターネット上の通信をローカルサーバへもってくることができるトンネリングサービス。

通常ローカルのWebサーバを公開するには、色々と手順が必要。最近はHerokuやAWS Lightsailで公開がだいぶしやすくなってきた。ただ、どちらも費用が発生するので手軽に検証したいという時は少し不便。

ngrokは柔軟性は下がるが、Webサーバを公開するには必要十分なものである。なにより手軽。HTTPをはじめSSHも可能なので、自宅のサーバのSSHを公開することも可能。

ただし、無料版ではネックな制限がかかるので本番環境での運用はおすすめしない。（根気があればできる？？）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113802/9fb6f79b-6302-3a1b-e192-c10d03340f25.png)

# 1. Create ngrok account.

ブラウザにて、[ngrokのアカウントを作成する。](https://dashboard.ngrok.com/signup)

# 2. Install ngrok command to your computer.

`flaskアプリ`があるサーバで、ngrokコマンドをインストールする。OS問わずどれでもいけそう。

[公式に手順がある。](https://ngrok.com/download)

- 手動インストール
- apt
- snap

たぶん、yumでも方法はある。

`token`は「Getting Started」の「Your Authtoken」に記載がある。

# 3. Start a tunnel

`flaskアプリ`があるサーバにて、`ngrok http 80`を実行すると、下記のような情報が表示される。

```
ngrok                                                                                                                                                                                                                         (Ctrl+C to quit)
                                                                                                                                                                                                                                              
Add Single Sign-On to your ngrok dashboard via your Identity Provider: https://ngrok.com/dashSSO                                                                                                                                              
                                                                                                                                                                                                                                              
Session Status                online                                                                                                                                                                                                          
Account                       Your Account (Plan: Free)                                                                                                                                                                                          
Update                        update available (version 3.1.1, Ctrl-U to update)                                                                                                                                                              
Version                       3.1.0                                                                                                                                                                                                           
Region                        Japan (jp)                                                                                                                                                                                                      
Latency                       8ms                                                                                                                                                                                                             
Web Interface                 http://127.0.0.1:4040                                                                                                                                                                                           
Forwarding                    https://xxxxxxxxx.jp.ngrok.io -> http://localhost:80                                                                                                                          
                                                                                                                                                                                                                                              
Connections                   ttl     opn     rt1     rt5     p50     p90                                                                                                                                                                     
                              0       0       0.00    0.00    0.00    0.00
```

このうち、`Forwarding`の`https://xxxxxxxxxxx.jp.ngrok.io`を控える。

`https://xxxxxxxxxxx.jp.ngrok.io -> http://localhost:80`は`ngork.io`にきたリクエストを`localhost:80`に飛ばすことを意味する。

# 4. Setting Webhook in LINE Messaging API

LINE botがメッセージ受信時に、LINE Messaging APIのWebhookが飛ばすリクエストの送信先を設定する。設定はブラウザで行う。

LINE Developersにログイン後、[LINE Developers Console](https://developers.line.biz/console/)に移動してボットを選択する。その後、`Messaging API設定`で下記の設定を行う。

- 「Webhookの利用」: ON
- 「Webhook URL」: `https://xxxxxxxxxxx.jp.ngrok.io`

# 5. Build and run Flask App

`flaskアプリ`があるサーバにて、`Flask`を`pip install`して、アプリを立ち上げる。ポートは80を指定。
LINE botがメッセージを受信すると、LINE Messaging APIは指定URLへPOSTリクエストを送信するためPOSTで公開しておく。

```bash
python -m venv venv
source venv/bin/activate
pip install flask
vim hello.py
# Setting flask app file and run.
FLASK_APP=hello.py flask run -p 80
```

```python:hello.py
from flask import Flask

app = Flask(__name__)

@app.route("/", methods=["POST"])
def reply():
    print("Hello ngrok")
    return "Hello World"
```

# 6. Check Received HTTP request in ngrok and flask app

LINE botのスぺースでメッセージを送信する。そうすると、`raspi`の例のngrokでは下記のように表示される。

```
ngrok                                                                                                                                                                                                                         (Ctrl+C to quit)
                                                                                                                                                                                                                                              
Add Single Sign-On to your ngrok dashboard via your Identity Provider: https://ngrok.com/dashSSO                                                                                                                                              
                                                                                                                                                                                                                                              
Session Status                online                                                                                                                                                                                                          
Account                       sagaziiin (Plan: Free)                                                                                                                                                                                          
Update                        update available (version 3.1.1, Ctrl-U to update)                                                                                                                                                              
Version                       3.1.0                                                                                                                                                                                                           
Region                        Japan (jp)                                                                                                                                                                                                      
Latency                       7ms                                                                                                                                                                                                             
Web Interface                 http://127.0.0.1:4040                                                                                                                                                                                           
Forwarding                    https://6c45-240b-11-10c3-3900-e65f-1ff-fe1f-16ce.jp.ngrok.io -> http://localhost:8888                                                                                                                          
                                                                                                                                                                                                                                              
Connections                   ttl     opn     rt1     rt5     p50     p90                                                                                                                                                                     
                              2       0       0.02    0.01    0.01    0.02                                                                                                                                                                    
                                                                                                                                                                                                                                              
HTTP Requests                                                                                                                                                                                                                                 
-------------                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                              
POST /                         200 OK
```

また、`flask app`でもPOSTリクエストが来たことを確認できる。

あとはPOSTリクエストの中身を処理するプログラムを書けば、LINEとflaskアプリの連携が可能になる。

# 7. 注意点

- ngrokのフリープランの場合、ngrokコマンドを終了して、再実行すると公開URLが変化する。その場合、再起動時にLINE Webhookも変更する必要がでてくる。

以上。