Skip to main content

chipa_webhooks/platform/
slack.rs

1use serde_json::{Map, Value, json};
2
3use super::Platform;
4
5pub struct Slack {
6    webhook_url: String,
7    username: Option<String>,
8    icon_emoji: Option<String>,
9}
10
11impl Slack {
12    pub fn new(webhook_url: impl Into<String>) -> Self {
13        Self {
14            webhook_url: webhook_url.into(),
15            username: None,
16            icon_emoji: None,
17        }
18    }
19
20    pub fn with_username(mut self, username: impl Into<String>) -> Self {
21        self.username = Some(username.into());
22        self
23    }
24
25    pub fn with_icon_emoji(mut self, emoji: impl Into<String>) -> Self {
26        self.icon_emoji = Some(emoji.into());
27        self
28    }
29}
30
31impl Platform for Slack {
32    fn build_payload(&self, rendered: &str, hints: &Map<String, Value>) -> Value {
33        let mut payload = json!({ "text": rendered });
34
35        let username = hints
36            .get("__slack_username")
37            .and_then(Value::as_str)
38            .map(str::to_owned)
39            .or_else(|| self.username.clone());
40
41        if let Some(u) = username {
42            payload["username"] = Value::String(u);
43        }
44
45        let icon = hints
46            .get("__slack_emoji")
47            .and_then(Value::as_str)
48            .map(str::to_owned)
49            .or_else(|| self.icon_emoji.clone());
50
51        if let Some(i) = icon {
52            payload["icon_emoji"] = Value::String(i);
53        }
54
55        payload
56    }
57
58    fn endpoint(&self) -> &str {
59        &self.webhook_url
60    }
61}