Endpunkte
`webhooks.list`, `list_all`, `iterate`, `get`, `create`, `update`, `delete`, `rotate_secret`, `test`, `get_delivery` und `replay_delivery` sowie die Zustell- und Aktivitätsprotokolle.
Jede Methode
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])create ist, abgesehen von rotate_secret, der EINZIGE Zeitpunkt, an dem das Secret zurückgegeben wird. Ein Lesevorgang gibt es nie wieder aus, speichern Sie es daher, bevor Sie irgendetwas anderes tun. Ohne eventTypes gilt die Standardauswahl, jedes email.*-Event außer email.replied. email.replied, domain.*, suppression.*, file.* und form.* erreichen einen Endpunkt nur, wenn er sie benennt.
rotate_secret hat kein Überlappungsfenster. Das alte Secret funktioniert sofort nicht mehr, rollen Sie das neue daher vor der Rotation aus. Der Aufruf wird nie automatisch wiederholt: Eine Wiederholung würde ein zweites Mal rotieren und das Secret ungültig machen, das der erste Versuch zurückgegeben hat.
Auch create wird nicht wiederholt, ein Netzwerkfehler kann also einen angelegten Endpunkt mit einem Secret hinterlassen, das Sie nie gesehen haben. Prüfen Sie list, bevor Sie ihn erneut anlegen. Ein Workspace hat standardmäßig Platz für 10 Endpunkte, und der nächste über dem Limit ergibt einen 422 workspace_limit_reached.
Was abonniert werden kann
OpenEmail::WEBHOOK_EVENTS ist ein eingefrorener Hash aller Event-Namen, sodass sich die Liste ohne Anfrage rendern lässt, und webhooks.list_events gibt dieselben Namen mit je einem Satz zurück, dazu die Limits, an die ein Endpunkt gebunden ist. Events sind Events des **Postfachs**, nicht dieser API: email.received feuert für Mail, die in der App eingeht, und email.sent feuert für eine Nachricht, die der Composer gesendet hat. Ein Abonnement ist nicht dasselbe wie das Beobachten des eigenen API-Verkehrs.
file.uploaded feuert, wenn eine Datei auf der Seite „Dateien“ abgelegt wird, und file.deleted, wenn eine gelöscht wird. Ihr data enthält fileId, filename, mimeType, sizeBytes, direction, to, threadId, messageId und uploadedAt oder deletedAt. to ist die Adresse, zu der die Datei gehört, oder nil bei einer Datei, die zum ganzen Workspace gehört.
Die Datei-Events sind nicht in der Standardauswahl, ein Endpunkt erhält sie also nur, wenn er sie in eventTypes benennt. Ein auf bestimmte Adressen beschränkter Endpunkt erfährt nur von den Dateien dieser Adressen, ein Upload für den ganzen Workspace, mit to nil, wird ihm also nicht gesendet.
form.submitted feuert, wenn sich jemand über eines Ihrer Formulare anmeldet, und form.confirmed, wenn eine ausstehende Anmeldung den Audiences beitritt, weil die Person den Bestätigungslink geöffnet hat oder weil Sie sie freigegeben haben. Das data von form.submitted enthält formId, formName, submissionId, email, status, answers, audienceIds, sourceUrl und submittedAt. Das data von form.confirmed enthält formId, formName, submissionId, email, audienceIds, via, das link oder approval ist, und confirmedAt.
Eine Anmeldung bei einem Formular ohne Double-Opt-in sendet form.submitted mit status added und kein form.confirmed; behandeln Sie diese Kombination also als den Moment, in dem jemand beitritt. Wer sich vor der Bestätigung erneut anmeldet, behält dieselbe submissionId, und form.submitted wird nur dann erneut gesendet, wenn sich die Antworten geändert haben. Die Formular-Events sind nicht in der Standardauswahl, und ein auf bestimmte Adressen beschränkter Endpunkt erhält sie nie, weil Anmeldungen dem ganzen Workspace gehören.
Nachweisen, dass es funktioniert
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 sendet ein signiertes synthetisches email.sent-Event per POST und wartet, bis der Versuch abgeschlossen ist. Es kehrt normal zurück, egal was Ihr Empfänger geantwortet hat. Verzweigen Sie also über delivery[:status] und nicht darüber, ob der Aufruf einen Fehler ausgelöst hat. Ein 4xx ist eine nützliche Antwort: Die URL ist erreichbar, und die Ablehnung kam von Ihrem eigenen Handler, oft von seiner Signaturprüfung.
Ein responseCode von nil bedeutet, dass es überhaupt keine Antwort gab (DNS, TLS, ein Timeout), was etwas anderes ist als eine Antwort, die 0 lautete. Jede Zeile führt attempt und maxAttempts mit, sodass mehrere Zeilen ein Event beschreiben können: Die gleiche eventId über sie hinweg ist das Event, und die Versuchsnummer ist der Versuch. nextAttemptAt sagt, wann die automatische Wiederholung nach einer Zeile fällig ist.
Erneut senden
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)Eine Zustellung, die immer wieder fehlschlägt, wird bis zu 8-mal versucht: sofort, dann nach 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden, 5 Stunden, 10 Stunden und 10 Stunden, insgesamt etwa 27,5 Stunden. Wiederholt wird nur ein Fehlschlag, der eine Wiederholung wert ist: keine Antwort, 408, 425, 429 oder ein 5xx. Ein Replay sendet das gespeicherte Event erneut mit derselben id, demselben type, demselben createdAt und denselben data, sodass ein Empfänger, der bereits verarbeitete ids verwirft, es als das Event behandelt, das er schon kennt. Nur die Signatur ist neu.
replay_deliverysendet ein Event sofort und gibt zurück, was Ihr Server geantwortet hat. Es funktioniert auch bei einem zugestellten Versuch und wird nie wiederholt. Bevor es sendet, werden die automatischen Wiederholungen dieses Events angehalten, die noch nicht begonnen haben: Sie bleiben abgebrochen, wenn das Replay zugestellt wird, und laufen nach Plan weiter, wenn es fehlschlägt.- Wird in diesem Moment eine automatische Wiederholung desselben Events gesendet, sendet
replay_deliverynichts und löst einen 409retry_in_progressaus, und solange ein anderes Replay davon noch gesendet wird, löst es einen 409replay_in_progressaus. So bekommt Ihr Empfänger nie zwei Kopien gleichzeitig, auch nicht von zwei im selben Augenblick gesendeten Replays. Warten Sie ein paar Sekunden und lesen Sieget_delivery, denn diese Wiederholung oder dieses Replay stellt es womöglich zu. Ein Replay betrifft immer genau ein Event: Kein Aufruf sendet jede fehlgeschlagene Zustellung erneut. - Außerdem löst es einen 409 aus bei einem ausgeschalteten Endpunkt (
webhook_disabled), einem Event, auf das der Endpunkt nicht mehr hört (event_not_subscribed) oder das er nicht mehr abdeckt (event_out_of_scope), und einem Versuch ohne gespeichertes Event (delivery_not_replayable).get_deliverymeldet diese Antwort vorab alsreplayRefusal.
Das Gem wiederholt replay_delivery nie von sich aus, weil eine Wiederholung nach einer verlorenen Antwort das Event noch einmal senden würde.
Parameter: webhooks.create
urlStringerforderlich- Wohin Zustellungen per POST gehen. Nur HTTPS, und der Host darf nicht `localhost`, ein `.localhost`-, `.local`- oder `.internal`-Name oder ein Loopback-, privates, CGNAT- oder Link-Local-IP-Literal sein. Dies ist eine serverseitige Anfrage an eine von Ihnen angegebene Adresse, daher ergeben diese einen 422 `invalid_webhook_url` auf `url`. Die Prüfung liest den Hostnamen so, wie er geschrieben steht, und jede Zustellung löst den Host erneut auf und weigert sich, an eine Adresse in einem dieser Bereiche zu senden. Zustellungen folgen nie Weiterleitungen, registrieren Sie daher die endgültige Adresse. Gespeichert wird die Serialisierung dessen, was Sie gesendet haben, durch den URL-Parser, `https://acme.com` wird also als `https://acme.com/` zurückgelesen.
eventTypesArray<String>- Welche Events diesen Endpunkt erreichen: beliebige der Werte aus `OpenEmail::WEBHOOK_EVENTS`. `create` begrenzt das Array auf die Anzahl der existierenden Events, eines mehr ergibt also einen 422 auf `eventTypes`, und `update` begrenzt es nicht. Begrenzt wird nur die Länge, und ein wiederholter Name wird genau so gespeichert und zurückgelesen, wie Sie ihn gesendet haben. Weggelassen oder leer wird es als leere Liste gespeichert, weshalb es als `["*"]` zurückgelesen wird, und es bedeutet jedes `email.*`-Event außer `email.replied`, heute vierzehn, und nie die Familien für Domains, Sperrliste, Dateien oder Formulare. Eine später hinzugefügte Familie erreicht nie einen Endpunkt, der sie nicht benannt hat, sodass eine Integration nicht wegen eines Releases eine Form empfängt, die sie nie gesehen hat.
descriptionString- Eine Bezeichnung für den Endpunkt, höchstens 200 Zeichen, damit sich eine Liste von Webhooks als Namen liest und nicht als Spalte von URLs. Ohne Angabe wird sie als nil gespeichert und zurückgegeben.
addressAllowlistArray<String>- Einzelne Adressen, von denen dieser Endpunkt erfährt. Ein Event wird zugestellt, wenn die betroffene Adresse auf dieser Liste steht oder ihre Domain in `domainAllowlist`. Lassen Sie beide leer, erfährt der Endpunkt von jeder Adresse, die dem Workspace gehört. Höchstens 50, und eine Adresse, die diesem Workspace nicht gehört, ergibt einen 422 `invalid_parameter`.
domainAllowlistArray<String>- Ganze Domains, von denen dieser Endpunkt erfährt, einschließlich später hinzugefügter Adressen. Eine Domain bringt auch ihre eigenen `domain.*`-Events mit. Höchstens 25.
api_keyString- Legt den Endpunkt mit diesem Schlüssel statt mit dem des Clients an.
Antwort: der angelegte Endpunkt
Ein Hash mit Symbol-Schlüsseln. get, list und update geben dieselbe Form ohne secret zurück.
objectString- Immer `webhook`, derselbe Diskriminator, den ein einfaches Lesen zurückgibt, denn das Secret ist ein zusätzlicher Schlüssel auf der gewöhnlichen Form und kein eigener Objekttyp. Ob `secret` vorhanden ist, entscheidet die aufgerufene Methode und nicht dieses Feld.
idString- Der Bezeichner des Endpunkts: `whe_` gefolgt von 24 Hex-Zeichen. Jeder andere Webhook-Aufruf nimmt ihn entgegen: `get`, `update`, `delete`, `rotate_secret`, `test`, `list_deliveries`, `list_all_deliveries`, `iterate_deliveries`, `get_delivery` und `replay_delivery`.
urlString- Der Endpunkt, wie er gespeichert ist, nachdem er die Prüfungen auf HTTPS und gesperrte Hosts bestanden hat. Es ist die geparste URL, erneut serialisiert. Vergleichen Sie daher mit diesem Wert und nicht mit dem String, den Sie gesendet haben.
descriptionString or nil- Die vergebene Bezeichnung oder nil, wenn keine vergeben wurde. Ein `update`, das `description: nil` sendet, löscht sie.
eventTypesArray<String>- Die abonnierten Events oder `["*"]`, wenn der Endpunkt keine benannt hat. `["*"]` ist die Darstellung einer leer gespeicherten Liste beim Lesen und kann nicht zurückgesendet werden, und es steht für die vierzehn Nachrichten-Events und nicht für den gesamten Katalog. `create` und `update` akzeptieren ausschließlich die wörtlichen Event-Namen.
enabledBoolean- Ob Zustellungen versucht werden. Ein deaktivierter Endpunkt wird beim Verteilen von Events übersprungen und behält sein Secret und seine Zustellhistorie. Hier immer true, da nur `update` `enabled` nimmt.
disabledAtString or nil- Wann der Server den Endpunkt nach 100 fehlgeschlagenen Zustellungen in Folge abgeschaltet hat. nil, solange er an ist, und wenn Sie ihn selbst abgeschaltet haben.
disabledReasonString or nil- Warum der Server ihn abgeschaltet hat. nil, wann immer `disabledAt` nil ist.
consecutiveFailuresInteger- Fehlgeschlagene Zustellungen in Folge. Jedes zugestellte Event setzt den Wert auf 0 zurück, ebenso `update` mit `enabled: true`.
addressAllowlistArray<String>- Die einzelnen Adressen, von denen dieser Endpunkt erfährt.
domainAllowlistArray<String>- Die ganzen Domains, von denen dieser Endpunkt erfährt. Sind beide Listen leer, bedeutet das jede Adresse, die dem Workspace gehört.
lastDeliveryAtString or nil- Zeitstempel nach ISO 8601 des letzten Zustell-VERSUCHS, nicht des letzten Erfolgs. Er wird auch nach einem fehlgeschlagenen POST gesetzt und sagt damit, dass der Endpunkt versucht wurde, und `list_deliveries` sagt, wie es ausging. nil bis zum ersten Versuch und daher bei `create` immer nil.
createdAtString- ISO 8601-Zeitstempel der Registrierung des Endpunkts. `list` gibt Endpunkte nach diesem Feld sortiert zurück, neueste zuerst.
secretString- Der HMAC-SHA-256-Schlüssel, der die `X-OpenEmail-Signature` jeder Zustellung signiert: `whsec_` gefolgt von 43 base64url-Zeichen, und das, was Sie an `OpenEmail.verify_webhook_signature` übergeben, Präfix eingeschlossen. Wird von `create` und `rotate_secret` zurückgegeben und von nichts sonst. Ein Lesevorgang gibt ihn nie wieder aus, speichern Sie ihn also jetzt. Ein verlorenes Secret lässt sich nur mit `rotate_secret` ersetzen, das das alte sofort ungültig macht.
Die Protokolle filtern
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 liest einen Endpunkt und list_workspace_deliveries jeden Endpunkt oder die, die endpoint_ids: nennt, und beide nehmen status:, since: und until:, die Filter des Tabs Zustellungen in der Konsole. list_activity und list_workspace_activity lesen das Audit-Protokoll: wer was angelegt, geändert, geschaltet, rotiert, getestet, erneut gesendet oder entfernt hat. Jede hat eine Version mit list_all_ und eine mit iterate_ daneben, und jede Zeile des Workspace-Protokolls trägt endpointId. webhooks.stats gibt die Zahlen hinter dem Tab Analysen für ein Fenster Ihrer Wahl zurück.
since: und until: nehmen ein Time, ein DateTime oder einen Zeitpunkt nach ISO 8601 als String, und ein Ruby-Date bedeutet Mitternacht UTC an diesem Tag. until ist ein Ruby-Schlüsselwort, funktioniert aber wie jedes andere als Keyword-Argument: list_deliveries(id, since: start, until: finish).