autopulse_service/settings/webhooks/
mod.rs1pub mod discord;
26
27pub mod hookshot;
43
44pub mod json;
60
61#[doc(hidden)]
62pub mod manager;
63
64#[doc(hidden)]
65pub mod transport;
66
67#[doc(hidden)]
68pub use manager::*;
69
70use discord::DiscordWebhook;
71use hookshot::HookshotWebhook;
72use json::JsonWebhook;
73use serde::{Deserialize, Serialize};
74
75#[derive(Serialize, Deserialize, Clone)]
76#[serde(tag = "type", rename_all = "lowercase")]
77pub enum Webhook {
78 Discord(DiscordWebhook),
79 Hookshot(HookshotWebhook),
80 Json(JsonWebhook),
81}
82
83impl Webhook {
84 pub async fn send(
85 &self,
86 batch: &WebhookBatch,
87 retries: u8,
88 timeout_secs: u64,
89 ) -> anyhow::Result<()> {
90 if batch.is_empty() {
91 return Ok(());
92 }
93
94 match self {
95 Self::Discord(d) => d.send(batch, retries, timeout_secs).await,
96 Self::Hookshot(h) => h.send(batch, retries, timeout_secs).await,
97 Self::Json(j) => j.send(batch, retries, timeout_secs).await,
98 }
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::{hookshot::HookshotWebhook, json::JsonWebhook, Webhook};
105
106 #[test]
107 fn deserializes_hookshot_webhook_config() {
108 let webhook = serde_json::from_value::<Webhook>(serde_json::json!({
109 "type": "hookshot",
110 "url": "https://example.com/webhooks/hookshot"
111 }));
112
113 assert!(webhook.is_ok(), "expected hookshot webhook to deserialize");
114 }
115
116 #[test]
117 fn deserializes_json_webhook_config() {
118 let webhook = serde_json::from_value::<Webhook>(serde_json::json!({
119 "type": "json",
120 "url": "https://example.com/webhooks/json"
121 }));
122
123 assert!(webhook.is_ok(), "expected json webhook to deserialize");
124 }
125
126 #[tokio::test]
127 async fn skips_sending_empty_batches() {
128 let hookshot = Webhook::Hookshot(HookshotWebhook {
129 url: "http://127.0.0.1:9/hookshot".to_string(),
130 username: None,
131 });
132 let json = Webhook::Json(JsonWebhook {
133 url: "http://127.0.0.1:9/json".to_string(),
134 });
135
136 hookshot.send(&Vec::new(), 3, 10).await.unwrap();
137 json.send(&Vec::new(), 3, 10).await.unwrap();
138 }
139}