Znalostní báze
Webhooky
Oznámí vašemu endpointu, že dorazila pošta, místo aby vás nutil se dotazovat.
Podrobnosti
- Použitelné už dnes z Nastavení → Webhooky i přes API: zaregistrujte https endpoint, vyberte, které z dvaceti událostí chce, a zkopírujte podpisové tajemství whsec_, které se zobrazí při vytvoření a při rotaci a pak už nikdy. Doručení jsou skutečné podepsané POSTy vyvolané samotnou schránkou, ne nějakým voláním API, takže se spouštějí na příchozí poštu i na otevření a kliknutí bez ohledu na to, co zprávu odeslalo. Odeslání se spouští ze všech rozhraní, a dřív se spouštělo jen z některých: odeslání přes API, MCP, šablonu nebo pravidlo vyvolalo email.sent, zatímco zpráva odeslaná z okna pro psaní v aplikaci ne, protože to zapisuje do schránky přímo, a ne přes odesílací službu, která událost vydávala. Událost se nyní vyvolává u samotné schránky, což je místo, kde se všechna rozhraní potkávají, takže psaní v aplikaci, naplánování na úterý a odeslání POSTu do API jsou tři způsoby, jak způsobit tentýž webhook. Odložené odeslání to řekne dvakrát: email.scheduled nebo email.queued při přijetí, email.sent, když skutečně odejde, a email.cancelled, pokud si to mezitím vezmete zpět. Deset endpointů na schránku, vynucováno všude, kde se endpoint registruje, ne jen na této obrazovce.
- Události se dělí do tří rodin. Patnáct se týká jedné zprávy: email.received, email.replied, email.sent, email.delivered, email.failed, email.cancelled, email.scheduled, email.queued (sourozenec scheduled pro vrácení odeslání), email.delivery_delayed, email.bounced, email.complained, email.suppressed, email.opened, email.clicked a email.downloaded. email.sent znamená, že zprávu přijala odesílací služba, email.delivered, že ji přijal přijímající server, a email.delivery_delayed, že ještě nedorazila a pokusy pokračují. email.replied se spouští vedle email.received, když příchozí zpráva odpovídá na zprávu, která už ve schránce je, takže odběratel, který chce obě, dostane obě. email.downloaded se spouští, když si někdo stáhne soubor, který odešel jako odkaz ke stažení, přičemž tentýž klasifikátor drží skenery a náhledovače odkazů mimo počítání, a neuvádí žádného příjemce, protože odkaz je stejný pro všechny, komu zpráva šla. Tři se týkají domény: domain.verified, když začne přijímat, domain.sending_changed, když se posune její verdikt pro odesílání, a domain.deleted, když je odebrána, ať už jste o to požádali, nebo ji jako neověřenou shodil sedmidenní úklid. Dvě se týkají samotného seznamu potlačených adres, což je něco jiného než email.suppressed: suppression.added, když se adresa přidá, a suppression.removed, když je zase povolena. Neodebírat žádnou z nich znamená každou událost o zprávě kromě email.replied, dnes jich je čtrnáct, nikdy žádnou rodinu přidanou později, a API to čte zpět jako ["*"]. Pokud chcete být výslovní, události vyjmenujte. Každé doručení nese X-OpenEmail-Signature ve tvaru t=<unix>,v1=<hex>, HMAC-SHA-256 přes časové razítko, tečku a surové tělo, plus X-OpenEmail-Event a X-OpenEmail-Delivery. Ověřujte proti bajtům tak, jak dorazily: parsování a opětovná serializace přeskládají klíče a podpis rozbijí. Třísetsekundové okno pro opakované přehrání si vynucuje příjemce a ověřovač v SDK ho má jako výchozí.
- Registrace se odmítne pro cokoli, co není https nebo není veřejně směrovatelné (loopback, RFC1918, link-local, CGNAT a jejich ekvivalenty v IPv6), a přesměrování se nenásledují, takže 3xx se zaznamená jako neúspěšné doručení, místo aby se za ním šlo někam jinam. Příjemce dostane 5 sekund, endpointy se obsluhují paralelně, takže deset z nich stojí pořád 5 sekund a ne 50, a nedávné pokusy jsou vypsané na stránce daného endpointu i s kódem odpovědi a tím, jak dlouho trvaly.
- Doručení se zkouší až pětkrát. První odchází ve chvíli, kdy událost nastane; selhání, které by se věrohodně mohlo samo spravit, se opakuje po 1 minutě, pak po 5, po 25 a po 2 hodinách, což jednu událost roztáhne zhruba na dvě a půl hodiny. Opakované pokusy se drží jako trvalá práce, ne v paměti, takže nasazení uprostřed tohoto okna o ně nepřijde. Opakují se jen selhání, která stojí za zopakování: vypršení časového limitu, odmítnuté spojení, 408, 425, 429 nebo jakékoli 5xx. Jakékoli jiné 4xx je záměrné odmítnutí obsahu endpointem a zeptat se ještě čtyřikrát by znamenalo čtyřnásobnou zátěž pro tutéž odpověď. Id události se razí jednou a každý pokus ho nese v X-OpenEmail-Delivery, takže příjemce, který totéž id uvidí podruhé, může to druhé zahodit, místo aby podle něj jednal dvakrát. Poté, co u 100 událostí v řadě selžou všechny pokusy, se endpoint vypne, pracovnímu prostoru přijde e-mail a důvod je čitelný přímo na endpointu. Endpoint odpovídající 410 Gone se vypne okamžitě.
- Endpoint, který selže 100krát v řadě, se vypne, místo aby se na něj vytáčelo donekonečna, a všem s přístupem k webhookům o tom přijde e-mail: který to byl, co hlásil poslední pokus a že se během selhávání nic nefrontovalo. Počítají se selhání JDOUCÍ PO SOBĚ a jakýkoli doručený pokus počet vynuluje, takže jedno zlé odpoledne loni v březnu nemůže dnes sečíst vypnutý endpoint. Opětovné zapnutí počet zároveň vymaže. Konzole tyto dva stavy rozlišuje, místo aby ukazovala jeden přepínač: endpoint, který jste vypnuli vy, vypadá jinak než ten, který jsme vypnuli my.
- Správa endpointů je jedna práce se dvěma vchody. Přes API je to POST /webhooks, patch, delete, rotace tajemství, test a log doručení, s metodou pro každý z nich v SDK; v aplikaci je to Nastavení → Webhooky, proti témuž registru, ne proti druhému. Čtení je hlídané oprávněním webhooks:read, takže kdokoli, kdo staví integraci, vidí endpointy a jejich historii doručení (který se spustil, co odpověděl příjemce, jak dlouho to trvalo), aniž by byl vlastníkem. Registrace, úprava, test, rotace a smazání vyžadují webhooks:write A vlastnictví schránky, a to na obou rozhraních; ta druhá polovina je záměrná: endpoint nemá osu adres, takže přijímá každou adresu, kterou pracovní prostor drží, i s předměty a příjemci na ní, a žádné oprávnění neznamená „smí mu být posláno tohle všechno“. Role, která staví integrace a nečte poštu, to řídí místo toho klíčem pracovního prostoru.