pretix_webhook/lib.rs
1//! Framework-independent Tower service for receiving pretix webhooks.
2//!
3//! [`WebhookServiceBuilder`] configures authentication, organizer and event
4//! filters, and a request body limit. [`build`](WebhookServiceBuilder::build)
5//! wraps a [`WebhookHandler`]. Functions and closures that accept a
6//! [`WebhookEvent`](pretix_webhook_events::WebhookEvent) and return a `Send`
7//! future implement that trait automatically:
8//!
9//! ```
10//! use std::convert::Infallible;
11//!
12//! use pretix_webhook::WebhookServiceBuilder;
13//! use pretix_webhook_events::WebhookEvent;
14//!
15//! let handler = |event: WebhookEvent| async move {
16//! println!("{}: {}", event.notification_id(), event.action());
17//! Ok::<_, Infallible>(())
18//! };
19//! let service = WebhookServiceBuilder::new()
20//! .allow_organizer("acmecorp")?
21//! .allow_event("democon")?
22//! .build(handler);
23//! # let _ = service;
24//! # Ok::<(), Box<dyn std::error::Error>>(())
25//! ```
26//!
27//! The resulting [`WebhookService`] implements
28//! `tower::Service<http::Request<B>>` for request bodies whose data is
29//! [`bytes::Bytes`]. It returns ordinary [`http::Response`] values and does not
30//! depend on Axum or a runtime. Callers own URL and HTTP method routing; for
31//! example, an Axum application can mount it with `post_service`:
32//!
33//! ```
34//! use std::convert::Infallible;
35//!
36//! use axum::{Router, routing::post_service};
37//! use pretix_webhook::WebhookServiceBuilder;
38//! use pretix_webhook_events::WebhookEvent;
39//!
40//! let service = WebhookServiceBuilder::new()
41//! .build(|_event: WebhookEvent| async { Ok::<_, Infallible>(()) });
42//! let app = Router::<()>::new().route("/webhook", post_service(service));
43//! # let _: Router = app;
44//! ```
45//!
46//! Authentication is checked before JSON parsing. Organizer and event filters
47//! are independent and exact. Organizer-level payloads consult only the
48//! organizer filter; an event-level payload with an unreadable event slug fails
49//! a configured event filter.
50//!
51//! The service returns `204` on success, `400` for malformed payloads, `401`
52//! for failed authentication, `404` for filtered events, `413` when the request
53//! exceeds the configured body limit, and `500` when the handler returns an
54//! error. Routing failures and unsupported methods are handled by the caller's
55//! router.
56//!
57//! # Feature flags
58//!
59//! The default feature set is empty. The `tracing` feature opens a
60//! `pretix_webhook` span containing the request URI path and, after parsing,
61//! the event identity. Records emitted by the handler inherit that span.
62
63mod builder;
64mod handler;
65mod service;
66
67pub use builder::{BasicAuthCredential, WebhookFilterError, WebhookServiceBuilder};
68pub use handler::WebhookHandler;
69pub use service::{DEFAULT_BODY_LIMIT, WebhookResponse, WebhookService};