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

Gửi media bằng UnifyPort: kiểm tra URL và trạng thái giao tin

Để gửi ảnh, video, âm thanh hoặc tài liệu qua UnifyPort, dùng POST /v1/messages với message.type được hỗ trợ và ít nhất một nguồn không rỗng trong message.url, message.file_url hoặc message.file_key. URL phải là địa chỉ HTTP(S) tuyệt đối. Tên tệp trên máy không phải URL mà dịch vụ có thể truy cập, và phản hồi status: accepted không xác nhận người nhận đã nhận tệp.

Điểm cần nhớ

  • Kiểm tra kênh của tài khoản nhắn tin trước khi cho phép chọn loại media.
  • Bắt đầu bằng một URL rõ ràng, truy cập được; không đoán thứ tự ưu tiên giữa nhiều trường nguồn.
  • message khi gửi khác với data.message.attachments[] khi nhận.
  • Chẩn đoán riêng việc truy cập tệp, kiểm tra yêu cầu, kết nối tài khoản và kết quả giao tin.

Xác định đúng hợp đồng API gửi

Giao diện không chính thức của UnifyPort tuân theo tài liệu gửi media, không phải Telegram Bot API hay LINE Messaging API. Chẳng hạn, tài liệu gửi tệp của Telegram mô tả mã định danh tệp, HTTP URL và tải lên multipart cho các phương thức riêng của Telegram. Điều đó không chứng minh UnifyPort nhận Telegram file_id làm file_key hoặc hỗ trợ cùng một yêu cầu tải lên.

TrườngĐiều tài liệu UnifyPort xác nhận
message.typeCó image, video, audio, document, file; vẫn phải kiểm tra từng kênh
message.url hoặc message.file_urlURL nguồn HTTP(S) tuyệt đối, không rỗng
message.file_keyMột lựa chọn nguồn đã được ghi nhận, không phải cơ sở để tự tạo key hay endpoint tải lên
message.captionChú thích tùy chọn cho ảnh, video, tài liệu và tệp
provider_data.secondsThời lượng tùy chọn cho âm thanh và video WhatsApp, là số nguyên không âm tính bằng giây

Thời lượng video WhatsApp có phạm vi được ghi nhận là 0–4294967295; provider_data.waveform chỉ dùng cho âm thanh. Không chép nguyên giá trị duration_ms nhận được vào trường tính bằng giây. Nếu không cần thời lượng, hãy bỏ qua thay vì đoán.

Bảng hỗ trợ gửi tin hiện không ánh xạ gửi âm thanh và tài liệu/tệp cho TikTok, đánh dấu âm thanh của X là hỗ trợ một phần, đồng thời tách whatsapp-protocol khỏi whatsapp. Khi xây dựng luồng dùng cả Zalo và WhatsApp, vẫn phải kiểm tra theo từng kênh. Một endpoint chung không bảo đảm mọi kênh có cùng khả năng hay giới hạn media.

Chuẩn bị tệp trước khi tạo yêu cầu

Đây là khuyến nghị thiết kế ứng dụng, không phải bảo đảm bổ sung của nền tảng:

  1. Xác nhận người thao tác có quyền gửi từ tài khoản đã chọn đến cuộc hội thoại đã chọn. Với nhóm, dùng ID và loại cuộc hội thoại, không dùng ID tác giả tin nhắn.
  2. Kiểm tra trạng thái cấp quyền và runtime_status riêng biệt; được cấp quyền không đồng nghĩa đang kết nối.
  3. Đặt đúng nội dung tệp tại nguồn được kiểm soát và truy cập được. Một trang chỉ mở được sau khi đăng nhập trên trình duyệt không chứng minh dịch vụ gửi có thể lấy tệp.
  4. Thử truy xuất từ môi trường máy chủ khác, không dùng Cookie của trình duyệt. Kiểm tra phản hồi chứa media mong muốn, không phải trang HTML đăng nhập hoặc báo lỗi.
  5. Nếu URL có hạn sử dụng, tính đến thời gian chờ hàng đợi và truy xuất dự kiến. Tài liệu không cam kết một thời hạn lấy tệp chung; kiểm tra trước thành công cũng không bảo đảm truy cập được về sau.

Ưu tiên HTTPS, quyền truy cập tối thiểu và nguồn lưu trữ được ứng dụng phê duyệt. Không ghi tham số URL có chữ ký hoặc thông tin xác thực vào log thông thường. Đây là khuyến nghị bảo mật, không phải tuyên bố về cơ chế lọc mạng chưa được công bố của UnifyPort.

Tạo yêu cầu gửi bằng URL

Hàm JavaScript sau tạo body từ tài khoản, cuộc hội thoại và URL media được ứng dụng chọn và cho phép. Hàm không tải tệp lên và không chứng minh nguồn truy cập được qua mạng. Trước khi gọi, vẫn cần kiểm tra quyền thao tác và khả năng của kênh.

function buildMediaRequest({ accountId, conversation, type, url, caption }) {
  const types = new Set(['image', 'video', 'audio', 'document', 'file']);
  if (!accountId || !conversation?.id || !conversation?.type) {
    throw new Error('Account and conversation are required');
  }
  if (!types.has(type)) throw new Error('Unsupported media type');

  const source = new URL(url);
  if (!['http:', 'https:'].includes(source.protocol) ||
      source.username || source.password) {
    throw new Error('Use an approved HTTP(S) media source');
  }

  const message = { type, url: source.href };
  if (caption !== undefined) {
    if (type === 'audio' || typeof caption !== 'string') {
      throw new Error('Caption is not valid for this request');
    }
    message.caption = caption;
  }

  return {
    account_id: accountId,
    to: { id: conversation.id, type: conversation.type },
    message,
  };
}

Gửi JSON tạo ra đến POST /v1/messages với xác thực X-Api-Key phía máy chủ và Content-Type: application/json. Hàm cố ý chỉ đặt message.url. Tài liệu yêu cầu ít nhất một nguồn nhưng không xác lập thứ tự ưu tiên khi các nguồn xung đột.

Không dán thẳng đối tượng tệp đính kèm nhận được vào body gửi. Hướng dẫn ánh xạ media đầu vào mô tả attachments[].type, url, mimetype và dữ liệu liên quan; đó là các trường nhận, không phải yêu cầu gửi hoàn chỉnh. Nếu URL gốc đã hết hạn, hãy dùng hướng dẫn khôi phục liên kết tải xuống để xác định cách xử lý đúng với API đang dùng trước khi chuyển tiếp.

Chẩn đoán tại đúng điểm lỗi

Hiện tượngKiểm tra tiếpTránh
Cung cấp đường dẫn cục bộ, URL tương đối hoặc data: URLChuẩn bị nguồn HTTP(S) tuyệt đốiĐổi tên đường dẫn thành file_key
URL chỉ hoạt động trong trình duyệt của bạnPhụ thuộc đăng nhập, hạn dùng, chuyển hướng và nội dung trả vềCho rằng phiên trình duyệt được chuyển sang dịch vụ gửi
unsupported_message_typeKênh và loại mediaLặp lại yêu cầu không đổi
provider_not_readyTrạng thái cấp quyền và runtimeCấp quyền lại khi chưa chẩn đoán
Yêu cầu hết thời gian chờGiữ bản ghi thao tác gửi và điều tra kết quả chưa rõTự gửi lại, có thể tạo tin trùng
Phản hồi là acceptedLưu mã định danh trả về; kiểm tra riêng bằng chứng giao tin được hỗ trợHiển thị ngay “đã giao” hoặc “đã đọc”

Dùng mã lỗi máy đọc được trong tài liệu lỗi để phân nhánh, thay vì đoán theo câu mô tả. Lưu request_id để chẩn đoán, không xem nó là token chống trùng. Hướng dẫn truy vết yêu cầu giải thích ranh giới này.

Nếu xử lý xác nhận giao tin, đối chiếu tài liệu sự kiện và bảng theo kênh. Xác minh chữ ký webhook, đồng thời xử lý sự kiện trùng hoặc đến sai thứ tự. Không phải mọi kênh đều phát mọi loại xác nhận; thiếu xác nhận phải giữ ở trạng thái chưa rõ, không trở thành lý do gửi thêm lần nữa.

Kiểm tra nghiệm thu và câu hỏi thường gặp

Trước khi đưa vào vận hành, nên thiết kế kiểm tra cho tệp truy cập được, nguồn hết hạn, trang đăng nhập thay vì tệp, cặp kênh/loại không hỗ trợ, tài khoản mất kết nối và phản hồi gửi bị thất lạc. Bài viết không khẳng định đã chạy các kiểm tra này trên hệ thống thực.

Có thể tải trực tiếp tệp cục bộ bằng yêu cầu JSON này không?

Yêu cầu media được ghi nhận sử dụng URL hoặc file key. Bài viết không xác nhận có endpoint tải lên multipart. Hãy đưa tệp vào quy trình lưu trữ được phép rồi dùng URL truy cập được.

Có thể dùng Telegram file_id làm file_key không?

Tài liệu không xác nhận sự tương đương này. Giữ mã định danh gốc của Telegram tách biệt với trường nguồn UnifyPort.

accepted có nghĩa người nhận đã nhận tệp không?

Không. Nó thể hiện yêu cầu được chấp nhận, không phải xác nhận giao hoặc đọc tin.

Bước tiếp theo và nguồn tham khảo

Làm theo hướng dẫn gửi ảnh và tệp với một cuộc hội thoại thử nghiệm được phép và một nguồn media đã duyệt trước khi bật gửi qua hàng đợi hoặc tự động hóa.

Nguồn được kiểm tra ngày 2026-10-09:

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.