tentekoten
@tentekoten

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

pythonのlinebot実装でimport linebot.modelsのエラー対処方法

解決したいこと

pythonでlinebotのおうむ返し機能の実装を試したところ10行目のlinebot.modelsのimportにエラーが出たので対処方法を教えてください。

発生している問題・エラー

2022-06-15T17:35:41.111714+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=POST path="/callback" host=.com request_id= fwd="" dyno= connect= service= status=503 bytes= protocol=https

該当するソースコード

from flask import Flask, request, abort
import os

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

app = Flask(__name__)

#環境変数取得
YOUR_CHANNEL_ACCESS_TOKEN = os.environ.get[""]
YOUR_CHANNEL_SECRET = os.environ.get[""]

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_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)
    print("----1----")
    print(body)
    print("----2----")

    # 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()
    port = int(os.getenv("PORT", 8080))
    app.run(host="0.0.0.0", port=port, debug=True)

自分で試したこと

自分のコードは以下のリンクを参考にしました。10行目のTextSendMessageの後ろの,を外したりしてみましたが変わらずエラーが発生しました。
https://qiita.com/kro/items/67f7510b36945eb9689b

以下のリンクを参考にFollowEventをlinbot.modelsに追加しましたが依然変わらず同じエラーが出力されました。
https://teratail.com/questions/204232

0

1Answer

pythonでlinebotのおうむ返し機能の実装を試したところ10行目のlinebot.modelsのimportにエラーが出たので対処方法を教えてください。

もしかすると、code=H10これから10行目でエラーが出ていると判断したのかもしれないですが、これはエラーコードでエラーが出ている行数ではないです。
おそらくエラーの原因は別のところにあると思います。

そちらのエラーコードについては、こちらの記事などが参考になるかもしれません。

1点気になる点ですが、記載したコード上では環境変数名が空になっています。
こちら実際のコードでは、環境変数名が指定されておりますでしょうか?
実際のコードでも空のままであれば、こちらを修正すれば改善するかもしれません。

YOUR_CHANNEL_ACCESS_TOKEN = os.environ.get[""]
YOUR_CHANNEL_SECRET = os.environ.get[""]
1Like

Comments

  1. @tentekoten

    Questioner

    こちらは自分のプロジェクトのTokenとSecretを使用しています!個人情報なので質問の際に一部伐採させて頂きました!間際らしくてすみません。
  2. @tentekoten

    Questioner

    それと提示して頂いた記事は既に参考済みでコードをそのように修正してみましたが依然エラーのままでした!
  3. 念のための確認ですが、os.environ.getメソッドの引数にTokenの文字列を直書きしていないでしょうか?

    コードにTokenなどの文字列を記載しないようにherokuの環境変数にTokenなどを埋め込んで、以下のように環境変数の名前が記述されているのが正しいと思うのですが、そうなっていますでしょうか?

    LINE_CHANNEL_ACCESS_TOKEN = os.environ["LINE_CHANNEL_ACCESS_TOKEN"]

    記載のソースでは、あえて空文字にしているようですので、そこに直書きしているのかと思った次第です。
  4. @tentekoten

    Questioner

    理解しました。ありがとうございます!
    以下のようにして実行してみたのですがエラーのままでした。これでもおかしいですか?

    #環境変数取得
    LINE_CHANNEL_ACCESS_TOKEN = "マイトークン"
    LINE_CHANNEL_SECRET = "マイシークレット"

    line_bot_api = LineBotApi(os.environ.get('LINE_CHANNEL_ACCESS_TOKEN'))
    handler = WebhookHandler(os.environ.get('LINE_CHANNEL_SECRET'))
  5. それだと上2行は必要ないです。
    下2行のみで環境変数から値を取得できるようにはなっていると思います。

    LINE_CHANNEL_ACCESS_TOKEN = "マイトークン"
    ⇒変数「LINE_CHANNEL_ACCESS_TOKEN」にTokenの値を書き込む

    os.environ.get('LINE_CHANNEL_ACCESS_TOKEN')
    ⇒「LINE_CHANNEL_ACCESS_TOKEN」というKey名の環境変数を取得
      変数「LINE_CHANNEL_ACCESS_TOKEN」とは無関係です。


    エラーのままということですが、heroku側の環境変数を一度確認したほうがいいかもしれません。

    webでherokuにログインして、「Settings」タブの「Config Vars」に、「LINE_CHANNEL_ACCESS_TOKEN」「INE_CHANNEL_SECRET」というKey名で値が設定されていますでしょうか?
  6. @tentekoten

    Questioner

    このように''を外し上の2行を取得。改善すればよろしいですか?

    #環境変数取得
    LINE_CHANNEL_ACCESS_TOKEN = "マイトークン"
    LINE_CHANNEL_SECRET = "マイシークレット"

    line_bot_api = LineBotApi(os.environ.get(LINE_CHANNEL_ACCESS_TOKEN))
    handler = WebhookHandler(os.environ.get(LINE_CHANNEL_SECRET))
  7. すみません、おそらく前のコメントの編集とかぶりましたね。

    「os.environ.get」これは環境変数から値を取得するメソッドです。
    それだとトークンのランダムの文字列をKeyとした環境変数を取得しようとしていることになります。


    そもそもソースコードにトークンなどの値を直書きすることはお勧めできません。
    先ほどのコメントに記載してあるherokuサーバの環境変数の設定画面から、「LINE_CHANNEL_ACCESS_TOKEN」「INE_CHANNEL_SECRET」というKeyで値を設定したうえで、以下のようにソースコードを記述して実行してみてください。

    line_bot_api = LineBotApi(os.environ.get('LINE_CHANNEL_ACCESS_TOKEN'))
    handler = WebhookHandler(os.environ.get('LINE_CHANNEL_SECRET'))
  8. @tentekoten

    Questioner

    やっと理解しました!お手数お掛けしてすみませんでした!configにkeyの値をYottyPGさんがおっしゃった変数名でsetして同じようにデプロイしたら無事作動しました!ありがとうございます!
    ちなみにLINE_CHANNEL_ACCESS_TOKENとLINE_CHANNEL_SECRETなどのメソッドはどこからimportされているのですか?
  9. 無事動作したようでよかったです!


    「LINE_CHANNEL_ACCESS_TOKEN」はただの文字列です。
    herokuの環境変数にKey「LINE_CHANNEL_ACCESS_TOKEN」という文字列で登録すると、
    os.environ.get('LINE_CHANNEL_ACCESS_TOKEN')としてその値が取得できるというだけのことです。

    環境変数のKeyとos.environ.getの引数の文字列が同じであれば、どんな文字列でも問題はないです!
  10. @tentekoten

    Questioner

    なるほど深く理解できました!本当にありがとうございます!ここから自分なりに色々応用していきたいと思います!

Your answer might help someone💌