LINE の Webhook 配信の仕組み

LINE の応答期限は 2 秒で、「Webhookの再送」は初期状態でオフです。確認済みの点と LINE が明かしていない点、x-line-signature の Node 検証コードを掲載しています。

配信の挙動

プロバイダーの公式ドキュメントから読み取っています(最終確認 2026-08-06)。プロバイダーが数値を示していない項目には、この表も数値を載せていません。

応答期限2 秒

ボットサーバーが 2 秒以内に応答しないと request_timeout として扱われる

ハンドラーが期限内に応答するか確認する

リトライ「Webhookの再送」:デフォルトはオフ(チャネルの「Messaging API設定」で有効にする)。回数と間隔は非公開
打ち切りボットサーバーが受信に失敗し続けると、Webhook の送信を停止することがある。しきい値は非公開
出典https://developers.line.biz/en/docs/messaging-api/receiving-messages/

署名

ドキュメントを読んだだけではなく、テストスイートで裏付けた動作する検証コードで確認しています。最終検証日は 2026-08-20 です。

アルゴリズムHMAC-SHA256
署名対象raw body
エンコードbase64
ヘッダーx-line-signature = base64
許容範囲適用なし

検証する

JSON としてパースする前の生のリクエストボディを、バイト単位でそのまま使います。フレームワークがペイロードを再シリアライズした時点で、このページのどの方式も検証に失敗します。

const crypto = require("node:crypto");

// base64(HMAC-SHA256(channel secret, raw body))
const expected = crypto
  .createHmac("sha256", channelSecret) // Messaging API → Basic settings
  .update(rawBody)
  .digest("base64");
const received = Buffer.from(req.headers["x-line-signature"] ?? "");
const wanted = Buffer.from(expected);
// timingSafeEqual throws on a length mismatch, so check that first.
const valid =
  received.length === wanted.length && crypto.timingSafeEqual(received, wanted);

落とし穴

LINE には「Webhookの再送」がありますが、初期状態では無効です。チャネルの「Messaging API設定」で有効にする必要があり、回数や間隔は公開されていません。有効にするまでは、失敗した配信はすべて失われたメッセージになります。

ボットサーバーが受信に失敗し続けると、LINE は Webhook の送信そのものを停止することがあり、そのしきい値は公開されていません。約 1 秒で応答し、保存できないものだけを断る中継サービスを挟めば、この不確定要素の大半はなくなります。

あわせて読む

AnyHook は、LINE から受信するエンドポイントの手前に入ります。約 1 秒で応答し、サーバーがダウンしていれば独自のスケジュールでリトライします。すべてのイベントは再送できる状態で保存されます。 変えるのは URL 1 つだけで、コードはそのままです。

仕組みを見る →