एंडपॉइंट
`webhooks.list`, `list_all`, `iterate`, `get`, `create`, `update`, `delete`, `rotate_secret`, `test`, `get_delivery` और `replay_delivery`, और डिलीवरी तथा गतिविधि लॉग।
हर मेथड
endpoint = client.webhooks.create( url: "https://acme.com/hooks/mail", eventTypes: ["email.sent", "email.bounced"], description: "Billing service") File.write(".openemail-webhook-secret", endpoint[:secret]) client.webhooks.listclient.webhooks.get(endpoint[:id])client.webhooks.update(endpoint[:id], enabled: false)client.webhooks.test(endpoint[:id])latest = client.webhooks.list_deliveries(endpoint[:id], limit: 1).items.firstclient.webhooks.get_delivery(endpoint[:id], latest[:id])client.webhooks.replay_delivery(endpoint[:id], latest[:id])rotated = client.webhooks.rotate_secret(endpoint[:id])File.write(".openemail-webhook-secret", rotated[:secret])client.webhooks.delete(endpoint[:id])rotate_secret के अलावा, create ही “इकलौता” मौक़ा है जब secret लौटाया जाता है। कोई read इसे कभी नहीं लौटाता, इसलिए कुछ और करने से पहले इसे सहेज लें। डिफ़ॉल्ट सेट के लिए eventTypes छोड़ दें, जो email.replied को छोड़ हर email.* इवेंट है। email.replied, domain.*, suppression.*, file.* और form.* किसी endpoint तक तभी पहुँचते हैं जब वह उनके नाम ले।
rotate_secret में कोई overlap विंडो नहीं है। पुराना secret तुरंत काम करना बंद कर देता है, इसलिए rotate करने से पहले नया deploy करें। इस पर कभी अपने-आप पुनः प्रयास नहीं होता: पुनः प्रयास दूसरी बार rotate कर देता और पहले प्रयास से लौटा secret अमान्य कर देता।
create पर भी पुनः प्रयास नहीं होता, इसलिए नेटवर्क विफलता ऐसा endpoint बना छोड़ सकती है जिसका secret आपने कभी देखा ही नहीं। दोबारा बनाने से पहले list जाँचें। एक वर्कस्पेस में डिफ़ॉल्ट रूप से 10 endpoints होते हैं, और सीमा के बाद अगला 422 workspace_limit_reached है।
आप किसकी सदस्यता ले सकते हैं
OpenEmail::WEBHOOK_EVENTS हर इवेंट नाम का एक frozen Hash है, ताकि आप बिना रिक्वेस्ट के सूची दिखा सकें, और webhooks.list_events वही नाम हर एक के एक वाक्य के साथ लौटाता है, साथ में वे सीमाएँ जिनमें endpoint बँधा है। इवेंट **मेलबॉक्स** के इवेंट हैं, इस API के नहीं: email.received ऐप में आने वाले मेल के लिए चलता है, और email.sent composer द्वारा भेजे संदेश के लिए। subscribe करना अपने API ट्रैफ़िक पर नज़र रखने जैसा नहीं है।
file.uploaded तब चलता है जब कोई फ़ाइल “फ़ाइलें” पेज पर रखी जाती है, और file.deleted जब कोई हटाई जाती है। उनके data में fileId, filename, mimeType, sizeBytes, direction, to, threadId, messageId, और uploadedAt या deletedAt होते हैं। to वह पता है जिसकी फ़ाइल है, या पूरे वर्कस्पेस की फ़ाइल के लिए nil।
फ़ाइल इवेंट डिफ़ॉल्ट सेट में नहीं हैं, इसलिए endpoint उन्हें तभी पाता है जब वह eventTypes में उनके नाम ले। कुछ पतों तक सीमित endpoint सिर्फ़ उन्हीं पतों की फ़ाइलों के बारे में सुनता है, इसलिए पूरे वर्कस्पेस के लिए हुआ अपलोड, to nil वाला, उसे नहीं भेजा जाता।
form.submitted तब चलता है जब कोई आपके किसी फ़ॉर्म से साइन अप करता है, और form.confirmed तब जब कोई लंबित साइन-अप ऑडियंस में जुड़ता है, क्योंकि व्यक्ति ने पुष्टि लिंक खोला या आपने उसे मंज़ूरी दी। form.submitted के data में formId, formName, submissionId, email, status, answers, audienceIds, sourceUrl और submittedAt होते हैं। form.confirmed के data में formId, formName, submissionId, email, audienceIds, via, जो link या approval है, और confirmedAt होते हैं।
डबल ऑप्ट-इन के बिना वाले फ़ॉर्म पर साइन-अप status added के साथ form.submitted भेजता है और कोई form.confirmed नहीं, इसलिए उसी को वह क्षण मानें जब कोई जुड़ता है। पुष्टि से पहले फिर से साइन-अप करने वाले का submissionId वही रहता है, और form.submitted दोबारा तभी भेजा जाता है जब उसके जवाब बदले हों। फ़ॉर्म events डिफ़ॉल्ट सेट में नहीं हैं, और कुछ पतों तक सीमित endpoint इन्हें कभी नहीं पाता, क्योंकि साइन-अप पूरे वर्कस्पेस के होते हैं।
यह साबित करना कि यह काम करता है
result = client.webhooks.test("whe_3f9c2a7b1e4d8f60a5c7b92d")puts result.dig(:delivery, :status), result.dig(:delivery, :responseCode) client.webhooks.iterate_deliveries("whe_3f9c2a7b1e4d8f60a5c7b92d") do |delivery| puts "#{delivery[:eventType]} #{delivery[:status]} #{delivery[:responseCode]} #{delivery[:error]}"endtest एक हस्ताक्षरित कृत्रिम email.sent इवेंट POST करता है और प्रयास पूरा होने का इंतज़ार करता है। आपके receiver ने जो भी जवाब दिया हो, यह सामान्य रूप से लौटता है, इसलिए शाखा delivery[:status] पर बनाएँ, इस पर नहीं कि कॉल ने raise किया या नहीं। 4xx एक उपयोगी जवाब है: URL पहुँच योग्य है और अस्वीकार आपके अपने handler से आया, अक्सर उसकी सिग्नेचर जाँच से।
responseCode का nil होना मतलब कोई जवाब आया ही नहीं (DNS, TLS, टाइमआउट), जो 0 कहने वाले जवाब से अलग तथ्य है। हर पंक्ति में attempt और maxAttempts होते हैं, इसलिए कई पंक्तियाँ एक इवेंट का वर्णन कर सकती हैं: उनमें एक जैसा eventId इवेंट है, और प्रयास संख्या कोशिश है। nextAttemptAt बताता है कि किसी पंक्ति के बाद अपने-आप होने वाला पुनः प्रयास कब होना है।
इसे दोबारा भेजना
detail = client.webhooks.get_delivery("whe_3f9c2a7b1e4d8f60a5c7b92d", "whd_8c1e4a7f2b9d3e6a0c5f1b28")p detail[:payload], detail[:responseBody], detail[:replayRefusal] replay = client.webhooks.replay_delivery("whe_3f9c2a7b1e4d8f60a5c7b92d", "whd_8c1e4a7f2b9d3e6a0c5f1b28")p replay.dig(:delivery, :status), replay.dig(:delivery, :responseCode)जो delivery लगातार विफल होती रहे, उसे 8 बार तक आज़माया जाता है: तुरंत, फिर 1 मिनट, 5 मिनट, 30 मिनट, 2 घंटे, 5 घंटे, 10 घंटे और फिर 10 घंटे बाद, कुल मिलाकर लगभग साढ़े 27 घंटे। केवल वही विफलता दोहराई जाती है जिसे दोहराना सार्थक हो: कोई जवाब नहीं, 408, 425, 429 या कोई 5xx। replay सहेजे गए event को उसी id, type, createdAt और data के साथ फिर भेजता है, इसलिए जो receiver पहले से संभाली गई ids को छोड़ देता है, वह इसे वही event मानता है जिसे वह जानता है। केवल signature नया होता है।
replay_deliveryएक इवेंट अभी भेजता है और लौटाता है कि आपके सर्वर ने क्या जवाब दिया। यह डिलीवर हो चुके प्रयास पर भी काम करता है और इस पर कभी पुनः प्रयास नहीं होता। भेजने से पहले उस इवेंट के अपने-आप होने वाले वे पुनः प्रयास जो शुरू नहीं हुए, रोक दिए जाते हैं: replay डिलीवर होने पर वे रद्द ही रहते हैं, और विफल होने पर अपने शेड्यूल पर फिर शुरू हो जाते हैं।- अगर उसी पल उसी इवेंट का कोई अपने-आप होने वाला पुनः प्रयास भेजा जा रहा हो, तो
replay_deliveryकुछ नहीं भेजता और 409retry_in_progressraise करता है, और जब उसका कोई दूसरा replay अभी भेजा जा रहा हो तो यह 409replay_in_progressraise करता है, ताकि आपके receiver को कभी एक साथ दो कॉपियाँ न मिलें, एक ही पल में भेजे गए दो replays से भी नहीं। कुछ सेकंड रुकें औरget_deliveryपढ़ें, क्योंकि वह पुनः प्रयास या replay उसे डिलीवर कर सकता है। replay एक बार में एक इवेंट का होता है: कोई भी कॉल हर विफल डिलीवरी दोबारा नहीं भेजती। - यह बंद किए गए endpoint (
webhook_disabled), ऐसे इवेंट जिसे endpoint अब नहीं सुनता (event_not_subscribed) या अब कवर नहीं करता (event_out_of_scope), और बिना सहेजे इवेंट वाले प्रयास (delivery_not_replayable) के लिए भी 409 raise करता है।get_deliveryयह जवाब पहले सेreplayRefusalके रूप में बताता है।
gem replay_delivery पर कभी अपने-आप पुनः प्रयास नहीं करता, क्योंकि खोए जवाब के बाद पुनः प्रयास इवेंट को फिर भेज देता।
पैरामीटर: webhooks.create
urlStringआवश्यक- जहाँ डिलीवरी POST की जाती हैं। सिर्फ़ HTTPS, और होस्ट `localhost`, `.localhost`, `.local` या `.internal` वाला नाम, या loopback, private, CGNAT या link-local IP literal नहीं हो सकता। यह आपके दिए पते पर सर्वर की ओर से की गई रिक्वेस्ट है, इसलिए ये सब `url` पर 422 `invalid_webhook_url` हैं। जाँच hostname को जैसा लिखा है वैसा पढ़ती है, और हर डिलीवरी होस्ट को फिर से खोजती है और इन श्रेणियों में से किसी के पते पर भेजने से इनकार करती है। डिलीवरी कभी redirect नहीं मानतीं, इसलिए अंतिम पता दर्ज करें। जो सहेजा जाता है वह आपके भेजे का URL parser वाला serialisation है, इसलिए `https://acme.com` वापस `https://acme.com/` के रूप में पढ़ा जाता है।
eventTypesArray<String>- कौन-से इवेंट इस endpoint तक पहुँचते हैं: `OpenEmail::WEBHOOK_EVENTS` के मानों में से कोई भी। `create` Array को मौजूद इवेंट की संख्या पर सीमित करता है, इसलिए उससे एक ज़्यादा `eventTypes` पर 422 है, और `update` इसे सीमित नहीं करता। सिर्फ़ लंबाई सीमित है, और दोहराया गया नाम ठीक वैसा ही सहेजा और पढ़ा जाता है जैसा आपने भेजा। छोड़ने या ख़ाली होने पर यह ख़ाली सूची के रूप में सहेजा जाता है, इसीलिए यह `["*"]` के रूप में पढ़ा जाता है, और इसका मतलब है `email.replied` को छोड़ हर `email.*` इवेंट, आज चौदह, और कभी domain, suppression, file या form परिवार नहीं। बाद में जोड़ा गया परिवार कभी ऐसे endpoint तक नहीं पहुँचता जिसने उसका नाम न लिया हो, इसलिए कोई integration किसी रिलीज़ की वजह से ऐसा आकार पाना शुरू नहीं कर सकता जो उसने कभी देखा ही न हो।
descriptionString- endpoint के लिए एक लेबल, अधिकतम 200 वर्ण, ताकि वेबहुक की सूची URLs के कॉलम के बजाय नामों की तरह पढ़ी जाए। छोड़ने पर यह nil के रूप में सहेजा और लौटाया जाता है।
addressAllowlistArray<String>- अलग-अलग पते जिनके बारे में यह endpoint सुनता है। कोई इवेंट तब डिलीवर होता है जब उससे जुड़ा पता इस सूची में हो, या उसका डोमेन `domainAllowlist` में हो। दोनों ख़ाली छोड़ें तो endpoint वर्कस्पेस के हर पते के बारे में सुनता है। अधिकतम 50, और जो पता इस वर्कस्पेस का नहीं है वह 422 `invalid_parameter` है।
domainAllowlistArray<String>- पूरे डोमेन जिनके बारे में यह endpoint सुनता है, उनमें बाद में जोड़े गए पतों समेत। डोमेन अपने `domain.*` इवेंट भी लाता है। अधिकतम 25।
api_keyString- क्लाइंट की कुंजी के बजाय इस कुंजी से endpoint बनाता है।
जवाब: बनाया गया endpoint
Symbol कुंजियों वाला एक Hash। get, list और update यही आकार secret के बिना लौटाते हैं।
objectString- हमेशा `webhook`, वही discriminator जो सादा read लौटाता है, क्योंकि secret सामान्य आकार पर एक अतिरिक्त कुंजी है, कोई अलग object टाइप नहीं। `secret` मौजूद है या नहीं, यह इस फ़ील्ड से नहीं, इससे तय होता है कि आपने कौन-सा मेथड कॉल किया।
idString- endpoint का पहचानकर्ता: `whe_` के बाद 24 hex वर्ण। वेबहुक की हर दूसरी कॉल इसे लेती है: `get`, `update`, `delete`, `rotate_secret`, `test`, `list_deliveries`, `list_all_deliveries`, `iterate_deliveries`, `get_delivery` और `replay_delivery`।
urlString- endpoint जैसा सहेजा गया, HTTPS और blocked-host जाँचें पार करने के बाद। यह पार्स किया गया URL है जिसे दोबारा serialise किया गया, इसलिए अपनी भेजी String से नहीं, इस मान से तुलना करें।
descriptionString or nil- आपका दिया लेबल, या nil अगर आपने कोई न दिया हो। `description: nil` भेजने वाला `update` इसे साफ़ कर देता है।
eventTypesArray<String>- subscribe किए गए इवेंट, या `["*"]` जब endpoint ने किसी का नाम न लिया हो। `["*"]` वह रूप है जिसमें ख़ाली सहेजी गई सूची read पर दिखती है और इसे वापस नहीं भेजा जा सकता, और यह पूरी सूची के बजाय चौदह संदेश इवेंट दर्शाता है। `create` और `update` सिर्फ़ शाब्दिक इवेंट नाम स्वीकार करते हैं।
enabledBoolean- क्या डिलीवरी का प्रयास होता है। निष्क्रिय endpoint इवेंट भेजे जाते समय छोड़ दिया जाता है और अपना secret तथा डिलीवरी इतिहास बनाए रखता है। यहाँ हमेशा true, क्योंकि सिर्फ़ `update` `enabled` लेता है।
disabledAtString or nil- जब सर्वर ने लगातार 100 विफल डिलीवरी के बाद endpoint बंद किया। चालू रहने पर nil, और तब भी जब आपने ख़ुद उसे बंद किया हो।
disabledReasonString or nil- सर्वर ने इसे क्यों बंद किया। जब भी `disabledAt` nil हो तब nil।
consecutiveFailuresInteger- लगातार विफल डिलीवरी। कोई भी डिलीवर हुआ इवेंट इसे 0 पर रीसेट करता है, और `enabled: true` के साथ `update` भी।
addressAllowlistArray<String>- अलग-अलग पते जिनके बारे में यह endpoint सुनता है।
domainAllowlistArray<String>- पूरे डोमेन जिनके बारे में यह endpoint सुनता है। दोनों सूचियाँ ख़ाली होने का मतलब वर्कस्पेस का हर पता।
lastDeliveryAtString or nil- आख़िरी डिलीवरी “प्रयास” का ISO 8601 timestamp, आख़िरी सफलता का नहीं। यह विफल POST के बाद भी लगता है, इसलिए यह बताता है कि endpoint को आज़माया गया और `list_deliveries` बताता है कि नतीजा क्या रहा। पहले प्रयास तक nil, और इसलिए `create` पर हमेशा nil।
createdAtString- endpoint कब पंजीकृत हुआ, इसका ISO 8601 timestamp। `list` इसी फ़ील्ड के अनुसार सबसे नए endpoint पहले लौटाता है।
secretString- HMAC-SHA-256 कुंजी जो हर डिलीवरी के `X-OpenEmail-Signature` पर हस्ताक्षर करती है: `whsec_` के बाद 43 base64url वर्ण, और वही जो आप prefix समेत `OpenEmail.verify_webhook_signature` को पास करते हैं। इसे `create` और `rotate_secret` लौटाते हैं, और कोई नहीं। कोई read इसे कभी नहीं लौटाता, इसलिए इसे अभी सहेज लें। खोया हुआ secret सिर्फ़ `rotate_secret` से बदला जा सकता है, जो पुराने को तुरंत अमान्य कर देता है।
लॉग फ़िल्टर करना
failed = client.webhooks.list_workspace_deliveries(status: "failed", since: Time.now - 86_400)p failed.items.map { |delivery| [delivery[:endpointId], delivery[:eventType], delivery[:responseCode]] } history = client.webhooks.list_activity("whe_3f9c2a7b1e4d8f60a5c7b92d")p history.items.map { |change| [change[:type], change.dig(:actor, :label)] }list_deliveries एक endpoint पढ़ता है और list_workspace_deliveries हर endpoint, या वे जिनके नाम endpoint_ids: लेता है, और दोनों status:, since: और until: लेते हैं, यानी console के “डिलीवरी” टैब के फ़िल्टर। list_activity और list_workspace_activity audit लॉग पढ़ते हैं: किसने क्या बनाया, बदला, चालू या बंद किया, rotate किया, टेस्ट किया, replay किया या हटाया। हर एक के साथ एक list_all_ और एक iterate_ संस्करण है, और वर्कस्पेस लॉग की हर पंक्ति में endpointId होता है। webhooks.stats आपकी चुनी विंडो के लिए “Analytics” टैब के पीछे के आँकड़े लौटाता है।
since: और until: Time, DateTime या String के रूप में ISO 8601 क्षण लेते हैं, और Ruby Date का मतलब उस दिन की UTC आधी रात है। until Ruby का keyword है, पर यह किसी भी दूसरे keyword argument की तरह काम करता है: list_deliveries(id, since: start, until: finish)।