Python(Flask)とherokuを使ったLINEBOT開発でエラーが出てないのにオウム返しできない時

最初に

PythonでFlaskとherokuを使用した初歩的なオウム返しLINE BOTを開発していましたが、heroku logsでログを確認しても特にエラーが出てないのにオウム返しできずにいました。 今回先輩など多くの方にアドバイスを頂き解決したので備忘録として記事をかきます。

解決法

以下が、僕がオウム返しできなかったPythonコードです。

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

app = Flask(__name__)

line_bot_api = LineBotApi('LINE_CHANNEL_ACCESS_TOKEN')
handler = WebhookHandler('LINE_CHANNEL_SECRET')

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

@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'

@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__":
    port = int(os.getenv("PORT"))
    app.run(host="0.0.0.0", port=port)

上記のコードは以下の記事を参考にしました。 https://qiita.com/suigin/items/0deb9451f45e351acf92

Pythonとなったら今まで何回お世話になったか分からないくらいプロプロの先輩(TwitterID: @JUN_NETWORK)に聞きまくった結果、原因として以下が挙げられました。

FlaskではデフォルトでデバッグモードがOFFとなっています。デフォルトでOFFなおかげで、本番環境でうっかり--productionのような本番用にスイッチするためのオプションを付け忘れて、デバッグ画面が表示してしまうようなことはありません。

引用:[https://www.subarunari.com/entry/2018/03/10/%E3%81%84%E3%81%BE%E3%81%95%E3%82%89%E3%81%AA%E3%81%8C%E3%82%89_Flask%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%BE%E3%81%A8%E3%82%81%E3%82%8B%E3%80%9CDebugger%E3%80%9C]

よって、

app = Flask(__name__)

の下に、

app = Flask(__name__)
app.debug = False

をつけることによってFlaskのデバッグモードをFalseにしました。

結果、無事治ってオウム返しできました。

デバッグモードをFlaseにしたのに治らない場合、以下の確認をしてみてください。

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

コードの最後がこうなっていた場合、僕の使用した環境では正常に動いてくれませんでした。 これはngrockなどを使用してローカル環境で実行するとちゃんと動いてくれるのですが、サーバをherokuにした途端動いてくれません。これはローカルならローカルで動く環境、herokuならherokuでちゃんと動く環境に適した書き方(自分でも何言ってるかわかんないんで間違ってたらごめん)をしないといけないらしいです。

よって、以下のように書き換えます。

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

これら以外でBOTが正常に動いてくれない場合、herokuでのLINEアクセストークンやシリアルキーの設定、名前があっているかなど確認しましょう。

今回は以上ですお読みいただきありがとうございました。