教學

@line/bot-sdk Express 中介軟體:replyMessage 與 validateSignature 完整範例

@line/bot-sdk Express 中介軟體實戰:webhook 簽章驗證、replyMessage 與 sentMessages、錯誤處理、TypeScript 型別。可直接上線的程式碼。

LineBot.pro Team11 分鐘閱讀
@line/bot-sdk Express 中介軟體:replyMessage 與 validateSignature 完整範例

#為什麼需要 Express 中介軟體?

官方 @line/bot-sdk 內含 Express 中介軟體,自動完成兩件事:

  1. HMAC-SHA256 簽章驗證x-line-signature 標頭)
  2. 解析 JSON body,簽章錯誤時回傳 401

建議搭配閱讀:LINE 聊天機器人教學LINE API 整合

#安裝與專案設定

bash
npm init -y
npm i express @line/bot-sdk
npm i -D typescript @types/express ts-node-dev
bash
LINE_CHANNEL_ACCESS_TOKEN=...
LINE_CHANNEL_SECRET=...

#最小可執行範例

ts
import express from "express"
import { middleware, messagingApi, WebhookEvent } from "@line/bot-sdk"

const config = {
  channelAccessToken: process.env.LINE_CHANNEL_ACCESS_TOKEN!,
  channelSecret: process.env.LINE_CHANNEL_SECRET!,
}
const client = new messagingApi.MessagingApiClient({ channelAccessToken: config.channelAccessToken })

const app = express()
app.post("/webhook", middleware(config), async (req, res) => {
  const events: WebhookEvent[] = req.body.events
  await Promise.all(events.map(handleEvent))
  res.status(200).end()
})

async function handleEvent(event: WebhookEvent) {
  if (event.type !== "message" || event.message.type !== "text") return
  const r = await client.replyMessage({
    replyToken: event.replyToken,
    messages: [{ type: "text", text: `Echo: ${event.message.text}` }],
  })
  console.log(r.sentMessages.map(m => m.id))
}

app.listen(3000)

LINE Bot webhook 架構
LINE Bot webhook 架構

#validateSignature() 運作原理

ts
import crypto from "node:crypto"

function validateSignature(body, secret, signature) {
  const computed = crypto.createHmac("sha256", secret).update(body).digest("base64")
  return crypto.timingSafeEqual(Buffer.from(computed), Buffer.from(signature))
}

常見失敗情況:

  • express.json() 放在 middleware 之前
  • 反向代理改寫 Content-Length
  • channelSecret 結尾有換行字元

#replyMessage(replyToken, ...) — 完整範例

replyToken 必須在 30 秒內使用,且只能使用一次。

ts
await client.replyMessage({
  replyToken: event.replyToken,
  messages: [
    { type: "text", text: "你好!" },
    { type: "flex", altText: "預約確認", contents: { type: "bubble", body: { type: "box", layout: "vertical", contents: [{ type: "text", text: "預約確認", weight: "bold" }] } } },
  ],
})

每次 replyMessage 最多可傳 5 則訊息

#ReplyMessageResponse.sentMessages

SDK v9(2024)起:

ts
type ReplyMessageResponse = { sentMessages: Array<{ id: string; quoteToken?: string }> }

#錯誤處理與 401/400

錯誤原因解法
401 SignatureValidationFailedexpress.json() 在前移除全域 JSON 解析
400 Invalid reply token已使用或超過 30 秒改用 pushMessage

#LINE Bot Webhook 架構

LINE → Webhook(middleware 驗證 HMAC)→ handleEvent → replyMessage → LINE

參見 LINE bot 工具比較圖文選單尺寸指南

#常見問題

Q: Express 中介軟體應該放在哪裡? 直接掛在 webhook 路由上,在任何 express.json() 之前

Q: 能否在 Express 之外呼叫 validateSignature()? 可以:import { validateSignature } from "@line/bot-sdk",傳入 raw body 與簽章。

Q: sentMessages 包含什麼?id(永久性 LINE 訊息 ID)與選填 quoteToken 組成的陣列。


下一步:

關於 LineBot.pro

LineBot.pro 是專為 LINE 官方帳號打造的自動化平台,協助您建立圖文選單、聊天機器人與群發訊息。這些指南由我們的團隊根據 LINE Messaging API 的實務經驗撰寫。

聯絡我們
LineBot.pro

準備好自動化您的LINE業務了嗎?

立即使用LineBot.pro開始自動化您的LINE訊息溝通。