दस्तावेज़ पर जाएँ
Python

batch भेजें

`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 में हर input के लिए एक प्रविष्टि होती है, उसी क्रम में: या तो ok अपने संदेश के साथ, या error उस लिफ़ाफ़े के साथ जिसके साथ वह संदेश अस्वीकार किया जाता। कुछ भी वापस नहीं लौटता, इसलिए failed > 0 पूरे batch को दोबारा भेजने का कारण नहीं, बल्कि कार्रवाई करने के लिए एक सूची है।

एक idempotency कुंजी पूरे batch को ढकती है और सर्वर उसे प्रति आइटम बढ़ा देता है, इसलिए दोबारा भेजा गया batch हर संदेश को दोहराता है, उन्हें पहले पर समेटता नहीं।

पैरामीटर: emails.send_batch

emailsSequence[EmailSend]आवश्यक
एक से 100 तक संदेश, `{ "emails": [...] }` के रूप में serialize किए जाते हैं और दिए गए क्रम में एक-एक करके स्वीकार किए जाते हैं। ख़ाली list, 100 से ज़्यादा, या `translate` रखने वाले 10 से ज़्यादा आइटम पूरी कॉल को `emails` पर `validation_error` के साथ अस्वीकार करते हैं। ग़ायब `emails:send` scope और ख़राब `idempotency_key` भी ऐसा ही करते हैं, दोनों एक भी संदेश भेजे जाने से पहले।
idempotency_keystr
batch को प्रक्रियाओं के बीच डुप्लिकेट होने से बचाता है। क्लाइंट वैसे भी हर कॉल पर ताज़ा बनी कुंजी जोड़ता है, इसलिए उसके अपने retry कभी दोहरा नहीं भेजते, और सर्वर उसे जो भी कुंजी मिले उसे प्रति आइटम `key/0`, `key/1` इत्यादि में बढ़ा देता है (slash से पृथक, ऐसे वर्ण से जो आपकी अपनी कुंजी में नहीं हो सकता), ताकि सौ संदेशों पर एक कुंजी उन्हें पहले पर न समेट सके।
emails[].fromRecipientInputआवश्यक
भेजने वाला, सादे पते, `Name <addr@host>` या किसी dict के रूप में। कोई फ़ॉलबैक प्रेषक नहीं है और कुंजी को इस पते की अनुमति होनी चाहिए; इनकार उसी एक आइटम को विफल करता है, `permission_error` के रूप में, कोड `from_address_forbidden` के साथ।
emails[].toRecipientInput | list[RecipientInput]आवश्यक
कम से कम एक प्राप्तकर्ता, और अकेले प्राप्तकर्ता को क्लाइंट list में लपेट देता है। `to`, `cc` और `bcc` को मिलाकर अधिकतम 50 पते, जिनकी गिनती batch भर में नहीं बल्कि प्रति संदेश होती है।
emails[].ccRecipientInput | list[RecipientInput]
डिफ़ॉल्ट रूप से कोई नहीं, और यह `to` तथा `bcc` वाली उसी 50-पतों की कुल सीमा में गिना जाता है।
emails[].bccRecipientInput | list[RecipientInput]
डिफ़ॉल्ट रूप से कोई नहीं, और यह उसी 50-पतों की कुल सीमा में गिना जाता है। `Bcc` उन नामों में से एक है जिन्हें `headers` सेट नहीं कर सकता, इसलिए blind-copy का यही एकमात्र तरीक़ा है। header वाला रूप उस प्रति-प्राप्तकर्ता लिफ़ाफ़े को उलट देता जो पते को छिपाए रखता है।
emails[].replyToRecipientInput
उत्तर कहाँ जाएँ। यह `headers` के बाद लागू होता है, इसलिए वहाँ सेट किया गया `Reply-To` दूसरा जोड़ने के बजाय इससे बदल जाता है।
emails[].subjectstr
अधिकतम 998 वर्ण, यानी RFC 5322 की पंक्ति-सीमा, और डिफ़ॉल्ट रूप से खाली स्ट्रिंग। जब `template` अपना विषय देता है तो खाली विषय उसी पर चला जाता है।
emails[].htmlstr
HTML हिस्सा, अधिकतम दस लाख वर्ण, और दोनों body दिए जाने पर प्राप्तकर्ता इसी को देखते हैं। `html`, `text`, `template` या `draftId` में से एक ज़रूरी है, और जिस आइटम में इनमें से कोई न हो वह `html` पर `validation_error` के रूप में विफल होता है।
emails[].textstr
सादा-पाठ हिस्सा, अधिकतम दस लाख वर्ण। दोनों भेजे जा सकते हैं, और इस रास्ते का हर transport एक ही स्ट्रिंग से एक body बनाता है, इसलिए जहाँ `html` हो वहाँ वही जीतता है।
emails[].headersdict[str, str]
केवल `X-*`, `List-*`, Reply-To, Precedence, Auto-Submitted, Importance, Priority और Feedback-ID; जो कुछ transport ख़ुद सेट करता है (From, To, Bcc, Subject, Message-ID, DKIM और ARC headers) उसे चुपचाप गिराने के बजाय `reserved_header` के रूप में अस्वीकार किया जाता है। मान अधिकतम 998 वर्ण के होते हैं और उनमें CR, LF या NUL नहीं हो सकते, क्योंकि दूसरी पंक्ति यानी दूसरा header।
emails[].attachmentslist[AttachmentInput]
प्रति संदेश अधिकतम 20 फ़ाइलें, जिनमें inline फ़ाइलें decode होने के बाद कुल 5 MB तक, और यह गिनती प्रति संदेश है, प्रति batch नहीं। तार पर `content` base64 होता है; आप bytes दें और क्लाइंट उन्हें encode कर देता है। `{'fileId': ...}` वाली प्रविष्टि वर्कस्पेस में पहले से मौजूद फ़ाइल का नाम लेती है और inline सीमा में नहीं गिनी जाती।
emails[].threadIdstr
किसी मौजूदा thread में उत्तर दें, अधिकतम 256 वर्ण। transport इसी से In-Reply-To और References लिखता है, और यही वह चीज़ है जिससे उत्तर बातचीत के भीतर आता है, उसके बग़ल में नहीं।
emails[].draftIdstr
इस लिफ़ाफ़े के तहत किसी सहेजे गए draft की सामग्री भेजें, अधिकतम 256 वर्ण। यहाँ बनाए गए प्राप्तकर्ता, विषय और headers ही तार पर जाते हैं।
emails[].templateEmailSendTemplate
सर्वर पर संग्रहित template को render करें, id (`tpl_…`) या slug से, जहाँ `version` किसी revision को पिन करता है और `props`/`slots` उसे भरते हैं। यह आइटम स्वीकार होते समय एक ही बार हल किया जाता है, और `html`/`text` के साथ तथा `draftId` के साथ अस्वीकार होता है, क्योंकि इनमें से हर एक इस सवाल का दूसरा जवाब है कि संदेश में क्या है।
emails[].scheduledAtdatetime | str
एक `datetime`, एक ISO-8601 क्षण, या `PT1H` जैसी कोई अवधि; कम से कम एक सेकंड भविष्य में और अधिकतम 365 दिन आगे। आइटम स्वतंत्र रूप से निर्धारित होते हैं, इसलिए एक batch में सौ अलग-अलग भेजने के समय हो सकते हैं।
emails[].cancellableForSecondsint
तत्काल भेजे जाने पर सेकंडों में एक undo खिड़की, 0 से 900 के बीच एक integer, डिफ़ॉल्ट 0। 0 से ऊपर कुछ भी उसी आइटम पर `scheduledAt` के साथ अस्वीकार होता है, क्योंकि निर्धारित संदेश जाने तक वैसे भी रद्द किया जा सकता है।
emails[].trackingTrackingRequest
`opens` और `clicks`, दोनों स्वतंत्र रूप से वैकल्पिक और दोनों केवल इसी संदेश के लिए सेटिंग को अधिभावी करते हैं। जिस स्विच को आप छोड़ देते हैं वह उस पते का अनुसरण करता है जिससे संदेश भेजा गया है (या उसे पकड़ने वाले catch-all का), जो तब तक बंद रहती है जब तक उस पते ने उसे चालू न किया हो।
emails[].tagsdict[str, str]
अधिकतम 10 लेबल, कुंजियाँ 1 से 64 वर्ण की और `A-Za-z0-9_-` में से ली गई, और मान 256 वर्ण तक। ये संदेश पर वापस लौटाए जाते हैं और इनकी कभी व्याख्या नहीं होती: `emails.list` `status`, `from_`, `broadcast_id`, `scheduled_from` और `scheduled_to` पर फ़िल्टर करता है और किसी और पर नहीं, इसलिए tag संदेश ढूँढ़ने का तरीक़ा नहीं, बल्कि वह चीज़ है जिसे आप पहले से अपने पास मौजूद संदेश से पढ़ते हैं।
emails[].translateSendTranslateOptions
इस आइटम को किसी दूसरी भाषा में भेजें; यह स्वीकार होते समय हल किया जाता है, ताकि जो शब्द मंज़ूर हुए वही शब्द बाहर जाएँ। एक batch में अधिकतम 10 आइटम इसे रख सकते हैं: हर एक में कई model कॉल ख़र्च होती हैं और आइटम क्रम से चलते हैं, इसलिए बड़ा batch बीच में ही मार दिया जाता। उससे ज़्यादा होने पर पूरी कॉल कुछ भी भेजे जाने से पहले `emails` पर `too_many_items` के रूप में अस्वीकार हो जाती है।

प्रतिक्रिया: BatchResultResource

itemslist[BatchItemResource]
हर input के लिए एक प्रविष्टि, उसी क्रम में जिसमें आपने भेजे। कुछ भी वापस नहीं लौटता, इसलिए यह किसी लेनदेन की रिपोर्ट नहीं बल्कि इसका रिकॉर्ड है कि हर संदेश के साथ क्या हुआ। हर संदेश स्वीकार हुआ हो, कुछ हुए हों या एक भी न हुआ हो, API 207 ही देता है, इसलिए कॉल हर हाल में लौटती है और शाखा प्रति-आइटम `status` पर बनानी है।
sentint
कितने आइटम स्वीकार हुए, जो इससे अलग बात है कि कितने रवाना हुए। कोई आइटम `ok` हो सकता है और फिर भी `email.status` `failed` या `partial` रख सकता है, क्योंकि पंक्ति बन जाने के बाद संदेश को ठुकराने वाला transport डिलीवरी का परिणाम है, अस्वीकृत रिक्वेस्ट नहीं।
failedint
कितनी प्रविष्टियों में `error` है। `failed > 0` पूरे batch को दोबारा भेजने का कारण नहीं, बल्कि कार्रवाई करने के लिए एक सूची है। स्वीकार हुए संदेश पहले ही जा चुके हैं।
items[].indexint
आपकी भेजी list में इस प्रविष्टि के संदेश की जो स्थिति थी। यह क्रम के साथ-साथ एक फ़ील्ड के रूप में भी रखी जाती है, ताकि `items` को फ़िल्टर या sort करने वाला कोड भी बता सके कि कौन-सा input विफल हुआ।
items[].statusLiteral['ok', 'error']
union का विभेदक: `ok` `email` रखता है, `error` `error` रखता है, और कोई प्रविष्टि दोनों नहीं रखती।
items[].emailSentEmailResource
स्वीकार हुआ संदेश, केवल `ok` प्रविष्टि पर, उसी आकार में जिसमें एकल send लौटाता है। इसमें कोई `tracking` कुंजी नहीं होती, क्योंकि जुड़ाव की सूचना बाद में आती है और स्वीकार होने के समय बताने को कुछ है ही नहीं।
items[].email.replayedbool
true तब जब निकाली गई `Idempotency-Key` पहले से मौजूद किसी send से मेल खा गई, यानी कुछ भी नया नहीं भेजा गया और यह मूल संदेश है।
items[].errorBatchItemResourceErrorError
यह एक संदेश क्यों अस्वीकार हुआ, केवल `error` प्रविष्टि पर। यह API का त्रुटि-लिफ़ाफ़ा है, बस `docUrl` और `requestId` के बिना: वे रिक्वेस्ट का वर्णन करते हैं, और रिक्वेस्ट समग्र रूप से सफल रही।
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
किसी व्यक्ति के लिए लिखा एक वाक्य, जो जहाँ कोई आपत्तिजनक मान हो वहाँ उसका नाम लेता है। यह स्थिर पहचानकर्ता नहीं है। शाखा `code` पर बनाएँ।
items[].error.paramNotRequired[str]
जो फ़ील्ड अस्वीकार हुआ, उसी संदेश के भीतर बिंदु-पथ के रूप में: `to.0`, `from`, `attachments`। जब विफलता किसी फ़ील्ड का नाम न ले तब अनुपस्थित, और इसके आगे batch की स्थिति कभी नहीं लगती। वह `index` का काम है।

संदर्भ