ドキュメント本文へスキップ
Python

バッチ送信する

`emails.send_batch`: 最大 100 通、結果は項目ごとに返ります。

emails.send_batch

send_batch.py
import sys from openemail import openemailfrom openemail.types import EmailSend invoices = {'[email protected]': 'INV-4021', '[email protected]': 'INV-4022'} messages: list[EmailSend] = [    {'from': '[email protected]', 'to': to, 'subject': f'Invoice {number}', 'text': 'Attached.'}    for to, number in invoices.items()] result = openemail.emails.send_batch(messages) print(result['sent'], 'sent,', result['failed'], 'failed') for item in result['items']:    if item['status'] == 'error':        print(item['index'], item['error']['code'], item['error']['message'], file=sys.stderr)    else:        print(item['index'], item['email']['id'])

items には入力ごとに 1 エントリーが順番どおりに入り、それぞれメッセージを伴う ok か、そのメッセージが拒否された理由のエンベロープを伴う error のいずれかです。ロールバックはないので、failed > 0 はバッチを再送する理由ではなく、対処すべきリストです。

1 つの冪等キーがバッチ全体を覆い、サーバーが項目ごとにそれを拡張するので、再試行されたバッチはすべてのメッセージを再生し、最初の 1 通に畳み込まれることはありません。

パラメーター: emails.send_batch

emailsSequence[EmailSend]必須
1 通から 100 通のメッセージ。`{ "emails": [...] }` としてシリアライズされ、渡された順に 1 通ずつ受け付けられます。空のリスト、100 通超、`translate` を持つ項目が 10 件超のいずれかであれば、`emails` に対する `validation_error` で呼び出し全体が拒否されます。`emails:send` スコープの欠落や不正な `idempotency_key` も同様で、いずれも 1 通も送られる前に判定されます。
idempotency_keystr
プロセスをまたいでバッチを重複排除します。クライアントはいずれにせよ呼び出しごとに新しく生成したキーを付けるので、自身の再試行が二重送信になることはありません。サーバーは受け取ったキーを項目ごとに `key/0`、`key/1` のように拡張します。区切りにはあなたのキーに含められない文字であるスラッシュを使うので、100 通に 1 つのキーを使っても最初の 1 通に畳み込まれることはありません。
emails[].fromRecipientInput必須
送信者。素のアドレス、`Name <addr@host>`、または dict で指定します。フォールバックの送信者はなく、キーがそのアドレスを許可されている必要があります。拒否された場合はその項目だけが失敗し、コード `from_address_forbidden` の `permission_error` になります。
emails[].toRecipientInput | list[RecipientInput]必須
受信者は少なくとも 1 人必要で、1 人だけの場合はクライアントがリストに包みます。`to`、`cc`、`bcc` の合計で最大 50 アドレスであり、バッチ全体ではなくメッセージごとに数えます。
emails[].ccRecipientInput | list[RecipientInput]
既定ではなしです。`to` や `bcc` と同じ合計 50 アドレスの上限に数えられます。
emails[].bccRecipientInput | list[RecipientInput]
既定ではなしです。同じ合計 50 アドレスの上限に数えられます。`Bcc` は `headers` で設定できない名前の 1 つなので、ブラインドコピーの手段はこれだけです。ヘッダー形式では、アドレスを隠すための受信者ごとのエンベロープが台無しになってしまいます。
emails[].replyToRecipientInput
返信の宛先。`headers` の後に適用されるので、そこで設定した `Reply-To` に 2 つ目を足すのではなく上書きします。
emails[].subjectstr
RFC 5322 の行長制限である最大 998 文字で、既定は空文字列です。件名が空の場合、`template` が件名を持っていればテンプレート自身の件名が使われます。
emails[].htmlstr
HTML パート。最大 100 万文字で、両方の本文が与えられたときに受信者が見るのはこちらです。`html`、`text`、`template`、`draftId` のいずれか 1 つが必要で、どれも持たない項目は `html` に対する `validation_error` として失敗します。
emails[].textstr
プレーンテキストのパート。最大 100 万文字です。両方を送ることもできますが、この経路のすべてのトランスポートは 1 つの文字列から 1 つの本文を作るので、`html` があるときはそちらが勝ちます。
emails[].headersdict[str, str]
`X-*`、`List-*`、Reply-To、Precedence、Auto-Submitted、Importance、Priority、Feedback-ID のみです。トランスポート自身が設定するもの(From、To、Bcc、Subject、Message-ID、DKIM および ARC のヘッダー)は、黙って落とされるのではなく `reserved_header` として拒否されます。値は最大 998 文字で、CR、LF、NUL を含められません。2 行目は 2 つ目のヘッダーになってしまうからです。
emails[].attachmentslist[AttachmentInput]
1 通あたり最大 20 ファイルで、インラインのファイルはデコード後の合計 5 MB まで。これはバッチ単位ではなくメッセージ単位で数えます。`content` は通信上 base64 です。バイト列を渡せばクライアントがエンコードします。`{'fileId': ...}` のエントリーはワークスペースにすでにあるファイルを指し、インラインの上限には数えられません。
emails[].threadIdstr
既存のスレッドへ返信します。最大 256 文字。トランスポートはこれをもとに In-Reply-To と References を書き込み、それによって返信が会話の横ではなく中に着地します。
emails[].draftIdstr
保存済みの下書きの内容をこのエンベロープで送ります。最大 256 文字。ここで組み立てられた受信者、件名、ヘッダーが通信上のものになります。
emails[].templateEmailSendTemplate
保存されたテンプレートをサーバー側でレンダリングします。id(`tpl_…`)または slug で指定し、`version` でリビジョンを固定し、`props`/`slots` で値を埋めます。項目が受け付けられた時点で一度だけ解決され、`html`/`text` と併用した場合も `draftId` と併用した場合も拒否されます。いずれもメッセージの内容に対する二つ目の答えだからです。
emails[].scheduledAtdatetime | str
`datetime`、ISO-8601 の時刻、または `PT1H` のような期間。少なくとも 1 秒先で、最大 365 日先までです。項目ごとに独立して予約されるので、1 つのバッチが 100 通りの送信時刻を持てます。
emails[].cancellableForSecondsint
即時送信における取り消し猶予を秒で指定します。0 から 900 の integer で、既定は 0 です。0 より大きい値は、同じ項目上の `scheduledAt` と併用すると拒否されます。予約されたメッセージは送信されるまですでに取り消し可能だからです。
emails[].trackingTrackingRequest
`opens` と `clicks` で、それぞれ独立して省略可能であり、それぞれこのメッセージに限って設定を上書きします。省略したスイッチは、メッセージの送信元アドレス(またはそのアドレスを受け止めたキャッチオール)の設定に従い、そのアドレスでオンにしていない限りオフです。
emails[].tagsdict[str, str]
最大 10 個のラベル。キーは `A-Za-z0-9_-` から成る 1〜64 文字、値は最大 256 文字です。メッセージ上にそのまま返され、解釈されることはありません。`emails.list` が絞り込みに使うのは `status`、`from_`、`broadcast_id`、`scheduled_from`、`scheduled_to` だけなので、タグはメッセージを探す手段ではなく、すでに手元にあるメッセージから読み取るものです。
emails[].translateSendTranslateOptions
この項目を別の言語で送ります。受付時に解決されるので、承認された言葉がそのまま出ていきます。1 つのバッチでこれを持てるのは最大 10 項目です。各項目が複数回のモデル呼び出しを消費し、項目は順番に処理されるため、それより大きなバッチは送信途中で打ち切られてしまいます。それを超えると、何も送信される前に `emails` に対する `too_many_items` で呼び出し全体が拒否されます。

レスポンス: BatchResultResource

itemslist[BatchItemResource]
入力ごとに 1 エントリーを、送った順で返します。ロールバックはないので、これはトランザクションの報告ではなく、各メッセージに何が起きたかの記録です。API は、全通が受け付けられた場合も、一部だけの場合も、1 通も受け付けられなかった場合も 207 を返すので、呼び出しはいずれにせよ戻り、分岐すべきなのは項目ごとの `status` です。
sentint
何件が受け付けられたか。何件が出ていったかではありません。項目が `ok` でありながら `email.status` が `failed` や `partial` になることはあります。行ができた後でトランスポートがメッセージを拒んだ場合、それは配送の結果であって、拒否されたリクエストではないからです。
failedint
`error` を持つエントリーの数。`failed > 0` はバッチを再送する理由ではなく、対処すべきリストです。受け付けられたメッセージはすでに出ていきました。
items[].indexint
このエントリーのメッセージが、送ったリストの中で占めていた位置。順序だけでなくフィールドとしても持たせてあるので、`items` を絞り込んだり並べ替えたりするコードでも、どの入力が失敗したかを示せます。
items[].statusLiteral['ok', 'error']
ユニオンの判別子です。`ok` は `email` を、`error` は `error` を伴い、両方を持つエントリーはありません。
items[].emailSentEmailResource
受け付けられたメッセージ。`ok` のエントリーにのみ付き、単体送信が返すのと同じ形です。`tracking` キーは持ちません。エンゲージメントは後から報告されるもので、受付時点では報告すべきものが何もないからです。
items[].email.replayedbool
導出された `Idempotency-Key` がすでに存在する送信と一致したときに true になります。新しく送られたものはなく、これは元のメッセージです。
items[].errorBatchItemResourceErrorError
このメッセージ 1 通が拒否された理由。`error` のエントリーにのみ付きます。API のエラーエンベロープから `docUrl` と `requestId` を除いたものです。あの 2 つはリクエストについての情報であり、リクエスト全体としては成功しているからです。
items[].error.typestr
クライアントが分岐に使える分類です。`validation_error`、`permission_error`、`not_found_error`、`conflict_error` などがあります。この集合は凍結されており、`code` と違って増えません。
items[].error.codestr
具体的な失敗。`from_address_forbidden`、`invalid_email_address`、`too_many_recipients`、`reserved_header`、`message_too_large`、`unknown_parameter` などです。開かれた追加型なので、知らないコードはその `type` として扱ってください。
items[].error.messagestr
人向けに書かれた 1 文で、問題の値があればそれを名指しします。安定した識別子ではありません。分岐は `code` で行ってください。
items[].error.paramNotRequired[str]
拒否されたフィールドを、そのメッセージ内のドット区切りパスで示します。`to.0`、`from`、`attachments` のような形です。フィールドを特定できない失敗では存在せず、バッチ内の位置が前置されることはありません。そちらは `index` の役目です。

リファレンス