rustyclaw_core/messengers/
mod.rs1use anyhow::Result;
7use async_trait::async_trait;
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Message {
15 pub id: String,
16 pub sender: String,
17 pub content: String,
18 pub timestamp: i64,
19 #[serde(default)]
20 pub channel: Option<String>,
21 #[serde(default)]
22 pub reply_to: Option<String>,
23 #[serde(default)]
24 pub media: Option<Vec<MediaAttachment>>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct MediaAttachment {
30 pub url: Option<String>,
31 pub path: Option<String>,
32 pub mime_type: Option<String>,
33 pub filename: Option<String>,
34}
35
36#[derive(Debug, Default)]
38pub struct SendOptions<'a> {
39 pub recipient: &'a str,
40 pub content: &'a str,
41 pub reply_to: Option<&'a str>,
42 pub silent: bool,
43 pub media: Option<&'a str>,
44}
45
46#[async_trait]
50pub trait Messenger: Send + Sync {
51 fn name(&self) -> &str;
53
54 fn messenger_type(&self) -> &str;
56
57 async fn initialize(&mut self) -> Result<()>;
59
60 async fn send_message(&self, recipient: &str, content: &str) -> Result<String>;
62
63 async fn send_message_with_options(&self, opts: SendOptions<'_>) -> Result<String> {
65 self.send_message(opts.recipient, opts.content).await
67 }
68
69 async fn receive_messages(&self) -> Result<Vec<Message>>;
71
72 fn is_connected(&self) -> bool;
74
75 async fn disconnect(&mut self) -> Result<()>;
77}
78
79pub struct MessengerManager {
83 messengers: Vec<Box<dyn Messenger>>,
84}
85
86impl MessengerManager {
87 pub fn new() -> Self {
88 Self {
89 messengers: Vec::new(),
90 }
91 }
92
93 pub fn add_messenger(&mut self, messenger: Box<dyn Messenger>) {
95 self.messengers.push(messenger);
96 }
97
98 pub async fn initialize_all(&mut self) -> Result<()> {
100 for messenger in &mut self.messengers {
101 messenger.initialize().await?;
102 }
103 Ok(())
104 }
105
106 pub fn get_messengers(&self) -> &[Box<dyn Messenger>] {
108 &self.messengers
109 }
110
111 pub fn get_messenger(&self, name: &str) -> Option<&dyn Messenger> {
113 self.messengers
114 .iter()
115 .find(|m| m.name() == name)
116 .map(|b| &**b)
117 }
118
119 pub fn get_messenger_by_type(&self, msg_type: &str) -> Option<&dyn Messenger> {
121 self.messengers
122 .iter()
123 .find(|m| m.messenger_type() == msg_type)
124 .map(|b| &**b)
125 }
126
127 pub async fn disconnect_all(&mut self) -> Result<()> {
129 for messenger in &mut self.messengers {
130 messenger.disconnect().await?;
131 }
132 Ok(())
133 }
134}
135
136impl Default for MessengerManager {
137 fn default() -> Self {
138 Self::new()
139 }
140}
141
142mod webhook;
145mod console;
146mod discord;
147mod telegram;
148
149pub use webhook::WebhookMessenger;
150pub use console::ConsoleMessenger;
151pub use discord::DiscordMessenger;
152pub use telegram::TelegramMessenger;
153
154#[cfg(feature = "matrix")]
157mod matrix;
158#[cfg(feature = "matrix")]
159pub use matrix::MatrixMessenger;
160
161#[cfg(feature = "signal")]
162mod signal;
163#[cfg(feature = "signal")]
164pub use signal::SignalMessenger;