batch भेजें
`emails->sendBatch`: 100 संदेशों तक, हर आइटम का अलग नतीजा।
emails->sendBatch
$invoices = [ ['number' => 'INV-1042', 'email' => '[email protected]'], ['number' => 'INV-1043', 'email' => '[email protected]'],]; $messages = []; foreach ($invoices as $invoice) { $messages[] = [ 'from' => '[email protected]', 'to' => $invoice['email'], 'subject' => 'Invoice ' . $invoice['number'], 'text' => 'Your invoice is attached.', ];} $result = $client->emails->sendBatch($messages, idempotencyKey: 'invoices:2026-09'); echo $result->sent, ' sent, ', $result->failed, ' failed', PHP_EOL; foreach ($result as $item) { if ($item['status'] === 'error') { error_log($item['index'] . ' ' . $item['error']['code'] . ' ' . $item['error']['message']); } else { echo $item['index'], ' ', $item['email']['id'], PHP_EOL; }}sendBatch संदेश arrays की एक सूची लेता है, हर एक ठीक उसी आकार का जैसा array emails->send लेता है, और एक OpenEmail\Result\BatchResult लौटाता है। इसके items में हर संदेश के लिए क्रम से एक array होता है, हर एक या तो अपने संदेश के साथ ok या उस envelope के साथ error जिससे वह संदेश अस्वीकार हुआ होता, और नतीजे पर लूप चलाने से इन पर चला जाता है। कुछ भी rollback नहीं होता, इसलिए 0 से ज़्यादा failed संख्या बैच दोबारा भेजने का कारण नहीं, बल्कि कार्रवाई करने के लिए एक सूची है।
एक idempotency कुंजी पूरे बैच को कवर करती है और सर्वर उसे हर आइटम के लिए बढ़ाता है, इसलिए retry किया गया बैच सभी संदेशों को पहले वाले में समेटने के बजाय हर संदेश को replay करता है। retry करते समय वही सूची उसी क्रम में भेजें: जो आइटम खिसक गया, वह किसी दूसरी स्थिति की कुंजी से बंध जाता है और idempotency_key_reuse error के रूप में लौटता है।
अस्वीकार किया गया संदेश throw नहीं करता। सिर्फ़ पूरे बैच की समस्या throw करती है: ख़ाली सूची, 100 से ज़्यादा संदेश, translate वाले 10 से ज़्यादा संदेश, कुंजी या scope की विफलता, या सर्वर की गड़बड़ी। बीच में आई सर्वर की गड़बड़ी पहले के आइटम जाने के बाद आती है, और क्लाइंट उसे उसी कुंजी के साथ retry करता है, जो उन आइटम को दो बार भेजने के बजाय replay करती है।
आइटम एक ही रिक्वेस्ट के अंदर एक के बाद एक भेजे जाते हैं, इसलिए तुरंत वाले sends का बड़ा बैच एक send से काफ़ी ज़्यादा समय लेता है। क्लाइंट का timeout: उदार रखें।
पैरामीटर: emails->sendBatch
emailsarrayआवश्यक- 1 से 100 संदेश, `{"emails": [...]}` के रूप में भेजे जाते हैं और दिए गए क्रम में एक-एक करके स्वीकार किए जाते हैं। हर एक `emails->send` जैसी ही प्रक्रिया से गुज़रता है, इसलिए अकेला प्राप्तकर्ता लपेटा जाता है, `DateTimeInterface` एक क्षण बन जाता है और अटैचमेंट के बाइट्स encode होते हैं, और जो प्रविष्टि array नहीं है वह कुछ भी भेजे जाने से पहले `InvalidArgumentException` throw करती है। ख़ाली सूची, 100 से ज़्यादा, या `translate` वाले 10 से ज़्यादा संदेश पूरी कॉल को `emails` पर `validation_error` के साथ अस्वीकार कर देते हैं। ग़ायब `emails:send` scope और ग़लत रूप वाला `idempotencyKey:` भी एक भी संदेश भेजे जाने से पहले पूरी कॉल को अस्वीकार कर देते हैं।
idempotencyKeystring- प्रोसेस के पार बैच का दोहराव हटाता है। क्लाइंट हर हाल में हर कॉल पर एक नई बनी कुंजी जोड़ता है, ताकि उसके अपने पुनः प्रयास कभी दो बार न भेजें, और सर्वर उसे मिली कुंजी को हर आइटम के लिए `key/0`, `key/1` इत्यादि के रूप में आगे बढ़ाता है, slash से अलग किया हुआ, ऐसा वर्ण जो आपकी अपनी कुंजी में नहीं हो सकता, ताकि सौ संदेशों पर एक कुंजी उन सबको पहले वाले पर न समेट सके।
apiKeystring- क्लाइंट की कुंजी के बजाय इस कुंजी से बैच भेजता है।
emails में हर संदेश
fromstring or arrayआवश्यक- भेजने वाला, सादे पते, `Name <addr@host>` या `email` और `name` वाले array के रूप में। कोई fallback भेजने वाला नहीं है और कुंजी को इस पते की अनुमति होनी चाहिए। अस्वीकार होने पर सिर्फ़ वह एक आइटम विफल होता है, `from_address_forbidden` कोड वाले `permission_error` के रूप में।
tostring or arrayआवश्यक- कम से कम एक प्राप्तकर्ता, और अकेले प्राप्तकर्ता को क्लाइंट एक सूची में लपेट देता है। `to`, `cc` और `bcc` को मिलाकर अधिकतम 50 पते, जो पूरे बैच के बजाय हर संदेश के लिए गिने जाते हैं।
ccstring or array- डिफ़ॉल्ट रूप से कोई नहीं, और यह `to` तथा `bcc` वाली उसी 50-पतों की कुल सीमा में गिना जाता है।
bccstring or array- डिफ़ॉल्ट रूप से कोई नहीं, और यह उसी 50-पतों की कुल सीमा में गिना जाता है। `Bcc` उन नामों में से एक है जिन्हें `headers` सेट नहीं कर सकता, इसलिए blind-copy का यही एकमात्र तरीक़ा है। header वाला रूप उस प्रति-प्राप्तकर्ता लिफ़ाफ़े को उलट देता जो पते को छिपाए रखता है।
replyTostring or array- उत्तर कहाँ जाएँ। यह `headers` के बाद लागू होता है, इसलिए वहाँ सेट किया गया `Reply-To` दूसरा जोड़ने के बजाय इससे बदल जाता है।
subjectstring- अधिकतम 998 अक्षर, जो RFC 5322 की पंक्ति सीमा है, और डिफ़ॉल्ट रूप से ख़ाली स्ट्रिंग। जब `template` अपना subject देता है, तो ख़ाली subject की जगह टेम्पलेट का अपना subject लिया जाता है।
htmlstring- HTML हिस्सा, अधिकतम दस लाख वर्ण, और दोनों body दिए जाने पर प्राप्तकर्ता इसी को देखते हैं। `html`, `text`, `template` या `draftId` में से एक ज़रूरी है, और जिस आइटम में इनमें से कोई न हो वह `html` पर `validation_error` के रूप में विफल होता है।
textstring- सादा-पाठ हिस्सा, अधिकतम दस लाख वर्ण। दोनों भेजे जा सकते हैं, और इस रास्ते का हर transport एक ही स्ट्रिंग से एक body बनाता है, इसलिए जहाँ `html` हो वहाँ वही जीतता है।
headersarray- सिर्फ़ `X-*`, `List-*`, Reply-To, Precedence, Auto-Submitted, Importance, Priority और Feedback-ID। transport जो कुछ ख़ुद सेट करता है (From, To, Bcc, Subject, Message-ID, DKIM और ARC हेडर) उसे चुपचाप हटाने के बजाय `reserved_header` के रूप में अस्वीकार किया जाता है। मान अधिकतम 998 वर्ण के होते हैं और उनमें CR, LF या NUL नहीं हो सकते, क्योंकि दूसरी पंक्ति यानी दूसरा हेडर।
attachmentsarray- हर संदेश में अधिकतम 20 फ़ाइलें, जिनमें inline फ़ाइलें डिकोड होने के बाद कुल 5 MB तक, जो बैच के बजाय हर संदेश के लिए गिनी जाती हैं। नेटवर्क पर `content` base64 होता है। `fopen` का stream, `SplFileInfo` या PSR-7 stream पास करें तो क्लाइंट उसे पढ़कर encode कर देता है, या पहले से base64 स्ट्रिंग पास करें। सिर्फ़ `fileId` वाला array वर्कस्पेस में पहले से मौजूद फ़ाइल का नाम लेता है और inline सीमा में नहीं गिना जाता।
threadIdstring- किसी मौजूदा thread में उत्तर दें, अधिकतम 256 वर्ण। transport इसी से In-Reply-To और References लिखता है, और यही वह चीज़ है जिससे उत्तर बातचीत के भीतर आता है, उसके बग़ल में नहीं।
draftIdstring- सहेजे गए ड्राफ़्ट की सामग्री इस envelope के तहत भेजें, अधिकतम 256 वर्ण। यहाँ बनाए गए प्राप्तकर्ता, विषय और हेडर ही नेटवर्क पर जाते हैं।
templatearray- सहेजे गए टेम्पलेट को सर्वर पर रेंडर करें, id (`tpl_…`) या slug से, जहाँ `version` किसी संस्करण को पिन करता है और `props` तथा `slots` उसे भरते हैं। आइटम स्वीकार होते समय एक बार तय होता है, और `html` या `text` के साथ तथा `draftId` के साथ अस्वीकार किया जाता है, क्योंकि इनमें से हर एक इस सवाल का दूसरा जवाब है कि संदेश में क्या है।
scheduledAtDateTimeInterface or string- एक `DateTimeInterface`, ISO 8601 क्षण, या `PT1H` जैसी अवधि, भविष्य में कम से कम एक सेकंड और अधिकतम 365 दिन आगे। बिना समय वाली तारीख़ की स्ट्रिंग का मतलब उस दिन की UTC आधी रात है। आइटम अलग-अलग शेड्यूल होते हैं, इसलिए एक बैच में सौ अलग-अलग भेजने के समय हो सकते हैं।
cancellableForSecondsint- तुरंत वाले send पर सेकंड में undo विंडो, 0 से 900, डिफ़ॉल्ट 0। उसी आइटम पर `scheduledAt` के साथ 0 से ऊपर का कोई भी मान अस्वीकार होता है, क्योंकि शेड्यूल किया गया संदेश जाने तक पहले से ही रद्द किया जा सकता है।
trackingarray- `opens` और `clicks`, दोनों वैकल्पिक और दोनों सिर्फ़ इसी संदेश के लिए सेटिंग को बदलते हैं। जो कुंजी आप छोड़ देते हैं वह उस पते का अनुसरण करती है जिससे संदेश भेजा जाता है (या उसे पकड़ने वाले catch-all का), जो तब तक बंद है जब तक उस पते ने उसे चालू न किया हो।
tagsarray- अधिकतम 10 लेबल, जिनकी कुंजियाँ `A-Za-z0-9_-` में से 1 से 64 वर्णों की और मान 256 तक। संदेश पर वापस लौटाए जाते हैं और इनकी कभी व्याख्या नहीं होती: `emails->list` सिर्फ़ `status:`, `from:`, `broadcastId:` और शेड्यूल विंडो पर फ़िल्टर करता है, और कुछ नहीं, इसलिए टैग ऐसी चीज़ है जिसे आप पहले से हाथ में मौजूद संदेश से पढ़ते हैं, उसे ढूँढने का तरीका नहीं।
translatearray- इस आइटम को दूसरी भाषा में भेजें, जो स्वीकार होते समय तय होता है ताकि जो शब्द स्वीकृत हुए वही बाहर जाएँ। एक बैच में अधिकतम 10 आइटम में यह हो सकता है: हर एक कई मॉडल कॉल ख़र्च करता है और आइटम क्रम से चलते हैं, इसलिए बड़ा बैच भेजते-भेजते बीच में ही ख़त्म कर दिया जाता। इससे ज़्यादा होने पर, कुछ भी भेजे जाने से पहले, पूरी कॉल `emails` पर `too_many_items` के रूप में अस्वीकार हो जाती है।
जवाब: OpenEmail\Result\BatchResult
नतीजा read-only है, items पर IteratorAggregate और Countable, इसलिए foreach ($result as $item) आइटम पर चलता है और count($result) उन्हें गिनता है।
itemsarray- हर संदेश के लिए एक array, उसी क्रम में जिसमें आपने भेजा। कुछ भी rollback नहीं होता, इसलिए यह किसी transaction की रिपोर्ट नहीं, बल्कि हर संदेश के साथ क्या हुआ इसका रिकॉर्ड है। API 207 का जवाब देता है चाहे हर संदेश स्वीकार हुआ हो, कुछ हुए हों या कोई नहीं, इसलिए कॉल हर हाल में लौटती है और branch करने के लिए हर आइटम का `status` देखें।
sentint or null- कितने आइटम “स्वीकार” हुए, जो इसके बराबर नहीं कि कितने गए। कोई आइटम `ok` होकर भी ऐसा `email` रख सकता है जिसका `status` `failed` या `partial` हो, क्योंकि पंक्ति बनने के बाद transport द्वारा संदेश को अस्वीकार करना delivery का नतीजा है, अस्वीकार की गई रिक्वेस्ट नहीं। null सिर्फ़ तब, जब जवाब में कोई संख्या न हो।
failedint or null- कितने आइटम में `error` है। 0 से ऊपर की गिनती बैच को दोबारा भेजने का कारण नहीं, बल्कि कार्रवाई करने की सूची है। स्वीकार हुए संदेश पहले ही जा चुके हैं।
हर आइटम
indexint- भेजी गई सूची में इस आइटम के संदेश की स्थिति। यह क्रम के साथ-साथ एक कुंजी के रूप में भी रहती है, इसलिए `items` को फ़िल्टर या sort करने वाला कोड भी बता सकता है कि कौन-सा संदेश विफल हुआ।
statusstring- `ok` या `error`। `ok` में `email` होता है, `error` में `error`, और किसी आइटम में दोनों नहीं होते।
emailarray- स्वीकार हुआ संदेश, सिर्फ़ `ok` आइटम पर, उसी आकार में जो एक अकेला send लौटाता है। जब निकाली गई `Idempotency-Key` पहले से मौजूद send से मेल खाती है तो उसका `replayed` true होता है, यानी कुछ नया नहीं भेजा गया और यह मूल संदेश है। इसमें कोई `tracking` कुंजी नहीं होती, क्योंकि engagement की रिपोर्ट बाद में आती है और स्वीकार होते समय बताने को कुछ नहीं होता।
errorarray- यह एक संदेश क्यों अस्वीकार हुआ, सिर्फ़ `error` आइटम पर। यह API का error envelope है, `docUrl` और `requestId` के बिना: वे रिक्वेस्ट का वर्णन करते हैं, और रिक्वेस्ट कुल मिलाकर सफल रही।
किसी आइटम की error
typestring- वह श्रेणी जिस पर शाखा बनानी है: `validation_error`, `permission_error`, `not_found_error`, `conflict_error` और बाक़ी। यह सेट frozen है और बढ़ेगा नहीं, `code` के विपरीत।
codestring- विशिष्ट विफलता: `from_address_forbidden`, `invalid_email_address`, `too_many_recipients`, `reserved_header`, `message_too_large`, `unknown_parameter`। यह खुला है और इसमें नए मान जुड़ सकते हैं, इसलिए जिस कोड को आप न पहचानें उसे उसके `type` की तरह मानें। यहाँ इसका नाम `code` है क्योंकि यह डिकोड किया गया envelope है, जबकि exception यही मान `errorCode` के रूप में रखता है।
messagestring- किसी व्यक्ति के लिए लिखा एक वाक्य, जो जहाँ कोई आपत्तिजनक मान हो वहाँ उसका नाम लेता है। यह स्थिर पहचानकर्ता नहीं है। शाखा `code` पर बनाएँ।
paramstring- अस्वीकार किया गया फ़ील्ड, “उसी” संदेश के भीतर बिंदुओं वाले path के रूप में: `to.0`, `from`, `attachments`। जब विफलता किसी फ़ील्ड का नाम न ले तो यह नहीं होता, और इसके आगे कभी बैच की स्थिति नहीं लगती, उसके लिए `index` है।