Line Messaging APIでの400Error【未解決】
4分目次
最近 Slack や Line の Bot 作りにハマってる。Web 系の技術でもネイティブの開発をできている感じが心地いい。そんな中エラーが出てハマったのでその備忘録。
環境
- Heroku
- Node >=10.0.0
- @line/bot-sdk 7.2.0,
その他 Express やら Prisma やら使っているがエラーとは関係なさそうなので割愛
エラー内容
基本的な仕様として
A. ユーザーから受け付けたメッセージをおうむ返し B. メッセージ内に特定の文字列が含まれる場合、任意の文字列を送信する
という単純なもの。この 2 つのうち、B が成功することもあれば失敗することもある(A は失敗しない)
エラーメッセージ
/app/node_modules/@line/bot-sdk/dist/http.js:89
return new exceptions_1.HTTPError(err.message, err.response.status, err.response.statusText, err);
^
HTTPError: Request failed with status code 400
at HTTPClient.wrapError (/app/node_modules/@line/bot-sdk/dist/http.js:89:20)
at /app/node_modules/@line/bot-sdk/dist/http.js:19:88
at processTicksAndRejections (node:internal/process/task_queues:94:5)
at async HTTPClient.post (/app/node_modules/@line/bot-sdk/dist/http.js:33:21) {
statusCode: 400,
statusMessage: 'Bad Request',
originalError: Error: Request failed with status code 400
at createError (/app/node_modules/axios/lib/core/createError.js:16:15)
at settle (/app/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/app/node_modules/axios/lib/adapters/http.js:244:11)
at IncomingMessage.emit (node:events:390:22)
at endReadableNT (node:internal/streams/readable:1307:12)
at processTicksAndRejections (node:internal/process/task_queues:81:21) {
config: { ... },
LineBot SDK を使用すると/hook
という URI に POST を飛ばす形だが、それが処理できていない模様。
ちなみに LINE Bot ではカルーセルやリッチなメッセージを飛ばすことができるがそういったことはしていない単純なおうむ返し部分でもエラーが出る。
集めた情報色々
すぐに応答するようにする
応答トークンは一定の期間が経過すると無効になるため、メッセージを受信したらすぐに応答を返す必要があります。応答トークンは 1 回のみ使用できます。
Ref: Messaging API リファレンス
すぐにっていうのが具体的にどれくらいなのか分からないけど早くするといいらしい
『Verify』ボタン押下時のエラーならしょうがないものとして受け入れる
LINE developers のサイトの「VERIFY」ボタンを押した時に、サーバーのログに LineBotApiError [Invalid reply token] のメッセージが出ているかと思います。LINE さんに確認したところ、「VERIFY」の処理は疎通確認が主なので、Token の整合性までは意識していない処理になっている(?) とのことで、LINE アプリからの応答処理でサーバーに本件のエラーメッセージが出ていなければ問題無さそうでした。本件は問い合わせも何件かきているので、修正していく方針とのことでした。そのうち出なくなる現象と思われます。
ref: GAE で LINE Message API(line-bot-sdk-python)を試してみた
これは僕のエラーとは異なるけどこういうこともあるそうな
Webhook URI に正しい URI を設定する
It is not a real request. The verify test sends a dummy request with invalid replyToken, and it’s the reason why the reply API fails. Please try with actual requests sent from the LINE app.
ref: Echo bot - Request failed with status code 400 #65
これも僕は正しく設定していたので異なるけどこういうこともあるそうな
暫定解決法
const hogeFunc = (event) => {
return client
.replyMessage(event.replyToken, {
type: "text",
text: "ホゲ〜",
})
.catch((err) => console.log(err.message));
};
const handleMessage = async (event) => {
const { displayName } = await client.getProfile(event.source.userId);
const text = event.message.type === "text" ? event.message.text : "";
if (text === "hoge") hogeFunc(event);
// オウム返し
return client
.replyMessage(event.replyToken, {
type: "text",
text: `${displayName}「${text}」`,
})
.catch((err) => console.log(err.message));
};
上記コードを下のように変更したら直った
const handleMessage = async (event) => {
const { displayName } = await client.getProfile(event.source.userId);
const text = event.message.type === "text" ? event.message.text : "";
if (text === "hoge") {
return client
.replyMessage(event.replyToken, {
type: "text",
text: "ホゲ〜",
})
.catch((err) => console.log(err.message));
}
// オウム返し
return client
.replyMessage(event.replyToken, {
type: "text",
text: `${displayName}「${text}」`,
})
.catch((err) => console.log(err.message));
};
ただ全然根本的な解決じゃない上に汎用性のかけらもないので未解決としました