Bỏ qua tới phần tài liệu
SDK

Gửi một lô

`emails.sendBatch`: tối đa 100 thư, kết quả theo từng mục.

emails.sendBatch

send-batch.ts
const result = await openemail.emails.sendBatch(invoices.map(toMessage)) console.log(result.sent, 'sent,', result.failed, 'failed') for (const item of result.items) {  if (item.status === 'error') console.error(item.index, item.error.code, item.error.message)  else console.log(item.index, item.email.id)}

items chứa một mục cho mỗi đầu vào, theo đúng thứ tự, mỗi mục hoặc là ok kèm thư của nó, hoặc là error kèm phong bì lỗi mà thư đó bị từ chối. Không có gì bị hoàn tác, nên failed > 0 là danh sách cần xử lý chứ không phải lý do để gửi lại cả lô.

Một idempotency key áp dụng cho cả lô và máy chủ mở rộng nó cho từng mục, nên một lô được thử lại sẽ phát lại từng thư thay vì gộp tất cả vào thư đầu tiên.

Tham số: emails.sendBatch

emailsEmailSend[]bắt buộc
Từ một đến 100 thư, được tuần tự hóa thành `{ "emails": [...] }` và được chấp nhận lần lượt theo thứ tự đã cho. Một mảng rỗng, nhiều hơn 100 thư, hoặc hơn 10 mục có `translate` sẽ khiến cả lệnh gọi bị từ chối với `validation_error` trên `emails`. Tương tự với việc thiếu scope `emails:send`, body không phải mảng hay `{ emails: [...] }`, và `Idempotency-Key` sai định dạng, tất cả đều xảy ra trước khi bất kỳ thư nào được gửi.
options.idempotencyKeystring
Khử trùng lặp lô giữa các tiến trình. Client luôn gắn một key mới trên mỗi lệnh gọi, nên các lần thử lại của chính nó không bao giờ gửi trùng, và máy chủ mở rộng key nhận được cho từng mục thành `key/0`, `key/1` và tiếp tục như vậy, phân tách bằng dấu gạch chéo, một ký tự mà key của bạn không được chứa, nên một key dùng cho một trăm thư không thể gộp chúng vào thư đầu tiên.
emails[].fromRecipientInputbắt buộc
Người gửi, dưới dạng địa chỉ trần, `Name <addr@host>` hoặc một object. Không có người gửi dự phòng và key phải được phép dùng địa chỉ này; nếu bị từ chối, chỉ mục đó thất bại, với `permission_error` và mã `from_address_forbidden`.
emails[].toRecipientInput | RecipientInput[]bắt buộc
Ít nhất một người nhận, và một người nhận đơn lẻ sẽ được client bọc thành mảng. Tối đa 50 địa chỉ gộp chung `to`, `cc` và `bcc`, tính theo từng thư chứ không theo cả lô.
emails[].ccRecipientInput | RecipientInput[]
Mặc định là không có, và tính vào cùng tổng 50 địa chỉ với `to` và `bcc`.
emails[].bccRecipientInput | RecipientInput[]
Mặc định là không có, và tính vào cùng tổng 50 địa chỉ. `Bcc` là một trong những tên mà `headers` không được phép đặt, nên đây là cách duy nhất để gửi bản sao ẩn. Dạng header sẽ phá vỡ phong bì riêng cho từng người nhận, thứ giữ cho địa chỉ được ẩn.
emails[].replyToRecipientInput
Nơi nhận thư trả lời. Được áp dụng sau `headers`, nên nó ghi đè `Reply-To` bạn đặt ở đó thay vì thêm một header thứ hai.
emails[].subjectstring
Tối đa 998 ký tự, giới hạn độ dài dòng của RFC 5322, và mặc định là chuỗi rỗng. Subject rỗng sẽ dùng subject của template khi `template` có cung cấp.
emails[].htmlstring
Phần HTML, tối đa một triệu ký tự, và là phần người nhận thấy khi có cả hai phần thân. Bắt buộc có một trong `html`, `text`, `template` hoặc `draftId`, và mục không có trường nào sẽ thất bại với `validation_error` trên `html`.
emails[].textstring
Phần văn bản thuần, tối đa một triệu ký tự. Có thể gửi cả hai, nhưng mọi tầng truyền tải trên luồng này đều dựng một phần thân từ một chuỗi, nên `html` được ưu tiên khi có.
emails[].headersRecord<string, string>
Chỉ `X-*`, `List-*`, Reply-To, Precedence, Auto-Submitted, Importance, Priority và Feedback-ID; mọi header do tầng truyền tải tự đặt (From, To, Bcc, Subject, Message-ID, các header DKIM và ARC) đều bị từ chối với `reserved_header` thay vì bị âm thầm bỏ qua. Giá trị tối đa 998 ký tự và không được chứa CR, LF hay NUL, vì một dòng thứ hai là một header thứ hai.
emails[].attachmentsAttachmentInput[]
Tối đa 20 tệp mỗi thư, với tổng dung lượng tệp nhúng 5 MB sau khi giải mã, tính theo từng thư chứ không theo cả lô. `content` là base64 khi truyền đi; hãy truyền byte và client sẽ mã hóa, vì base64 tự viết thường xuyên làm tràn call stack. Một mục `{ fileId }` trỏ tới tệp đã có trong workspace và không tính vào giới hạn tệp nhúng.
emails[].threadIdstring
Trả lời vào một luồng có sẵn, tối đa 256 ký tự. Tầng truyền tải tạo In-Reply-To và References từ giá trị này, nhờ đó thư trả lời nằm trong cuộc hội thoại chứ không nằm tách riêng.
emails[].draftIdstring
Gửi nội dung của một bản nháp đã lưu với phong bì này, tối đa 256 ký tự. Người nhận, subject và header được dựng ở đây mới là thứ được gửi đi.
emails[].template{ id, version?, props?, slots? }
Render một template đã lưu ở phía máy chủ, theo id (`tpl_…`) hoặc slug, với `version` để ghim một bản sửa đổi và `props`/`slots` để điền giá trị. Được phân giải một lần khi mục được chấp nhận, và bị từ chối nếu đi cùng `html`/`text` hoặc `draftId`, vì mỗi trường đó là một nguồn nội dung khác cho thư.
emails[].scheduledAtDate | string
Một `Date`, một thời điểm ISO-8601, hoặc một khoảng thời gian như `PT1H`; ít nhất một giây trong tương lai và tối đa 365 ngày tới. Các mục được hẹn giờ độc lập, nên một lô có thể chứa một trăm thời điểm gửi khác nhau.
emails[].cancellableForSecondsnumber
Cửa sổ hoàn tác tính bằng giây cho lần gửi ngay, một integer từ 0 đến 900, mặc định 0. Mọi giá trị lớn hơn 0 đều bị từ chối nếu đi cùng `scheduledAt` trên cùng mục, vì thư đã hẹn giờ vốn có thể hủy cho tới khi được gửi.
emails[].trackingTrackingRequest
`opens` và `clicks`, mỗi cái là tùy chọn độc lập và ghi đè cài đặt chỉ cho thư này. Nếu bỏ trống, giá trị lấy theo cài đặt của địa chỉ gửi thư, hoặc nếu không có thì theo All addresses, vốn bật trừ khi một trong hai nơi đó đã tắt.
emails[].tagsRecord<string, string>
Tối đa 10 nhãn, khóa dài 1 đến 64 ký tự thuộc `A-Za-z0-9_-` và giá trị tối đa 256 ký tự. Được trả về nguyên trên thư và không bao giờ được diễn giải: `emails.list` chỉ nhận `status`, `from`, `limit` và `cursor`, nên tag là thứ để đọc trên thư bạn đã có chứ không phải cách để tìm thư.
emails[].translateSendTranslateOptions
Gửi mục này bằng ngôn ngữ khác, được phân giải lúc chấp nhận để nội dung đã duyệt chính là nội dung được gửi đi. Tối đa 10 mục trong một lô được dùng trường này: mỗi mục tốn vài lượt gọi mô hình và các mục chạy tuần tự, nên lô lớn hơn sẽ bị ngắt giữa chừng. Vượt quá con số đó, cả lệnh gọi bị từ chối với `too_many_items` trên `emails`, trước khi bất cứ thứ gì được gửi.

Phản hồi: BatchResultResource

itemsBatchItemResource[]
Một mục cho mỗi đầu vào, theo đúng thứ tự bạn đã gửi. Không có gì bị hoàn tác, nên đây là bản ghi về những gì đã xảy ra với từng thư chứ không phải báo cáo về một giao dịch. API trả về 207 dù tất cả, một phần hay không thư nào được chấp nhận, nên promise luôn phân giải và `status` của từng mục mới là thứ để rẽ nhánh.
sentnumber
Số mục đã được CHẤP NHẬN, không giống với số thư đã được gửi đi. Một mục có thể là `ok` nhưng vẫn mang `email.status` là `failed` hoặc `partial`, vì tầng truyền tải từ chối thư sau khi bản ghi đã tồn tại là kết quả chuyển phát chứ không phải request bị từ chối.
failednumber
Số mục mang `error`. `failed > 0` là danh sách cần xử lý chứ không phải lý do để gửi lại cả lô. Các thư đã được chấp nhận thì đã được gửi đi.
items[].indexnumber
Vị trí của thư ứng với mục này trong mảng bạn đã gửi. Được trả về như một trường chứ không chỉ qua thứ tự, nên code lọc hoặc sắp xếp `items` vẫn biết đầu vào nào thất bại.
items[].status'ok' | 'error'
Trường phân biệt của union: `ok` mang `email`, `error` mang `error`, và không mục nào mang cả hai.
items[].emailSentEmailResource
Thư đã được chấp nhận, chỉ có trên mục `ok`, cùng cấu trúc với kết quả của một lần gửi đơn lẻ. Nó không có khóa `tracking`, vì mức độ tương tác được báo cáo sau và tại thời điểm chấp nhận thì chưa có gì để báo.
items[].email.replayedboolean
True khi `Idempotency-Key` suy ra khớp với một lần gửi đã tồn tại, nên không có gì mới được gửi và đây chính là thư ban đầu.
items[].error{ type: string; code: string; message: string; param?: string }
Lý do chính thư này bị từ chối, chỉ có trên mục `error`. Đây là phong bì lỗi của API, bỏ đi `docUrl` và `requestId`: hai trường đó mô tả request, còn request xét tổng thể thì đã thành công.
items[].error.typestring
Loại lỗi mà client có thể rẽ nhánh: `validation_error`, `permission_error`, `not_found_error`, `conflict_error` và các loại còn lại. Tập này cố định và sẽ không mở rộng, khác với `code`.
items[].error.codestring
Lỗi cụ thể: `from_address_forbidden`, `invalid_email_address`, `too_many_recipients`, `reserved_header`, `message_too_large`, `unknown_parameter`. Tập này mở và chỉ được bổ sung, nên hãy xử lý mã bạn không nhận ra theo `type` của nó.
items[].error.messagestring
Một câu viết cho người đọc, nêu giá trị gây lỗi nếu có. Không phải định danh ổn định. Hãy rẽ nhánh theo `code`.
items[].error.paramstring
Trường bị từ chối, dưới dạng đường dẫn phân tách bằng dấu chấm bên trong CHÍNH THƯ ĐÓ: `to.0`, `from`, `attachments`. Không có khi lỗi không liên quan tới trường nào, và không bao giờ có tiền tố là vị trí trong lô, vì đó là việc của `index`.