titanium_http/
channel.rs

1use crate::error::HttpError;
2use crate::HttpClient;
3use serde::Serialize;
4use titanium_model::{Channel, CreateMessage, Message, Snowflake, Webhook};
5
6impl HttpClient {
7    // =========================================================================
8    // Channel Operations
9    // =========================================================================
10
11    /// Get a channel.
12    pub async fn get_channel(&self, channel_id: Snowflake) -> Result<Channel<'static>, HttpError> {
13        let route = format!("/channels/{}", channel_id);
14        self.get(&route).await
15    }
16
17    /// Delete/Close a channel.
18    pub async fn delete_channel(
19        &self,
20        channel_id: Snowflake,
21        reason: Option<&str>,
22    ) -> Result<Channel<'static>, HttpError> {
23        let route = format!("/channels/{}", channel_id);
24
25        let headers = reason
26            .map(|r| -> Result<_, HttpError> {
27                let mut h = reqwest::header::HeaderMap::new();
28                h.insert(
29                    "X-Audit-Log-Reason",
30                    reqwest::header::HeaderValue::from_str(r)?,
31                );
32                Ok(h)
33            })
34            .transpose()?;
35
36        self.delete_with_headers(&route, headers).await
37    }
38
39    /// Create a new channel in a guild.
40    pub async fn create_channel(
41        &self,
42        guild_id: Snowflake,
43        params: &titanium_model::builder::CreateChannel<'_>,
44    ) -> Result<Channel<'static>, HttpError> {
45        let route = format!("/guilds/{}/channels", guild_id);
46        self.post(&route, params).await
47    }
48
49    // =========================================================================
50    // Message Operations
51    // =========================================================================
52
53    /// Get a single message.
54    pub async fn get_message(
55        &self,
56        channel_id: Snowflake,
57        message_id: Snowflake,
58    ) -> Result<Message<'static>, HttpError> {
59        let route = format!("/channels/{}/messages/{}", channel_id, message_id);
60        self.get(&route).await
61    }
62
63    /// Send a message to a channel.
64    pub async fn create_message_struct(
65        &self,
66        channel_id: Snowflake,
67        message: &CreateMessage<'_>,
68    ) -> Result<Message<'static>, HttpError> {
69        let route = format!("/channels/{}/messages", channel_id);
70        self.post(&route, message).await
71    }
72
73    /// Send a simple text message.
74    pub async fn send_message(
75        &self,
76        channel_id: Snowflake,
77        content: impl Into<String>,
78    ) -> Result<Message<'static>, HttpError> {
79        #[derive(Serialize)]
80        struct SimpleMessage {
81            content: String,
82        }
83
84        let route = format!("/channels/{}/messages", channel_id);
85        self.post(
86            &route,
87            SimpleMessage {
88                content: content.into(),
89            },
90        )
91        .await
92    }
93
94    /// Edit a message.
95    pub async fn edit_message(
96        &self,
97        channel_id: Snowflake,
98        message_id: Snowflake,
99        content: impl Into<String>,
100    ) -> Result<Message<'static>, HttpError> {
101        #[derive(Serialize)]
102        struct EditMessage {
103            content: String,
104        }
105
106        let route = format!("/channels/{}/messages/{}", channel_id, message_id);
107        self.patch(
108            &route,
109            EditMessage {
110                content: content.into(),
111            },
112        )
113        .await
114    }
115
116    /// Delete a message.
117    pub async fn delete_message(
118        &self,
119        channel_id: Snowflake,
120        message_id: Snowflake,
121        reason: Option<&str>,
122    ) -> Result<(), HttpError> {
123        let route = format!("/channels/{}/messages/{}", channel_id, message_id);
124
125        let headers = reason
126            .map(|r| -> Result<_, HttpError> {
127                let mut h = reqwest::header::HeaderMap::new();
128                h.insert(
129                    "X-Audit-Log-Reason",
130                    reqwest::header::HeaderValue::from_str(r)?,
131                );
132                Ok(h)
133            })
134            .transpose()?;
135
136        self.delete_with_headers(&route, headers).await
137    }
138
139    /// Bulk delete messages (2-100 messages, not older than 14 days).
140    /// This is much faster than deleting one by one.
141    pub async fn bulk_delete_messages(
142        &self,
143        channel_id: Snowflake,
144        message_ids: &[Snowflake],
145    ) -> Result<(), HttpError> {
146        if message_ids.len() < 2 || message_ids.len() > 100 {
147            return Err(HttpError::ClientError(
148                "bulk_delete_messages requires 2-100 message IDs".into(),
149            ));
150        }
151
152        #[derive(Serialize)]
153        struct BulkDelete<'a> {
154            messages: &'a [Snowflake],
155        }
156
157        let route = format!("/channels/{}/messages/bulk-delete", channel_id);
158        self.post_no_response(
159            &route,
160            BulkDelete {
161                messages: message_ids,
162            },
163        )
164        .await
165    }
166
167    // =========================================================================
168    // Webhook Operations (merged from webhook.rs)
169    // =========================================================================
170
171    /// Create a webhook.
172    pub async fn create_webhook(
173        &self,
174        channel_id: Snowflake,
175        name: &str,
176        avatar: Option<&str>,
177    ) -> Result<Webhook<'static>, HttpError> {
178        #[derive(Serialize)]
179        struct CreateWebhook<'a> {
180            name: &'a str,
181            avatar: Option<&'a str>,
182        }
183
184        let route = format!("/channels/{}/webhooks", channel_id);
185        self.post(&route, CreateWebhook { name, avatar }).await
186    }
187
188    /// Get channel webhooks.
189    pub async fn get_channel_webhooks(
190        &self,
191        channel_id: Snowflake,
192    ) -> Result<Vec<Webhook<'static>>, HttpError> {
193        let route = format!("/channels/{}/webhooks", channel_id);
194        self.get(&route).await
195    }
196
197    /// Get guild webhooks.
198    pub async fn get_guild_webhooks(
199        &self,
200        guild_id: Snowflake,
201    ) -> Result<Vec<Webhook<'static>>, HttpError> {
202        let route = format!("/guilds/{}/webhooks", guild_id);
203        self.get(&route).await
204    }
205
206    /// Execute webhook (send message).
207    pub async fn execute_webhook(
208        &self,
209        webhook_id: Snowflake,
210        webhook_token: &str,
211        params: &titanium_model::builder::ExecuteWebhook,
212    ) -> Result<Option<Message<'static>>, HttpError> {
213        let route = format!("/webhooks/{}/{}", webhook_id, webhook_token);
214        self.post_with_query(&route, params, &[("wait", "true")])
215            .await
216    }
217}