Skip to main content

rustyclaw_core/messengers/
discord.rs

1//! Discord messenger using bot token and REST API.
2
3use super::{Message, Messenger};
4use anyhow::Result;
5use async_trait::async_trait;
6
7/// Discord messenger using bot token
8pub struct DiscordMessenger {
9    name: String,
10    bot_token: String,
11    connected: bool,
12    http: reqwest::Client,
13}
14
15impl DiscordMessenger {
16    pub fn new(name: String, bot_token: String) -> Self {
17        Self {
18            name,
19            bot_token,
20            connected: false,
21            http: reqwest::Client::new(),
22        }
23    }
24}
25
26#[async_trait]
27impl Messenger for DiscordMessenger {
28    fn name(&self) -> &str {
29        &self.name
30    }
31
32    fn messenger_type(&self) -> &str {
33        "discord"
34    }
35
36    async fn initialize(&mut self) -> Result<()> {
37        // Verify bot token by fetching current user
38        let resp = self
39            .http
40            .get("https://discord.com/api/v10/users/@me")
41            .header("Authorization", format!("Bot {}", self.bot_token))
42            .send()
43            .await?;
44
45        if resp.status().is_success() {
46            self.connected = true;
47            Ok(())
48        } else {
49            anyhow::bail!("Discord auth failed: {}", resp.status())
50        }
51    }
52
53    async fn send_message(&self, channel_id: &str, content: &str) -> Result<String> {
54        let url = format!(
55            "https://discord.com/api/v10/channels/{}/messages",
56            channel_id
57        );
58
59        let resp = self
60            .http
61            .post(&url)
62            .header("Authorization", format!("Bot {}", self.bot_token))
63            .json(&serde_json::json!({ "content": content }))
64            .send()
65            .await?;
66
67        if resp.status().is_success() {
68            let data: serde_json::Value = resp.json().await?;
69            Ok(data["id"].as_str().unwrap_or("unknown").to_string())
70        } else {
71            anyhow::bail!("Discord send failed: {}", resp.status())
72        }
73    }
74
75    async fn receive_messages(&self) -> Result<Vec<Message>> {
76        // Real implementation would use Discord gateway WebSocket
77        Ok(Vec::new())
78    }
79
80    fn is_connected(&self) -> bool {
81        self.connected
82    }
83
84    async fn disconnect(&mut self) -> Result<()> {
85        self.connected = false;
86        Ok(())
87    }
88}