2025-07-14 Line 訂單系統-C 階段 「LINE 訂單整合」

2025-07-14 Line 訂單系統-C 階段 「LINE 訂單整合」

「LINE 訂單整合」

— 這一步是整個 📘 C 階段「LINE 訂單整合」 的最關鍵部分。
完成這一步後,你的系統就能做到以下完整流程:

LINE 使用者輸入:「購買 1」 →
Node.js webhook 接收 →
建立新訂單 →
儲存到 MySQL →
Vue3 後台可立即看到新訂單。


✅ 一、目標說明

目前你已有兩個後端檔案:

  • lineWebhook.js → 接收 LINE 訊息事件
  • orders.js → 提供 /api/orders 新增與查詢

現在我們要:

讓 webhook 在使用者輸入「購買 [商品ID]」時自動呼叫 /api/orders 新增訂單。


🧩 二、修改檔案:backend/routes/lineWebhook.js

這份版本整合了:

  • 「查詢商品」(商品 1)
  • 「購買商品」(購買 1)
    兩種指令。

當使用者輸入「購買 1」時,後端會:
1️⃣ 從 MySQL 查詢商品資訊;
2️⃣ 建立新訂單(寫入 orders 表);
3️⃣ 回覆使用者「訂單建立成功」訊息。


🔧 更新後完整程式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// backend/routes/lineWebhook.js
import express from "express";
import axios from "axios";
import crypto from "crypto";
import mysql from "mysql2/promise";

const router = express.Router();

// 建立 MySQL 連線池
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});

// 驗證 LINE webhook 簽章
function validateSignature(body, signature) {
const hash = crypto
.createHmac("SHA256", process.env.LINE_CHANNEL_SECRET)
.update(JSON.stringify(body))
.digest("base64");
return hash === signature;
}

// 處理 Webhook
router.post("/webhook", async (req, res) => {
const signature = req.headers["x-line-signature"];
if (!validateSignature(req.body, signature)) {
return res.status(401).send("Invalid signature");
}

const events = req.body.events;
for (const event of events) {
if (event.type === "message" && event.message.type === "text") {
const userText = event.message.text.trim();
const userName = event.source.userId || "LINE使用者";

let replyMessage = "";

// 🟢 1️⃣ 查詢商品
if (userText.startsWith("商品")) {
const itemCode = userText.replace("商品", "").trim();
const [rows] = await pool.query(
"SELECT name, price, description FROM products WHERE id = ?",
[itemCode]
);

if (rows.length > 0) {
const p = rows[0];
replyMessage = `📦 商品名稱:${p.name}\n💲 價格:${p.price}\n📝 說明:${p.description}\n\n若要下單,請輸入:購買 ${itemCode}`;
} else {
replyMessage = "查無此商品,請確認代號是否正確。";
}
}

// 🟠 2️⃣ 購買商品
else if (userText.startsWith("購買")) {
const itemCode = userText.replace("購買", "").trim();

// 檢查商品是否存在
const [rows] = await pool.query(
"SELECT name, price FROM products WHERE id = ?",
[itemCode]
);

if (rows.length === 0) {
replyMessage = "找不到該商品,請確認代號。";
} else {
// 新增訂單
await pool.query(
`INSERT INTO orders (user_name, product_id, quantity, status, created_at)
VALUES (?, ?, 1, '新訂單', NOW())`,
[userName, itemCode]
);

const product = rows[0];
replyMessage = `✅ 已建立訂單:${product.name}\n💲 價格:${product.price}\n📦 狀態:新訂單`;
}
}

// 🔵 其他訊息
else {
replyMessage =
"您好!請輸入:\n「商品 1」查詢商品\n或「購買 1」直接下單。";
}

// 回覆 LINE 訊息
await axios.post(
"https://api.line.me/v2/bot/message/reply",
{
replyToken: event.replyToken,
messages: [{ type: "text", text: replyMessage }],
},
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.LINE_CHANNEL_ACCESS_TOKEN}`,
},
}
);
}
}

res.status(200).end();
});

export default router;

🗂️ 資料庫確認

請確認 orders 表已存在,結構如下:

1
2
3
4
5
6
7
8
9
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_name VARCHAR(100),
product_id INT,
quantity INT DEFAULT 1,
status VARCHAR(50) DEFAULT '新訂單',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (product_id) REFERENCES products(id)
);

⚙️ 測試流程

步驟 動作 預期結果
1️⃣ 啟動後端伺服器 (npm run dev) 伺服器運行於 http://localhost:3000
2️⃣ 使用 ngrok 對外公開 ngrok http 3000
3️⃣ 在 LINE Developers Webhook URL 設為 https://<ngrok-url>/api/webhook 成功設定 Webhook
4️⃣ 在 LINE 輸入「商品 1」 Bot 回覆商品資訊
5️⃣ 在 LINE 輸入「購買 1」 Bot 回覆「已建立訂單」,同時 MySQL 寫入新訂單
6️⃣ 在 Vue3 後台「LINE 訂單紀錄」頁面查看 可看到剛剛建立的訂單紀錄

💡 延伸建議(C 階段完成後的下一步)

完成這部分後,你的系統已經具備:
✅ 商品查詢
✅ 下單功能
✅ 後台查詢

接下來可以進入 📒 D 階段:Redis 即時快取 + 訂單通知系統
讓訂單狀態(例如「已接單」、「配送中」)能即時更新前端畫面或推播到 LINE。


是否要我幫你繼續進入 📒 D 階段 — Redis 快取與訂單狀態通知設計與實作