modo/webhook/mod.rs
1//! Outbound webhook delivery following the
2//! [Standard Webhooks](https://www.standardwebhooks.com/) specification.
3//!
4//! This module provides signed outbound HTTP POST requests using HMAC-SHA256,
5//! plus verification helpers for incoming webhook requests.
6//!
7//! # Provides
8//!
9//! | Type | Purpose |
10//! |------|---------|
11//! | [`WebhookSender`] | Signs and delivers webhook payloads via HTTP POST. Clone-cheap (`Arc` inside). |
12//! | [`WebhookSecret`] | HMAC-SHA256 signing key. Serialized as `whsec_<base64>`. `Debug` output is redacted. |
13//! | [`WebhookResponse`] | HTTP status code and body bytes returned by the endpoint. |
14//! | [`SignedHeaders`] | The three Standard Webhooks request headers produced by [`sign_headers()`]. |
15//! | [`sign()`] | Compute a raw HMAC-SHA256 signature (base64-encoded). |
16//! | [`verify()`] | Verify a raw HMAC-SHA256 signature with constant-time comparison. |
17//! | [`sign_headers()`] | Build the three Standard Webhooks headers from id, timestamp, body, and secrets. |
18//! | [`verify_headers()`] | Verify incoming Standard Webhooks headers with replay-attack protection. |
19//!
20//! # Quick start
21//!
22//! ```
23//! use modo::webhook::{WebhookSender, WebhookSecret};
24//!
25//! # async fn example() -> modo::Result<()> {
26//! let sender = WebhookSender::default_client();
27//! let secret: WebhookSecret = "whsec_dGVzdC1rZXktYnl0ZXM=".parse()?;
28//!
29//! let response = sender.send(
30//! "https://example.com/webhooks",
31//! "msg_01HXYZ",
32//! b"{\"event\":\"user.created\"}",
33//! &[&secret],
34//! ).await?;
35//!
36//! println!("endpoint returned {}", response.status);
37//! # Ok(())
38//! # }
39//! ```
40
41mod client;
42mod secret;
43mod sender;
44mod signature;
45
46pub use client::WebhookResponse;
47pub use secret::WebhookSecret;
48pub use sender::WebhookSender;
49pub use signature::{SignedHeaders, sign, sign_headers, verify, verify_headers};