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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#[macro_use]
extern crate lazy_static;
mod error;
mod http;
use error::IftttWebhookError;
use http::HTTP_CLIENT;
use std::collections::HashMap;
use std::error::Error;
#[derive(Debug, Clone)]
pub struct IftttWebhook {
pub event: String,
pub key: String,
}
pub fn build_hook_url(key: &str, event: &str) -> String {
format!(
"https://maker.ifttt.com/trigger/{event}/with/key/{key}",
event = event,
key = key,
)
}
pub async fn trigger_webhook(key: &str, event: &str, body: Option<&HashMap<&str, &str>>) -> Result<(), impl Error> {
let req = if let Some(body) = body {
HTTP_CLIENT.post(&build_hook_url(key, event)).json(body)
} else {
HTTP_CLIENT.get(&build_hook_url(key, event))
};
let res = req.send().await?;
if res.status() != 200 {
Err(IftttWebhookError::new(format!(
"Invalid status {}.\n{:?}",
res.status(),
res
)))
} else {
Ok(())
}
}
impl IftttWebhook {
pub fn url(&self) -> String {
build_hook_url(&self.event,&self.key)
}
pub async fn trigger(&self, body: Option<&HashMap<&str, &str>>) -> Result<(), impl Error> {
trigger_webhook(&self.key, &self.event, body).await
}
}
#[cfg(test)]
mod tests {
use super::IftttWebhook;
use std::collections::HashMap;
use std::env;
lazy_static! {
pub static ref KEY: String = env::var("IFTTT_KEY").unwrap();
}
#[tokio::test]
async fn test_post() {
let mut values = HashMap::new();
values.insert("value1", "value_1_test_value");
values.insert("value2", "value_2_test_value");
values.insert("value3", "value_3_test_value");
let webhook = IftttWebhook {
key: KEY.clone(),
event: "test".into(),
};
let result = webhook.trigger(Some(&values)).await;
assert_eq!(result.is_ok(), true);
}
#[tokio::test]
async fn test_get() {
let webhook = IftttWebhook {
key: KEY.clone(),
event: "test".into(),
};
let result = webhook.trigger(None).await;
assert_eq!(result.is_ok(), true);
}
#[tokio::test]
async fn test_post_error_unauthorized() {
let mut values = HashMap::new();
values.insert("value1", "value_1_test_value");
values.insert("value2", "value_2_test_value");
values.insert("value3", "value_3_test_value");
let webhook = IftttWebhook {
key: "wrong_key".into(),
event: "test".into(),
};
let result = webhook.trigger(Some(&values)).await;
assert_eq!(result.is_err(), true);
}
#[tokio::test]
async fn test_get_error_unauthorized() {
let webhook = IftttWebhook {
key: "wrong_key".into(),
event: "test".into(),
};
let result = webhook.trigger(None).await;
assert_eq!(result.is_err(), true);
}
}