Một LINE Webhook cho cả nhóm Nhật Bản: Cách một startup ở Fukuoka chuyển tiếp tin nhắn LINE sang Slack, CRM và AI
Vào lúc 9:47 sáng thứ Ba, một khách hàng ở Osaka gửi tin nhắn LINE cho quản lý tài khoản của mình: “Xuất CSV cứ bị lỗi hoài — đây có phải lỗi đã biết chưa?” Quản lý tài khoản đang họp. Tin nhắn nằm trên điện thoại cô suốt ba tiếng. Đến khi cô trả lời, khách hàng đã tạo ticket hỗ trợ qua website — và tag công ty trên X, hỏi liệu có ai thực sự theo dõi kênh LINE của họ không.
Đây không phải câu chuyện về hạn chế của nền tảng. LINE hoạt động rất tốt với vai trò ứng dụng nhắn tin. Vấn đề nằm ở chỗ sáu người trong văn phòng Fukuoka, mỗi người nhận tin nhắn khách hàng trên tài khoản LINE riêng, trên điện thoại riêng, mà không có cái nhìn chung nào về việc ai đang trả lời ai. Công ty — một đội B2B SaaS bán công cụ hoạch định logistics cho các kho hàng trên khắp Nhật Bản và Đông Nam Á — đã vượt qua giai đoạn mà “mỗi người tự kiểm tra LINE của mình” còn là chiến lược hỗ trợ khả thi. Nhưng mọi giải pháp thay thế đều đòi hỏi phải chuyển khách hàng khỏi LINE, và ở Nhật Bản, điều đó là bất khả thi.
Hàng đợi không tồn tại
Hệ thống hỗ trợ của đội vào đầu năm 2026 như sau: ba nhân viên kinh doanh và hai kỹ sư hỗ trợ, mỗi người có một tài khoản LINE mà khách hàng đã kết bạn. Tin nhắn đến trên điện thoại cá nhân. Không có hộp thư chung, không theo dõi phản hồi, không SLA. Nếu ai đó nghỉ ốm, tin nhắn của họ nằm chờ cho đến khi họ quay lại. Nếu khách hàng nhắn sau 7 giờ tối, họ phải đợi đến ngày làm việc tiếp theo — không phải vì đội không muốn giúp, mà vì không ai biết tin nhắn đã đến.
Công ty đã cân nhắc con đường Tài khoản Chính thức LINE (Official Account, OA), vốn cung cấp hộp thư chung và một số tính năng tự động hóa. Nhưng quy trình đăng ký OA mất tới 60 ngày làm việc để xác minh, và bậc Unverified giới hạn danh sách liên hệ ở 500 bạn — một trần cứng đối với đội có cơ sở khách hàng đang tiến gần 800. Các bậc Verified và Premium mở khóa giới hạn cao hơn nhưng đi kèm phí hàng tháng và quy tắc cửa sổ tương tác, chi phối thời điểm doanh nghiệp được phép chủ động liên hệ. Đội này không chủ động liên hệ — họ phản hồi. Bộ máy phát sóng OA đang giải quyết một vấn đề mà họ không có.
Trong khi đó, chi phí vận hành từ hiện trạng ngày càng chồng chất. Trong quý đầu năm 2026, đội ghi nhận 23 trường hợp tin nhắn khách hàng không được trả lời quá bốn tiếng. Bảy trường hợp trong số đó dẫn đến ticket hỗ trợ bị đẩy lên qua các kênh khác. Hai trường hợp dẫn đến khiếu nại công khai trên X. Trưởng nhóm hỗ trợ, Kenji, lập một bảng tính để theo dõi các phản hồi bị bỏ lỡ. Anh ngừng cập nhật nó sau tuần thứ sáu.
Một Webhook, ba điểm đến
Bước ngoặt không phải là một cuộc khủng hoảng — mà là một tin nhắn Slack từ CTO của công ty, người đã tìm hiểu về định tuyến tin nhắn dựa trên webhook. Ý tưởng rất đơn giản: thay vì mỗi người tự kiểm tra LINE của mình, hãy kết nối cả sáu tài khoản LINE thông qua một giao diện không chính thức duy nhất, chuyển tiếp tin nhắn đến các công cụ mà đội đã sử dụng. Slack để hiển thị theo thời gian thực. CRM để ghi log và theo dõi. Và đối với các câu hỏi thông thường, một bản nháp AI mà đội có thể xem xét trước khi gửi.
Đội kết nối các tài khoản LINE với UnifyPort bằng xác thực mã QR — chế độ xác thực duy nhất mà LINE hỗ trợ trên nền tảng này. Mỗi lần quét tài khoản mất khoảng 30 giây. Trong vòng một giờ, cả sáu tài khoản đã hoạt động, và một webhook endpoint duy nhất nhận mọi tin nhắn LINE đến dưới dạng sự kiện message.received.
Payload webhook trông như sau:
{
"id": "evt_9a3f7c2e01",
"type": "message.received",
"provider": "line",
"account_id": "acc_4b82d1",
"occurred_at": "2026-05-12T01:47:23Z",
"data": {
"conversation": {
"id": "U4af2c891...",
"type": "user",
"title": "Tanaka-san"
},
"sender": {
"id": "U4af2c891...",
"type": "user",
"name": "Tanaka-san"
},
"message": {
"id": "msg_18420...",
"type": "text",
"text": "The CSV export keeps failing — is this a known issue?",
"direction": "inbound",
"sent_at": "2026-05-12T01:47:22Z"
},
"event": {
"kind": "message_received"
}
}
}
Mỗi lần gửi đến đều đi kèm header X-Device-Signature — một HMAC-SHA256 hex digest của timestamp ghép nối với phần body request thô, được ký bằng signing_secret của webhook. Handler Express của đội xác minh chữ ký trước khi xử lý bất cứ điều gì:
import crypto from 'crypto';
import express from 'express';
const app = express();
const SECRET = process.env.WEBHOOK_SIGNING_SECRET;
app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
const timestamp = req.get('X-Device-Timestamp') ?? '';
const signature = req.get('X-Device-Signature') ?? '';
const hmac = crypto.createHmac('sha256', SECRET);
hmac.update(timestamp + '.');
hmac.update(req.body);
const expected = hmac.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).end();
}
const event = JSON.parse(req.body.toString('utf8'));
if (event.type === 'message.received') {
await routeMessage(event);
}
res.status(200).end();
});
Phần thú vị không nằm ở handler webhook — mọi tích hợp đều có một cái. Phần thú vị là hàm routeMessage chạy sau khi xác minh. Thay vì đổ mọi tin nhắn vào một hàng đợi duy nhất, logic định tuyến kiểm tra nội dung tin nhắn và ngữ cảnh cuộc trò chuyện để quyết định nó nên đi đâu.
Logic định tuyến: Slack, CRM, AI — hoặc cả ba
Quy tắc định tuyến của đội phát triển qua hai tuần đầu, nhưng phiên bản cuối cùng có ba tầng:
Tầng 1 — Thông báo Slack (mọi tin nhắn). Mỗi tin nhắn LINE đến đều được đăng lên kênh #support-line trong Slack với tên người gửi, xem trước tin nhắn và account_id để đội biết tin nhắn đến từ tài khoản của ai. Chỉ riêng điều này đã giải quyết vấn đề “tin nhắn nằm trên điện thoại của ai đó”. Nếu chủ tài khoản đang họp, bất kỳ ai trong đội cũng có thể thấy tin nhắn và phản hồi qua endpoint POST /v1/messages của UnifyPort, sử dụng reply_to.reply_token từ tin nhắn gốc.
Tầng 2 — Ghi log CRM (mọi tin nhắn). Một lệnh gọi song song tạo hoặc cập nhật bản ghi liên hệ trong CRM với toàn bộ nội dung tin nhắn, timestamp và ID cuộc trò chuyện. Trước đây, các tương tác khách hàng trên LINE hoàn toàn vô hình với CRM — chúng chỉ tồn tại trong lịch sử trò chuyện cá nhân trên điện thoại. Giờ đây, mọi cuộc trò chuyện LINE đều có dấu vết kiểm toán đầy đủ, song song với lịch sử email và ticket trên website.
Tầng 3 — Bản nháp AI (chỉ câu hỏi thông thường). Một bộ phân loại từ khóa đơn giản kiểm tra tin nhắn đến với danh sách các chủ đề phổ biến: xuất CSV, thanh toán, vấn đề đăng nhập, yêu cầu tài liệu API. Nếu tìm thấy kết quả phù hợp, tin nhắn được chuyển tiếp đến một LLM endpoint nội bộ với system prompt chứa phần tài liệu liên quan. Bản nháp phản hồi của AI được đăng lên kênh Slack #support-drafts với nút “Xem xét & Gửi”. Không phản hồi nào được gửi đi mà không có sự phê duyệt của con người — nhưng bản nháp đã sẵn sàng trong vài giây, và nhân viên chỉ cần nhấp một lần.
async function routeMessage(event) {
const { conversation, sender, message } = event.data;
const accountId = event.account_id;
// Tier 1: Always notify Slack
await postToSlack('#support-line', {
account: accountId,
sender: sender.name,
preview: message.text?.slice(0, 120),
reply_token: message.reply_token,
});
// Tier 2: Always log to CRM
await crm.upsertContact({
external_id: sender.id,
platform: 'line',
name: sender.name,
last_message: message.text,
last_message_at: message.sent_at,
});
// Tier 3: AI draft for routine questions
const topic = classifyTopic(message.text);
if (topic) {
const draft = await generateDraft(topic, message.text, sender.name);
await postToSlack('#support-drafts', {
sender: sender.name,
topic,
draft,
account_id: accountId,
reply_token: message.reply_token,
});
}
}
Hàm classifyTopic được thiết kế đơn giản một cách có chủ ý — một bảng ánh xạ từ khóa, không phải bộ phân loại nơ-ron. “CSV”, “export”, “download” ánh xạ tới chủ đề export-docs. “請求”, “料金”, “支払い” ánh xạ tới billing. Giữ nó dựa trên quy tắc có nghĩa là đội có thể gỡ lỗi các lỗi định tuyến trong vài phút, không phải vài giờ.
Nhãn cuộc trò chuyện để phân công trách nhiệm trong nhóm
Một tính năng mà đội áp dụng trong tuần thứ hai là nhãn cuộc trò chuyện của UnifyPort. Sử dụng endpoint POST /v1/conversations/labels, họ tạo nhãn cho mỗi thành viên: kenji, yuki, hiro, sales. Khi tin nhắn đến, hàm định tuyến gắn nhãn cuộc trò chuyện với tên chủ tài khoản. Nếu chủ tài khoản vắng mặt (kiểm tra qua tích hợp lịch đơn giản), cuộc trò chuyện được gán lại nhãn cho người trực.
Điều này có nghĩa là tại bất kỳ thời điểm nào, mọi thành viên đều có thể gọi GET /v1/conversations/labels và thấy chính xác những cuộc trò chuyện nào được giao cho mình — trên tất cả sáu tài khoản LINE. Vấn đề hộp thư chung được giải quyết không phải bằng cách tạo hộp thư mới, mà bằng cách gắn nhãn các cuộc trò chuyện xuyên suốt những hộp thư hiện có.
Nhãn cũng hỗ trợ báo cáo hàng tuần: một cron job kéo tất cả cuộc trò chuyện được gắn nhãn của từng nhân viên, đếm thời gian phản hồi (đo từ occurred_at của message.received đến lệnh gọi POST /v1/messages outbound đầu tiên), và đăng tóm tắt lên #support-metrics mỗi sáng thứ Hai.
Tuần một so với tuần bốn
Những con số tự nói lên tất cả. Trong tuần trước khi webhook đi vào hoạt động, thời gian phản hồi trung vị của đội trên LINE là 3 giờ 40 phút, với 11 tin nhắn không được trả lời quá bốn tiếng. Đến tuần bốn, thời gian phản hồi trung vị là 22 phút. Không tin nhắn nào bị bỏ quá bốn tiếng — trường hợp tệ nhất là 1 giờ 15 phút trong một buổi offsite toàn công ty.
Tầng bản nháp AI xử lý khoảng 35% tin nhắn đến. Đội phê duyệt và gửi khoảng 80% số bản nháp đó mà không cần chỉnh sửa. 20% còn lại cần viết lại nhỏ — thường vì câu hỏi của khách hàng có sắc thái mà bộ phân loại từ khóa bỏ sót. Ngay cả trong những trường hợp đó, bản nháp vẫn cho nhân viên một điểm khởi đầu, rút ngắn thời gian soạn phản hồi từ vài phút xuống còn vài giây.
Tích hợp CRM mang lại một tác dụng phụ bất ngờ: đội kinh doanh bắt đầu sử dụng lịch sử trò chuyện LINE để chuẩn bị cho các cuộc gọi gia hạn. Trước khi có webhook, một nhân viên bước vào cuộc họp gia hạn không có hồ sơ nào về các tương tác hỗ trợ trước đây của khách hàng trên LINE. Giờ đây họ có thể thấy mọi tin nhắn, mọi thời gian phản hồi và mọi cách giải quyết — tất cả được ghi log tự động.
Những gì đội không thay đổi
Khách hàng không nhận thấy gì khác biệt. Họ vẫn nhắn tin vào cùng những tài khoản LINE mà họ đã sử dụng suốt nhiều tháng. Họ vẫn nhận phản hồi từ cùng những người. Khác biệt duy nhất là phản hồi đến nhanh hơn, và nếu người quản lý thường ngày không có mặt, người khác sẽ tiếp nhận — bởi vì tin nhắn hiển thị cho cả đội trong Slack, chứ không chìm trên điện thoại của một người.
Đội cũng giữ các tài khoản LINE làm tài khoản cá nhân, không phải tài khoản OA. Webhook UnifyPort gửi tin nhắn đến bất kể loại tài khoản — hàng đợi xác minh OA và cửa sổ tương tác là những vấn đề liên quan đến phát sóng outbound, trong khi quy trình làm việc của đội hoàn toàn là inbound. Việc sử dụng giao diện không chính thức cho tài khoản cá nhân đáp ứng đầy đủ nhu cầu của họ. Nếu một ngày nào đó họ quyết định chạy các chiến dịch chủ động (khuyến mãi theo mùa, thông báo sản phẩm), con đường OA sẽ trở nên phù hợp. Cho đến lúc đó, đó là một lớp thủ tục hành chính mà họ không cần.
Mô hình chung
Đây không phải câu chuyện chỉ dành riêng cho LINE. Bất kỳ đội nào nhận tin nhắn khách hàng trên nhiều tài khoản cá nhân trên bất kỳ nền tảng nào — WhatsApp, Telegram, X, Zalo — đều đối mặt với cùng một vấn đề định tuyến. Tại Việt Nam, nơi cả WhatsApp và Zalo đều được sử dụng rộng rãi trong giao tiếp kinh doanh, mô hình này đặc biệt có ý nghĩa. Webhook không quan tâm tin nhắn đến từ nền tảng nào; trường provider thay đổi, nhưng cấu trúc payload, xác minh HMAC-SHA256 và logic định tuyến vẫn giữ nguyên. Đội Fukuoka đã lên kế hoạch thêm tài khoản WhatsApp (được các đối tác kho hàng Đông Nam Á sử dụng) vào cùng hệ thống định tuyến. Một handler, một bộ nhãn, một pipeline đo lường.
Nếu chiến lược hỗ trợ của đội bạn là “mỗi người tự kiểm tra tin nhắn của mình”, câu hỏi không phải là bạn có cần nền tảng tốt hơn hay không — mà là tin nhắn của bạn có cần một lớp định tuyến tốt hơn hay không. Một webhook endpoint duy nhất, 20 dòng logic định tuyến và các công cụ bạn đã sử dụng có thể là đủ.