1#[macro_use]
2extern crate lazy_static;
3
4mod error;
5mod http;
6
7use error::IftttWebhookError;
8use http::HTTP_CLIENT;
9
10use std::collections::HashMap;
11use std::error::Error;
12
13#[derive(Debug, Clone)]
14pub struct IftttWebhook {
15 pub event: String,
16 pub key: String,
17}
18
19pub fn build_hook_url(key: &str, event: &str) -> String {
20 format!(
21 "https://maker.ifttt.com/trigger/{event}/with/key/{key}",
22 event = event,
23 key = key,
24 )
25}
26
27pub async fn trigger_webhook(key: &str, event: &str, body: Option<&HashMap<&str, &str>>) -> Result<(), impl Error> {
28 let req = if let Some(body) = body {
29 HTTP_CLIENT.post(&build_hook_url(key, event)).json(body)
30 } else {
31 HTTP_CLIENT.get(&build_hook_url(key, event))
32 };
33 let res = req.send().await?;
34 if res.status() != 200 {
35 Err(IftttWebhookError::new(format!(
36 "Invalid status {}.\n{:?}",
37 res.status(),
38 res
39 )))
40 } else {
41 Ok(())
42 }
43}
44
45impl IftttWebhook {
46 pub fn url(&self) -> String {
47 build_hook_url(&self.event,&self.key)
48 }
49
50 pub async fn trigger(&self, body: Option<&HashMap<&str, &str>>) -> Result<(), impl Error> {
51 trigger_webhook(&self.key, &self.event, body).await
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::IftttWebhook;
58 use std::collections::HashMap;
59 use std::env;
60
61 lazy_static! {
62 pub static ref KEY: String = env::var("IFTTT_KEY").unwrap();
64 }
65
66 #[tokio::test]
67 async fn test_post() {
68 let mut values = HashMap::new();
70 values.insert("value1", "value_1_test_value");
71 values.insert("value2", "value_2_test_value");
72 values.insert("value3", "value_3_test_value");
73 let webhook = IftttWebhook {
74 key: KEY.clone(),
75 event: "test".into(),
76 };
77 let result = webhook.trigger(Some(&values)).await;
78 assert_eq!(result.is_ok(), true);
79 }
80
81 #[tokio::test]
82 async fn test_get() {
83 let webhook = IftttWebhook {
85 key: KEY.clone(),
86 event: "test".into(),
87 };
88 let result = webhook.trigger(None).await;
89 assert_eq!(result.is_ok(), true);
90 }
91
92 #[tokio::test]
93 async fn test_post_error_unauthorized() {
94 let mut values = HashMap::new();
96 values.insert("value1", "value_1_test_value");
97 values.insert("value2", "value_2_test_value");
98 values.insert("value3", "value_3_test_value");
99 let webhook = IftttWebhook {
100 key: "wrong_key".into(),
101 event: "test".into(),
102 };
103 let result = webhook.trigger(Some(&values)).await;
104 assert_eq!(result.is_err(), true);
105 }
106
107 #[tokio::test]
108 async fn test_get_error_unauthorized() {
109 let webhook = IftttWebhook {
111 key: "wrong_key".into(),
112 event: "test".into(),
113 };
114 let result = webhook.trigger(None).await;
115 assert_eq!(result.is_err(), true);
116 }
117}