← Tất cả bài viết
Hướng dẫn

Xử lý tin nhắn LINE đã chỉnh sửa bằng Webhook message.updated

Ngày 12 tháng 8 năm 2026, LINE thêm sự kiện chỉnh sửa vào Messaging API. Khi người dùng sửa tin nhắn văn bản đã gửi trong nhóm chat đủ điều kiện có LINE Official Account, LINE có thể gửi Webhook messageEdited. Hộp thư chung nên cập nhật tin nhắn gốc thay vì thêm một tin nhắn thứ hai. Trong UnifyPort, sự kiện chuẩn tương ứng là message.updated, liên kết bằng data.message.id ban đầu.

Điểm chính

  • Tên sự kiện gốc của LINE là messageEdited; tên chuẩn trong UnifyPort là message.updated.
  • Tìm tin nhắn gốc bằng tổ hợp messaging account, cuộc trò chuyện và data.message.id.
  • Chỉnh sửa là thay đổi trạng thái, không phải tin nhắn đến mới.
  • Xác minh chữ ký HMAC-SHA256 trước khi phân tích JSON và ghi dữ liệu.
  • Nhận được chỉnh sửa từ LINE không có nghĩa là có thể chủ động sửa tin nhắn LINE qua UnifyPort.

Điều gì thay đổi trong nhóm chat LINE

Trang tin chính thức của Messaging API ghi nhận cập nhật ngày 12 tháng 8 năm 2026: người dùng có thể sửa tin nhắn trong nhóm chat có LINE Official Account, đồng thời messageEdited được thêm vào các đối tượng sự kiện Webhook. Messaging API reference hiện cũng liệt kê Edit event trong nhóm đối tượng sự kiện Webhook.

Thay đổi này ảnh hưởng đến hộp thư chung, dòng thời gian CRM, chỉ mục tìm kiếm và ngữ cảnh gửi cho AI. Nếu khách hàng sửa mã đơn hàng, địa chỉ hoặc câu hỏi nhưng hệ thống vẫn dùng nội dung cũ, các bước tự động tiếp theo sẽ xử lý dữ liệu lỗi thời. Nếu lưu bản sửa thành tin nhắn mới, số lượng tin nhắn bị nhân đôi và dòng hội thoại không còn khớp với LINE.

Mô hình đúng là cập nhật trạng thái của cùng một tin nhắn từ nhà cung cấp.

Từ LINE messageEdited đến UnifyPort message.updated

Payload chính thức của LINE có cấu trúc riêng theo nền tảng. UnifyPort chuẩn hóa thay đổi vào một envelope chung, cho phép cùng một handler xử lý tin nhắn đã sửa từ các nhà cung cấp khác được hỗ trợ.

{
  "id": "evt_7f42c18a9d",
  "type": "message.updated",
  "provider": "line",
  "account_id": "acc_8c21d0",
  "occurred_at": "2026-08-22T09:15:30Z",
  "data": {
    "conversation": {
      "id": "c8f2a4d91e",
      "type": "group",
      "title": "Hỗ trợ đơn hàng"
    },
    "sender": {
      "id": "u71b9d420f",
      "type": "user",
      "name": "Jordan Lee"
    },
    "message": {
      "id": "551842037194",
      "text": "Đính chính: mã đơn hàng là A1234.",
      "direction": "inbound",
      "sent_at": "2026-08-22T09:12:04Z"
    },
    "event": {
      "kind": "message_updated"
    }
  }
}

Hai ID có vai trò khác nhau:

  • id ở cấp cao nhất nhận diện sự kiện Webhook và dùng để loại bỏ lần giao lại trùng lặp.
  • data.message.id nhận diện tin nhắn gốc có nội dung đã thay đổi.

Có thể kiểm tra hỗ trợ hiện tại trong ma trận khác biệt sự kiện Webhook theo nhà cung cấp. Ma trận liệt kê LINE hỗ trợ message.updated, nhưng trường thực tế vẫn có thể thay đổi theo tài khoản nguồn và môi trường triển khai.

Hợp nhất bản sửa mà không tạo tin nhắn trùng

Không nên giả định message ID của nhà cung cấp là duy nhất trên toàn hệ thống. Hãy dùng khóa ghép:

(account_id, conversation_id, provider_message_id)

Sau đó áp dụng bản sửa như một chuyển đổi trạng thái có tính idempotent:

  1. Xác minh chữ ký trên raw request body.
  2. Loại bỏ lần giao trùng bằng Webhook event ID.
  3. Tìm bản ghi bằng account_id, data.conversation.iddata.message.id.
  4. Thay nội dung hiện tại bằng data.message.text.
  5. Lưu occurred_at làm thời điểm quan sát bản sửa.
  6. Giữ thời gian nhận ban đầu; nếu cần kiểm toán, lưu lịch sử phiên bản nội bộ riêng.
  7. Chỉ trả về 2xx sau khi ghi bền vững thành công.

Đoạn Express ngắn sau giữ các hàm cơ sở dữ liệu ở mức trừu tượng để làm rõ hợp đồng sự kiện thật:

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 expected = crypto.createHmac('sha256', secret)
    .update(timestamp + '.')
    .update(req.body)
    .digest('hex');

  const valid = signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  if (!valid) return res.sendStatus(401);

  const event = JSON.parse(req.body.toString('utf8'));
  if (await db.hasWebhookEvent(event.id)) return res.sendStatus(200);

  if (event.type === 'message.updated') {
    await db.applyMessageEdit({
      accountId: event.account_id,
      conversationId: event.data.conversation.id,
      messageId: event.data.message.id,
      text: event.data.message.text,
      editedAt: event.occurred_at
    });
  }

  await db.rememberWebhookEvent(event.id);
  return res.sendStatus(200);
});

Chuỗi ký chính xác, điều kiện thử lại và lưu ý về thứ tự nằm trong hướng dẫn giao Webhook và xác minh chữ ký. Hướng dẫn HMAC và bảo vệ trước yêu cầu phát lại trình bày sâu hơn về timestamp và idempotency.

Khi thiếu tin nhắn gốc hoặc sự kiện đến sai thứ tự

Thứ tự giao Webhook không được bảo đảm. Sự kiện chỉnh sửa có thể đến worker trước khi tin nhắn gốc được commit; hệ thống nhận cũng có thể bỏ lỡ tin gốc trong thời gian ngừng hoạt động. Đừng tạo ngay một mục bình thường trên dòng thời gian và đừng tăng thống kê tin nhắn đến.

Thay vào đó, lưu thay đổi trong bảng pending ngắn hạn, dùng khóa ghép của tin nhắn. Khi message.received gốc đến, áp dụng phần nội dung đang chờ trước khi hiển thị. Nếu tin gốc không bao giờ đến, hãy đánh dấu đây là quan sát chỉnh sửa chưa đầy đủ để nhân viên kiểm tra, thay vì trình bày như một tin nhắn hoàn chỉnh.

Cách tư duy theo trạng thái này cũng áp dụng cho reaction. Đọc Cách xử lý Message Reactions trong Unified Webhook để phân biệt sự kiện với trạng thái tin nhắn mà sự kiện đó thay đổi.

UnifyPort phù hợp ở đâu và giới hạn nào cần biết

UnifyPort phù hợp với đội nhỏ nhận LINE cùng WhatsApp, Telegram, TikTok, Zalo hoặc X và muốn dùng một hợp đồng sự kiện có chữ ký. Với đội vận hành tại Việt Nam, mô hình này đặc biệt hữu ích khi hộp thư cần kết hợp Zalo, WhatsApp và LINE. Giao diện không chính thức giúp giảm parser riêng cho từng nền tảng, còn handler chỉ cần rẽ nhánh theo message.updated.

Nếu ứng dụng tập trung vào LINE Official Account và cần tính năng gốc của LINE hoặc Payload nguyên bản, Messaging API chính thức vẫn là lựa chọn phù hợp hơn. Cũng cần phân biệt giới hạn hành động hiện tại: UnifyPort có thể chuẩn hóa cập nhật tin nhắn LINE nhận vào, nhưng POST /v1/messages/edit hiện chưa hỗ trợ chủ động sửa tin nhắn LINE. Nhận bản sửa và tạo bản sửa là hai khả năng riêng biệt.

Câu hỏi thường gặp

LINE messageEdited là gì?

Đây là sự kiện Webhook chính thức của LINE Messaging API cho một thao tác sửa tin nhắn đủ điều kiện. LINE công bố sự kiện này cho nhóm chat có LINE Official Account vào ngày 12 tháng 8 năm 2026.

Nên đăng ký sự kiện nào trong UnifyPort?

Đăng ký message.updated. Có thể dùng "*" nếu Endpoint chủ ý nhận mọi sự kiện chuẩn công khai; với bộ lọc production, nên ghi chính xác tên sự kiện.

Tin nhắn LINE đã sửa có nên tạo mục mới trong hộp thư không?

Không. Dùng data.message.id để tìm và cập nhật tin gốc. Nếu cần kiểm toán, hãy lưu lịch sử chỉnh sửa riêng.

Có thể sửa tin nhắn LINE qua UnifyPort không?

Hiện chưa thể. Ma trận hành động theo nhà cung cấp chưa liệt kê hỗ trợ outbound edit cho LINE. Bài này chỉ nói về việc nhận và hợp nhất sự kiện chỉnh sửa.

Bước tiếp theo

Kiểm tra ma trận sự kiện Webhook theo nhà cung cấp, thêm message.updated vào subscription và thử cả cập nhật idempotent lẫn trường hợp sự kiện sai thứ tự trước khi bật cho hộp thư production.

Nguồn chính thức

Đã kiểm tra ngày 22 tháng 8 năm 2026:

UnifyPort API

Biến tích hợp nhắn tin thành một pipeline sản phẩm ổn định.

Bắt đầu bằng cách gửi qua một API, rồi đưa mọi tin nhắn inbound trở lại hệ thống kinh doanh bằng sự kiện chuẩn.