簡単なLINE botを作ってみようと思い立ち、こちらやこちらの記事を参考にLINE bot用のAPIをVercelに立てようとしたのですが、かなり手こずったので、手こずった箇所のメモを備忘録用に書いておきたいと思います。
ディレクトリ構成
最初は以下のような構成にしていましたが、
my_app/
├ app.py
├ requirements.txt
└ vercel.json
以下の設定でなぜかパスが見つからないと404エラーになり、途方に暮れていました。
{
"rewrites": [
{ "source": "/(.*)", "destination": "/app" }
]
}
後でvercelが挙げているサンプルのflask appの構成を見たところ、api/index.py
と言う構造になっており、このindex.py
内から呼ばないといけないらしいと言うことがわかり
my_app/
├ api/
│ └ index.py
├ requirements.txt
└ vercel.json
構造にし、以下の設定に変えたところ無事表示されました。。なぜなの?
{
"rewrites": [
{ "source": "/(.*)", "destination": "/api/index" }
]
}
handlerと言う変数名
なぜかhandlerを使うところで、idsubclassエラーが出てさっぱりわかりませんでした。。
if not issubclass(base, BaseHTTPRequestHandler)
こちらの記事によると、どうもhandler
と言う変数名がvercelのpythonアプリだと使えないらしい...
そうなの?
サンプルコードだと
handler = WebhookHandler(os.environ["LINE_CHANNEL_SECRET"])
と書いているところが多いが、これをline_handler
にしたところ、出なくなった。
環境変数が反映されない
これは他の記事でも書いてあるところがあるものの、環境変数は一連の「デプロイ」前に設定しておかないとダメらしい。自分の場合はGithubのリポジトリ連携していたので、pushするたびにデプロイが走っていたが、全然環境変数が読み込まれなくて焦った。
Githubからのpush履歴経由でのデプロイの場合は、デプロイキャッシュが使われるのかもしれない。
とりあえずredeployボタンを押して、デプロイし直したところ環境変数が読み込まれた。
ルート以外に置いたファイルが読み込まれない
以下のディレクトリでapi/index.pyファイルからtoken.jsonを読み込みたかった場合に、ファイルパスとして./token.json
を指定したが、ローカルならもちろんこのコードは動くものの、vercel内でこのindex.pyを実行するとtoken.jsonが見つかりませんエラーが出て悩まされた。あるんだが???
どうもvercelでファイルを読み込むときに、実行しているファイルからの相対パスではなく、実行しているアプリのルートディレクトリから読み込まれるらしく、ルートディレクトリにこのtoken.jsonを置いたところ(index.py内でのパス指定は変えず)無事に読み込まれた。
vercel、落とし穴がたくさんありすぎる。。。
これを
my_app/
├ api/
│ └ index.py|
│ └ token.json
├ requirements.txt
└ vercel.json
こうした。
my_app/
├ api/
│ └ index.py|
├ requirements.txt
├ token.json
└ vercel.json
終わりに
vercel.jsonの書き方についても、ある程度ググった後にVercelが出しているサンプルアプリのソースまで見ないと最新のプラクティスがわからなくて困った。うーむ。