1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! The official Rust client for [Honk](https://honk-me.app): send events from your apps, jobs,
//! scripts and CI to your phone, as calm, grouped push notifications.
//!
//! - Async-first on Tokio and `reqwest` with rustls (no OpenSSL); a synchronous
//! `blocking::Honk` with the feature `blocking`.
//! - Every send carries an `Idempotency-Key` (yours, or a UUIDv7) that is reused on every
//! retry, so a retry never creates a duplicate.
//! - Retries only network errors, timeouts, 429 and 5xx, with exponential backoff and full
//! jitter, never sooner than `Retry-After`, all under a total deadline (30 s). Redirects are
//! reported, never followed.
//! - Local validation of everything cheap (lengths, URLs, actions, metadata, the 16 KiB body),
//! with every invalid field reported at once. [`HonkBuilder::validate`]`(false)` leaves it to
//! the server.
//!
//! Keep the ingestion key (`honk_…`) on the server: never ship it inside a client app.
//!
//! # Quick start
//!
//! ```no_run
//! use honk_me::{Honk, Message, Severity};
//!
//! #[tokio::main]
//! async fn main() -> honk_me::Result<()> {
//! let honk = Honk::from_env()?; // HONK_URL, HONK_KEY
//!
//! // The Honk scale: light, beep, loud, long, blast.
//! honk.beep("Backup finished", "nightly pg_dump took 42 s").await?;
//!
//! // Every field, and your own idempotency key.
//! let msg = Message::new("Ana asked for a quote: 3 rooms, 2 bathrooms")
//! .title("New quote request")
//! .severity(Severity::LOUD)
//! .group_key("requests/4812")
//! .url("https://shop.example.com/admin/requests/4812")
//! .metadata("rooms", 3);
//! let accepted = honk.send(&msg, "request-4812").await?;
//! println!("stored as {}", accepted.id);
//!
//! // Incidents: a problem opens one for its group, a recovery closes it.
//! honk.problem("db/backup", "Backup failed", "pg_dump exited with 1").await?;
//! honk.recovery("db/backup", "Backup OK", "pg_dump finished").await?;
//! Ok(())
//! }
//! ```
//!
//! # Errors
//!
//! Every failure is an [`Error`]: `Validation` (fix the message), `Auth`, `Quota`, `Conflict`,
//! `Network`, `Timeout`, `Server` or `Http`, each with a [`Failure`] holding the details.
//! [`Error::is_retryable`] tells whether sending again later (with the same idempotency key)
//! may succeed.
//!
//! # Features
//!
//! - `blocking`: `blocking::Honk`, a synchronous client on a private Tokio runtime.
pub use ;
pub use ;
pub use ;
pub use new_idempotency_key;
pub use ;