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

Album media qua webhook: gom ảnh mà không làm mất tin nhắn

Để ghép album media từ webhook, hãy lưu từng tin nhắn thành phần độc lập rồi chỉ dùng mã album để tạo chế độ xem theo nhóm. Không loại trùng các tin nhắn bằng ID album: cách đó sẽ bỏ mất những ảnh khác nhau trong cùng album. Khi payload không có tổng số dự kiến, một khoảng thời gian không nhận thêm mục mới có thể kích hoạt xử lý, nhưng không chứng minh mọi mục đã đến.

Điểm chính

  • ID tin nhắn và ID album phục vụ hai mục đích khác nhau.
  • Cả hai cần có phạm vi tài khoản nhận và cuộc trò chuyện.
  • Lưu bền vững từng tin nhắn trước khi xác nhận nhận dữ liệu; tổng hợp sau.
  • Giữ trạng thái album sau khi bộ hẹn giờ chạy để bổ sung mục đến muộn.

ID album không phải ID tin nhắn

Tài liệu Bot API chính thức của Telegram định nghĩa Message.media_group_id là trường tùy chọn xác định nhóm media mà tin nhắn thuộc về, có tính duy nhất trong cuộc trò chuyện đó. Trường này mô tả quan hệ giữa các tin nhắn, không thay thế định danh của từng tin.

UnifyPort dùng hợp đồng dữ liệu khác. Tài liệu webhook chuẩn mô tả đối tượng tùy chọn data.message.album với id, index và total có thể vắng mặt. Mỗi tin nhắn thành phần vẫn có data.message.id riêng. Ví dụ album trong tài liệu là WhatsApp; không thể từ đó khẳng định mọi kênh, chẳng hạn Zalo, luôn có metadata album, hay trường gốc của Telegram sẽ xuất hiện trong payload chuẩn hóa.

Nếu đang triển khai bước đọc tệp đính kèm, hãy xem hướng dẫn ánh xạ media trước. Gom album là một lớp hiển thị bổ sung, không phải giao thức tải tệp mới.

Định danhPhạm vi đề xuấtMục đích
ID sự kiện thông thườngWorkspace và luồng sự kiệnNhận biết lần gửi lại cùng sự kiện
ID tin nhắn thành phầnWorkspace, nhà cung cấp, tài khoản nhắn tin, cuộc trò chuyệnLưu hoặc cập nhật một tin
ID albumWorkspace, nhà cung cấp, tài khoản nhắn tin, cuộc trò chuyệnLiên kết nhiều mục
URL tệp đính kèmBản ghi tin nhắn chứa tệpXác định vị trí media, không làm khóa nhóm

Trong ví dụ giả định gửi ba ảnh, nếu B đến hai lần còn C đến một lần thì chỉ có hai mục khác nhau, không phải ba. Số HTTP request không đo được độ đầy đủ của album.

Lưu từng tin trước khi tạo chế độ xem tổng hợp

Đoạn JavaScript sau tạo khóa lưu trữ của ứng dụng từ sự kiện UnifyPort đã được xác thực. Tên thuộc tính trả về là thiết kế nội bộ, không phải trường API mới. Hàm này không kiểm tra chữ ký hay ghi cơ sở dữ liệu.

function albumKeys(workspaceKey, event) {
  if (event.type !== 'message.received') return null;
  const conversation = event.data?.conversation;
  const message = event.data?.message;
  if (!event.provider || !event.account_id ||
      !conversation?.id || !message?.id) {
    throw new Error('Missing message identity');
  }

  const scope = [workspaceKey, event.provider,
    event.account_id, conversation.id];
  return {
    childKey: JSON.stringify([...scope, message.id]),
    albumKey: message.album?.id
      ? JSON.stringify([...scope, message.album.id])
      : null
  };
}

Trình tự giao dịch được đề xuất:

  1. Xác thực request nguyên bản theo hợp đồng phân phối webhook. Khi bật signing_secret, kiểm tra HMAC-SHA256 trên timestamp, dấu chấm và body nguyên bản, đồng thời kiểm tra độ mới của timestamp.
  2. Lưu sự kiện và upsert tin nhắn thành phần với ràng buộc duy nhất trên định danh đầy đủ. Giữ chú thích, tệp đính kèm, sent_at và metadata album hiện có.
  3. Liên kết tin nhắn với album đúng phạm vi. Nếu không có ID album, giữ như tin độc lập; không đoán quan hệ từ chú thích giống nhau hoặc thời điểm đến gần nhau.
  4. Commit bản ghi đầu vào và tác vụ bền vững trước khi trả 2xx. Để worker cập nhật chế độ xem và tải media riêng.

Dùng cùng một giao dịch hoặc durable outbox để tránh tình trạng tiến trình dừng sau khi lưu tin nhưng trước khi tạo tác vụ tổng hợp. Giữ chú thích của từng mục thay vì để lần gửi cuối ghi đè lên một chú thích chung của album.

Chọn thời điểm xử lý, không tuyên bố chắc chắn đã đủ

Các trạng thái dưới đây là đề xuất cho ứng dụng, không phải sự kiện nền tảng hay trường API.

Quan sátQuyết định của ứng dụng
total nhất quán và đã lưu đủ từng ấy mục khác nhauĐánh dấu đạt số lượng dự kiến; theo dõi tệp sẵn sàng riêng
Thiếu totalXử lý snapshot tạm thời sau khoảng chờ do ứng dụng chọn
total mâu thuẫn hoặc index trùngGiữ các tin nhắn và đánh dấu metadata cần kiểm tra
Mục mới đến sau khi đã xử lýCập nhật chế độ xem, áp dụng chính sách mục đến muộn
Một mục được gửi lạiCập nhật idempotent, không tăng số mục khác nhau

Tuần tự hóa việc cập nhật cùng album hoặc dùng kiểm tra phiên bản trong giao dịch. Nếu không, nhiều worker có thể đọc cùng trạng thái cũ rồi tạo tác vụ phía sau bị trùng. Lưu quyết định xử lý cùng danh sách ID tin nhắn thực sự được đưa vào. Khi có ảnh đến muộn, chọn rõ việc cập nhật giao diện, phân tích bổ sung hay chuyển cho người kiểm tra; không tự động gửi lại tin cho khách hàng.

Giữ album.index nhận được để phục vụ hiển thị, nhưng không suy ra quy tắc bắt đầu đánh số chưa được tài liệu mô tả từ một ví dụ. Thiếu hoặc xung đột chỉ số không phải lý do bỏ mục. Bộ hẹn giờ là chính sách độ trễ của ứng dụng, không phải tín hiệu hoàn tất từ nền tảng.

Tách trạng thái media sẵn sàng

Album có thể đủ số bản ghi tin nhắn nhưng vẫn có tệp chưa dùng được. UnifyPort mô tả URL đính kèm tạm thời và trường hợp tệp quá lớn không có URL. Hãy xếp tác vụ tải kịp thời, hiển thị trạng thái thành công hoặc lỗi riêng cho từng tệp.

Hướng dẫn khôi phục liên kết tải hết hạn giải thích vì sao không thể áp dụng trực tiếp thao tác làm mới tệp của Telegram Bot API cho URL đính kèm UnifyPort. Đừng trì hoãn vô thời hạn việc lưu những tệp đã có thể tải chỉ để đợi album đầy đủ.

UnifyPort là giao diện không chính thức. Luồng chuẩn hóa không bảo đảm metadata giống nhau trên mọi kênh. Sản phẩm không có REST API đọc lịch sử tin nhắn hoặc bảo đảm phát lại payload bị bỏ lỡ. Nếu cần hợp đồng bot gốc của Telegram, hãy dùng Bot API chính thức và không trộn hai schema trong một bộ phân tích.

Kiểm thử và câu hỏi thường gặp

Nên kiểm thử mục trùng, thứ tự đảo, cùng ID album ở các cuộc trò chuyện khác nhau, thiếu tổng số, metadata mâu thuẫn và mục đến sau khi xử lý. Đây là đề xuất kiểm thử, không phải kết quả đã thực hiện.

Có thể dùng album.id để loại trùng tin nhắn không?

Không áp dụng cho tin thành phần. Nhiều tin khác nhau có thể dùng chung ID album. Hãy lưu bằng ID tin nhắn có phạm vi đầy đủ.

Đạt total có nghĩa là đã tải đủ tệp không?

Không. Khi được cung cấp, total mô tả kích thước nhóm dự kiến. Lưu tệp bền vững là một mốc riêng.

Có nên bỏ album không có total không?

Không. Giữ các mục, xử lý chế độ xem tạm thời theo chính sách rõ ràng và cho phép bổ sung về sau.

Bước tiếp theo và nguồn

Triển khai lưu trữ từng tin theo tài liệu sự kiện chuẩn trước khi bật tự động hóa cấp album.

Ngày đối chiếu tài liệu: 2026-09-29.

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.