LINE Messaging API
一個 Verify 按鈕一次就過的 webhook 網址。
Console 要求 https、按 Verify 要拿到 200 才肯存檔;重新傳送藏在開關後面而且預設關閉;LINE 又從不公佈重試頻率。AnyHook 替你回 Verify、在 edge 把每個事件存下來,然後用你看得到的排程重試你的 handler。
時序問題
LINE Developers Console 不收非 https 的 Webhook URL,旁邊的 Verify 按鈕會真的打一個 POST 過來,必須回 200 才存得進去。tunnel 可以過一次,但網址一輪替,你的 bot 就指著一個不存在的地方,console 不會提醒你。更深的問題在漏接之後:webhook 重新傳送出廠就是關的,就算打開,LINE 官方直接寫明重試次數與間隔不公開、隨時可能改。
回覆這一側還有自己的時鐘。reply token 有效期一分鐘、只能用一次,所以 crash、部署、或重試之後才處理到的事件,已經沒辦法用免費的 reply 回了。而 bot server 失聯太久,LINE 可能整個停止對它送 webhook,這個門檻同樣沒有公開數字。
關
重新傳送的出廠設定,漏接的 webhook 就是沒了
200
Verify 按鈕存檔前要看到的回應
1 分鐘
reply token 的壽命,而且只能用一次
?
LINE 公開的重試次數與間隔:沒有
把 console 指到 AnyHook,只驗一個標頭
app 的 source 設成 LINE、貼上 Channel Secret:AnyHook 就在 edge 驗 x-line-signature(raw body 的 HMAC-SHA256,base64),偽造的請求到不了你的伺服器、也不花你的額度。每次投遞都重新簽好 AnyHook-Signature。
// 1. AnyHook 這邊:把 app 的 source 設成 LINE,貼上 Channel Secret。
//
// 2. LINE Developers Console -> Messaging API:
// Webhook URL: https://in.anyhook.net/{user-slug}/{app-slug}
// 按 Verify(AnyHook 會回 200)、打開「Use webhook」,
// 順手把「Webhook redelivery」也打開。
import { verifyWebhook } from "anyhook-verify";
export async function POST(req: Request) {
const ok = await verifyWebhook(req, process.env.ANYHOOK_SIGNING_SECRET!);
if (!ok) return new Response("invalid signature", { status: 401 });
const event = await req.json();
for (const e of event.payload.events ?? []) {
if (e.type !== "message") continue;
const answer = await draftAnswer(e.message); // LLM 呼叫,幾秒
// reply token 一分鐘就過期、只能用一次。重試進來的投遞
// token 已經死了,所以失敗就改走 push,不要把回覆丟掉。
try {
await lineReply(e.replyToken, answer);
} catch {
await linePush(e.source.userId, answer);
}
}
return new Response("ok", { status: 200 });
}工程團隊常問的問題
- Console 的 Verify 按鈕一直失敗,它到底要什麼?
- 它會對網址打一個 events 是空陣列的 POST,要求 https 且回純粹的 200。本機 tunnel 偶爾能過,網址一輪替就斷。AnyHook 的 inbound 網址是固定的 https 端點,事件確實排入佇列才回 200,所以 Verify 第一次就過,之後也一直過。還有一件事要知道:LINE 連這個驗證 POST 都會用 Channel Secret 簽章,所以 source 設成 LINE 之後 Verify 還是失敗,最常見的原因是 secret 貼錯。AnyHook 會在 edge 直接回 401,而被拒絕的請求不會出現在 event log 裡,是 app 設定頁上方會出現一條 edge-reject 橫幅。重貼一次 secret 再按 Verify 就好。
- x-line-signature 是 AnyHook 驗,還是我的伺服器驗?
- AnyHook 在 edge 驗:app 的 source 設成 LINE、填了 Channel Secret 之後,驗不過的請求根本到不了你的伺服器,也不會花額度。你的伺服器只要驗一個統一的 AnyHook-Signature 標頭。原本的 x-line-signature 仍會原封轉發,而且 LINE 的簽章只簽 body、沒有時間戳,重試時依然有效,想在下游再驗一次也可以。
- 投遞被重試的時候,reply token 怎麼辦?
- 幾乎一定過期了,token 從原始 webhook 起算只活一分鐘。可行的模式是:第一次、最快的那次投遞用 reply 回,reply 失敗就改走 push。AnyHook 兩種情況都保留完整事件內容,晚到的 handler 還是清楚對方說了什麼。
- AnyHook 都會重試了,LINE 自己的重新傳送還要開嗎?
- 要。兩者管的是不同一段路。AnyHook 重試的是事件存下來之後、AnyHook 到你伺服器這段;LINE 的重新傳送管的是 LINE 到 AnyHook 這段,在 AnyHook 真的無處可存、刻意回 503 請寄件方再試的罕見情況下,它就是最後的保險。
改一個 URL,保留你的 LINE handler。
Free tier 每月含 3,000 events。沒有 SDK、沒有 code 變更,把 LINE 指到你的 AnyHook inbound URL 就好。