教程
@line/bot-sdk Express 中间件:replyMessage 与 validateSignature 完整示例
@line/bot-sdk Express 中间件实战:webhook 签名验证、replyMessage 与 sentMessages、错误处理、TypeScript 类型。生产可用代码。
LineBot.pro Team11 分钟阅读

#为什么需要 Express 中间件?
@line/bot-sdk 官方包含 Express 中间件,自动完成两件事:
- HMAC-SHA256 签名验证(
x-line-signature头) - 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)

#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 SignatureValidationFailed | express.json() 在前 | 移除全局 JSON 解析 |
| 400 Invalid reply token | 已用或超 30 秒 | 改用 pushMessage |
#LINE Bot Webhook 架构
LINE → Webhook(middleware 验证 HMAC)→ handleEvent → replyMessage → LINE
参见 LINE bot 工具对比 与 Rich Menu 尺寸。
#常见问题
Q: Express 中间件应放在哪里?
直接挂在 webhook 路由,在任何 express.json() 之前。
Q: 能否在 Express 外调用 validateSignature()?
可以:import { validateSignature } from "@line/bot-sdk",传入 raw body 与签名。
Q: sentMessages 包含什么?
id(持久化 LINE 消息 ID)与可选 quoteToken 的数组。
下一步: