rustyclaw_core/messengers/
webhook.rs1use super::{Message, Messenger, SendOptions};
4use anyhow::Result;
5use async_trait::async_trait;
6use serde::Serialize;
7
8pub struct WebhookMessenger {
10 name: String,
11 webhook_url: String,
12 connected: bool,
13 http: reqwest::Client,
14}
15
16impl WebhookMessenger {
17 pub fn new(name: String, webhook_url: String) -> Self {
18 Self {
19 name,
20 webhook_url,
21 connected: false,
22 http: reqwest::Client::new(),
23 }
24 }
25}
26
27#[derive(Serialize)]
28struct WebhookPayload<'a> {
29 content: &'a str,
30 recipient: &'a str,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 reply_to: Option<&'a str>,
33}
34
35#[async_trait]
36impl Messenger for WebhookMessenger {
37 fn name(&self) -> &str {
38 &self.name
39 }
40
41 fn messenger_type(&self) -> &str {
42 "webhook"
43 }
44
45 async fn initialize(&mut self) -> Result<()> {
46 self.connected = true;
47 Ok(())
48 }
49
50 async fn send_message(&self, recipient: &str, content: &str) -> Result<String> {
51 let payload = WebhookPayload {
52 content,
53 recipient,
54 reply_to: None,
55 };
56
57 let resp = self
58 .http
59 .post(&self.webhook_url)
60 .json(&payload)
61 .send()
62 .await?;
63
64 if resp.status().is_success() {
65 Ok(format!("webhook-{}", chrono::Utc::now().timestamp_millis()))
66 } else {
67 anyhow::bail!("Webhook returned {}", resp.status())
68 }
69 }
70
71 async fn send_message_with_options(&self, opts: SendOptions<'_>) -> Result<String> {
72 let payload = WebhookPayload {
73 content: opts.content,
74 recipient: opts.recipient,
75 reply_to: opts.reply_to,
76 };
77
78 let resp = self
79 .http
80 .post(&self.webhook_url)
81 .json(&payload)
82 .send()
83 .await?;
84
85 if resp.status().is_success() {
86 Ok(format!("webhook-{}", chrono::Utc::now().timestamp_millis()))
87 } else {
88 anyhow::bail!("Webhook returned {}", resp.status())
89 }
90 }
91
92 async fn receive_messages(&self) -> Result<Vec<Message>> {
93 Ok(Vec::new())
95 }
96
97 fn is_connected(&self) -> bool {
98 self.connected
99 }
100
101 async fn disconnect(&mut self) -> Result<()> {
102 self.connected = false;
103 Ok(())
104 }
105}