titanium_model/
integration.rs

1//! Integration and webhook types.
2//!
3//! Integrations connect external services to Discord guilds.
4
5use crate::Snowflake;
6use crate::TitanString;
7use serde::{Deserialize, Serialize};
8
9/// A Discord integration.
10#[derive(Debug, Clone, Deserialize, Serialize)]
11pub struct Integration<'a> {
12    /// Integration ID.
13    pub id: Snowflake,
14
15    /// Integration name.
16    pub name: String,
17
18    /// Integration type (twitch, youtube, discord, guild_subscription).
19    #[serde(rename = "type")]
20    pub integration_type: String,
21
22    /// Is this integration enabled.
23    #[serde(default)]
24    pub enabled: bool,
25
26    /// Is this integration syncing.
27    #[serde(default)]
28    pub syncing: Option<bool>,
29
30    /// ID that this integration uses for "subscribers".
31    #[serde(default)]
32    pub role_id: Option<Snowflake>,
33
34    /// Whether emoticons should be synced.
35    #[serde(default)]
36    pub enable_emoticons: Option<bool>,
37
38    /// The behavior of expiring subscribers.
39    #[serde(default)]
40    pub expire_behavior: Option<u8>,
41
42    /// The grace period (in days) before expiring subscribers.
43    #[serde(default)]
44    pub expire_grace_period: Option<u32>,
45
46    /// User for this integration.
47    #[serde(default)]
48    pub user: Option<super::User<'a>>,
49
50    /// Integration account information.
51    #[serde(default)]
52    pub account: Option<IntegrationAccount>,
53
54    /// When this integration was last synced (ISO8601 timestamp).
55    #[serde(default)]
56    pub synced_at: Option<String>,
57
58    /// How many subscribers this integration has.
59    #[serde(default)]
60    pub subscriber_count: Option<u32>,
61
62    /// Has this integration been revoked.
63    #[serde(default)]
64    pub revoked: Option<bool>,
65
66    /// The bot/OAuth2 application for Discord integrations.
67    #[serde(default)]
68    pub application: Option<IntegrationApplication<'a>>,
69
70    /// The scopes the application has been authorized for.
71    #[serde(default)]
72    pub scopes: Vec<String>,
73}
74
75/// Integration account information.
76#[derive(Debug, Clone, Deserialize, Serialize)]
77pub struct IntegrationAccount {
78    /// ID of the account.
79    pub id: String,
80
81    /// Name of the account.
82    pub name: String,
83}
84
85/// Application for a Discord integration.
86#[derive(Debug, Clone, Deserialize, Serialize)]
87pub struct IntegrationApplication<'a> {
88    /// The ID of the app.
89    pub id: Snowflake,
90
91    /// The name of the app.
92    pub name: String,
93
94    /// The icon hash of the app.
95    #[serde(default)]
96    pub icon: Option<String>,
97
98    /// The description of the app.
99    pub description: String,
100
101    /// The bot associated with this application.
102    #[serde(default)]
103    pub bot: Option<super::User<'a>>,
104}
105
106/// Event data for INTEGRATION_DELETE.
107#[derive(Debug, Clone, Deserialize, Serialize)]
108pub struct IntegrationDeleteEvent {
109    /// Integration ID.
110    pub id: Snowflake,
111
112    /// ID of the guild.
113    pub guild_id: Snowflake,
114
115    /// ID of the bot/OAuth2 application for this discord integration.
116    #[serde(default)]
117    pub application_id: Option<Snowflake>,
118}
119
120/// Event data for GUILD_INTEGRATIONS_UPDATE.
121#[derive(Debug, Clone, Deserialize, Serialize)]
122pub struct GuildIntegrationsUpdateEvent {
123    /// ID of the guild.
124    pub guild_id: Snowflake,
125}
126
127/// A Discord webhook.
128#[derive(Debug, Clone, Deserialize, Serialize)]
129pub struct Webhook<'a> {
130    /// The ID of the webhook.
131    pub id: Snowflake,
132
133    /// The type of the webhook.
134    #[serde(rename = "type")]
135    pub webhook_type: u8,
136
137    /// The guild ID this webhook is for.
138    #[serde(default)]
139    pub guild_id: Option<Snowflake>,
140
141    /// The channel ID this webhook is for.
142    #[serde(default)]
143    pub channel_id: Option<Snowflake>,
144
145    /// The user this webhook was created by.
146    #[serde(default)]
147    pub user: Option<super::User<'a>>,
148
149    /// The default name of the webhook.
150    #[serde(default)]
151    pub name: Option<TitanString<'a>>,
152
153    /// The default avatar of the webhook.
154    #[serde(default)]
155    pub avatar: Option<TitanString<'a>>,
156
157    /// The secure token of the webhook.
158    #[serde(default)]
159    pub token: Option<TitanString<'a>>,
160
161    /// The bot/OAuth2 application that created this webhook.
162    #[serde(default)]
163    pub application_id: Option<Snowflake>,
164
165    /// The guild of the channel that this webhook is following.
166    #[serde(default)]
167    pub source_guild: Option<WebhookSourceGuild>,
168
169    /// The channel that this webhook is following.
170    #[serde(default)]
171    pub source_channel: Option<WebhookSourceChannel>,
172
173    /// The URL used for executing the webhook.
174    #[serde(default)]
175    pub url: Option<TitanString<'a>>,
176}
177
178/// Source guild for a webhook.
179#[derive(Debug, Clone, Deserialize, Serialize)]
180pub struct WebhookSourceGuild {
181    /// The ID of the guild.
182    pub id: Snowflake,
183
184    /// The name of the guild.
185    pub name: String,
186
187    /// The icon hash of the guild.
188    #[serde(default)]
189    pub icon: Option<String>,
190}
191
192/// Source channel for a webhook.
193#[derive(Debug, Clone, Deserialize, Serialize)]
194pub struct WebhookSourceChannel {
195    /// The ID of the channel.
196    pub id: Snowflake,
197
198    /// The name of the channel.
199    pub name: String,
200}
201
202/// Event data for WEBHOOKS_UPDATE.
203#[derive(Debug, Clone, Deserialize, Serialize)]
204pub struct WebhooksUpdateEvent {
205    /// ID of the guild.
206    pub guild_id: Snowflake,
207
208    /// ID of the channel.
209    pub channel_id: Snowflake,
210}
211
212#[cfg(test)]
213mod tests {
214    use super::*;
215
216    #[test]
217    fn test_integration() {
218        let json = r#"{
219            "id": "123",
220            "name": "Test Bot",
221            "type": "discord",
222            "enabled": true
223        }"#;
224
225        let integration: Integration = crate::json::from_str(json).unwrap();
226        assert_eq!(integration.name, "Test Bot");
227        assert_eq!(integration.integration_type, "discord");
228    }
229
230    #[test]
231    fn test_webhook() {
232        let json = r#"{
233            "id": "123",
234            "type": 1,
235            "guild_id": "456",
236            "channel_id": "789",
237            "name": "Test Webhook"
238        }"#;
239
240        let _webhook: Webhook = crate::json::from_str(json).unwrap();
241        let webhook: Webhook = crate::json::from_str(json).unwrap();
242        assert_eq!(webhook.name, Some(TitanString::Borrowed("Test Webhook")));
243    }
244}