actor_discord/
intents.rs

1use bitflags::__impl_bitflags;
2use serde::{
3    de::{Deserialize, Deserializer},
4    ser::{Serialize, Serializer},
5};
6
7/// [Gateway Intents] will limit the events your bot will receive via the gateway.
8/// By default, all intents except [Privileged Intents] are selected.
9///
10/// # What are Intents
11///
12/// A [gateway intent] sets the types of gateway events
13/// (e.g. member joins, guild integrations, guild emoji updates, ...) the
14/// bot shall receive. Carefully picking the needed intents greatly helps
15/// the bot to scale, as less intents will result in less events to be
16/// received via the network from Discord and less processing needed for
17/// handling the data.
18///
19/// # Privileged Intents
20///
21/// The intents [`GatewayIntents::GUILD_PRESENCES`] and [`GatewayIntents::GUILD_MEMBERS`]
22/// are [Privileged Intents]. They need to be enabled in the
23/// *developer portal*.
24///
25/// **Note**:
26/// Once the bot is in 100 guilds or more, [the bot must be verified] in
27/// order to use privileged intents.
28///
29/// [gateway intent]: https://discord.com/developers/docs/topics/gateway#privileged-intents
30/// [Privileged Intents]: https://discord.com/developers/docs/topics/gateway#privileged-intents
31/// [the bot must be verified]: https://support.discord.com/hc/en-us/articles/360040720412-Bot-Verification-and-Data-Whitelisting
32/// [`GatewayIntents::GuildPresences`]: serenity::client::bridge::gateway::GatewayIntents::GUILD_PRESENCES
33/// [`GatewayIntents::GuildMembers`]: serenity::client::bridge::gateway::GatewayIntents::GUILD_MEMBERS
34#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
35pub struct GatewayIntents {
36    /// The flags composing gateway intents.
37    ///
38    /// # Note
39    /// Do not modify this yourself; use the provided methods.
40    /// Do the same when creating, unless you're absolutely certain that you're giving valid intents flags.
41    pub bits: u64,
42}
43
44__impl_bitflags! {
45    GatewayIntents: u64 {
46        /// Enables following gateway events:
47        ///
48        /// - GuildCreate
49        /// - GUILD_DELETE
50        /// - GUILD_ROLE_CREATE
51        /// - GUILD_ROLE_UPDATE
52        /// - GUILD_ROLE_DELETE
53        /// - CHANNEL_CREATE
54        /// - CHANNEL_UPDATE
55        /// - CHANNEL_DELETE
56        /// - CHANNEL_PINS_UPDATE
57        /// - THREAD_CREATE
58        /// - THREAD_UPDATE
59        /// - THREAD_DELETE
60        /// - THREAD_LIST_SYNC
61        /// - THREAD_MEMBER_UPDATE
62        /// - THREAD_MEMBERS_UPDATE
63        /// - STAGE_INSTANCE_CREATE
64        /// - STAGE_INSTANCE_UPDATE
65        /// - STAGE_INSTANCE_DELETE
66        GUILDS = 1;
67        /// Enables following gateway events:
68        ///
69        /// - GUILD_MEMBER_ADD
70        /// - GUILD_MEMBER_UPDATE
71        /// - GUILD_MEMBER_REMOVE
72        /// - THREAD_MEMBERS_UPDATE
73        ///
74        /// **Info**:
75        /// This intent is *privileged*.
76        /// In order to use it, you must head to your application in the
77        /// Developer Portal and enable the toggle for *Privileged Intents*.
78        ///
79        /// This intent is also necessary to even receive the events in contains.
80        GUILD_MEMBERS = 1 << 1;
81        /// Enables following gateway events:
82        ///
83        /// - GUILD_BAN_ADD
84        /// - GUILD_BAN_REMOVE
85        GUILD_BANS = 1 << 2;
86        /// Enables following gateway event:
87        ///
88        /// - GUILD_EMOJIS_UPDATE
89        GUILD_EMOJIS = 1 << 3;
90        /// Enables following gateway event:
91        ///
92        /// - GUILD_INTEGRATIONS_UPDATE
93        /// - INTEGRATION_CREATE
94        /// - INTEGRATION_UPDATE
95        /// - INTEGRATION_DELETE
96        GUILD_INTEGRATIONS = 1 << 4;
97        /// Enables following gateway event:
98        ///
99        /// - WEBHOOKS_UPDATE
100        GUILD_WEBHOOKS = 1 << 5;
101        /// Enables following gateway events:
102        ///
103        /// - INVITE_CREATE
104        /// - INVITE_DELETE
105        GUILD_INVITES = 1 << 6;
106        /// Enables following gateway event:
107        ///
108        /// - VOICE_STATE_UPDATE
109        GUILD_VOICE_STATES = 1 << 7;
110        /// Enables following gateway event:
111        ///
112        /// - PRESENCE_UPDATE
113        ///
114        /// **Info**:
115        /// This intent is *privileged*.
116        /// In order to use it, you must head to your application in the
117        /// Developer Portal and enable the toggle for *Privileged Intents*.
118        ///
119        /// This intent is also necessary to even receive the events in contains.
120        GUILD_PRESENCES = 1 << 8;
121        /// Enables following gateway events:
122        ///
123        /// - MESSAGE_CREATE
124        /// - MESSAGE_UPDATE
125        /// - MESSAGE_DELETE
126        /// - MESSAGE_DELETE_BULK
127        GUILD_MESSAGES = 1 << 9;
128        /// Enables following gateway events:
129        ///
130        /// - MESSAGE_REACTION_ADD
131        /// - MESSAGE_REACTION_REMOVE
132        /// - MESSAGE_REACTION_REMOVE_ALL
133        /// - MESSAGE_REACTION_REMOVE_EMOJI
134        GUILD_MESSAGE_REACTIONS = 1 << 10;
135        /// Enable following gateway event:
136        ///
137        /// - TYPING_START
138        GUILD_MESSAGE_TYPING = 1 << 11;
139        /// Enable following gateway events:
140        ///
141        /// - MESSAGE_CREATE
142        /// - MESSAGE_UPDATE
143        /// - MESSAGE_DELETE
144        /// - CHANNEL_PINS_UPDATE
145        DIRECT_MESSAGES = 1 << 12;
146        /// Enable following gateway events:
147        ///
148        /// - MESSAGE_REACTION_ADD
149        /// - MESSAGE_REACTION_REMOVE
150        /// - MESSAGE_REACTION_REMOVE_ALL
151        /// - MESSAGE_REACTION_REMOVE_EMOJI
152        DIRECT_MESSAGE_REACTIONS = 1 << 13;
153        /// Enable following gateway event:
154        ///
155        /// - TYPING_START
156        DIRECT_MESSAGE_TYPING = 1 << 14;
157    }
158}
159
160impl Default for GatewayIntents {
161    fn default() -> Self {
162        Self::empty()
163    }
164}
165
166impl<'de> Deserialize<'de> for GatewayIntents {
167    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
168        Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?))
169    }
170}
171
172impl Serialize for GatewayIntents {
173    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
174    where
175        S: Serializer,
176    {
177        serializer.serialize_u64(self.bits())
178    }
179}
180
181#[cfg(feature = "model")]
182impl GatewayIntents {
183    /// Gets all of the intents that don't are considered privileged by Discord.
184    pub const fn non_privileged() -> GatewayIntents {
185        // bitflags don't support const evaluation. Workaround.
186        // See: https://github.com/bitflags/bitflags/issues/180
187        Self::from_bits_truncate(Self::all().bits() & !Self::privileged().bits())
188    }
189
190    /// Gets all of the intents that are considered privileged by Discord.
191    /// Use of these intents will require explicitly whitelisting the bot.
192    pub const fn privileged() -> GatewayIntents {
193        // bitflags don't support const evaluation. Workaround.
194        // See: https://github.com/bitflags/bitflags/issues/180
195        Self::from_bits_truncate(Self::GUILD_MEMBERS.bits() | Self::GUILD_PRESENCES.bits())
196    }
197
198    /// Checks if any of the included intents are privileged
199    ///
200    /// [GUILD_MEMBERS]: #associatedconstant.GUILD_MEMBERS
201    /// [GUILD_PRESENCES]: #associatedconstant.GUILD_PRESENCES
202    pub fn is_privileged(self) -> bool {
203        self.guild_members() || self.guild_presences()
204    }
205
206    /// Shorthand for checking that the set of intents contains the
207    /// [GUILDS] intent.
208    ///
209    /// [GUILDS]: Self::GUILDS
210    pub fn guilds(self) -> bool {
211        self.contains(Self::GUILDS)
212    }
213
214    /// Shorthand for checking that the set of intents contains the
215    /// [GUILD_MEMBERS] intent.
216    ///
217    /// [GUILD_MEMBERS]: Self::GUILD_MEMBERS
218    pub fn guild_members(self) -> bool {
219        self.contains(Self::GUILD_MEMBERS)
220    }
221
222    /// Shorthand for checking that the set of intents contains the
223    /// [GUILD_BANS] intent.
224    ///
225    /// [GUILD_BANS]: Self::GUILD_BANS
226    pub fn guild_bans(self) -> bool {
227        self.contains(Self::GUILD_BANS)
228    }
229
230    /// Shorthand for checking that the set of intents contains the
231    /// [GUILD_EMOJIS] intent.
232    ///
233    /// [GUILD_EMOJIS]: Self::GUILD_EMOJIS
234    pub fn guild_emojis(self) -> bool {
235        self.contains(Self::GUILD_EMOJIS)
236    }
237
238    /// Shorthand for checking that the set of intents contains the
239    /// [GUILD_INTEGRATIONS] intent.
240    ///
241    /// [GUILD_INTEGRATIONS]: Self::GUILD_INTEGRATIONS
242    pub fn guild_integrations(self) -> bool {
243        self.contains(Self::GUILD_INTEGRATIONS)
244    }
245
246    /// Shorthand for checking that the set of intents contains the
247    /// [GUILD_WEBHOOKS] intent.
248    ///
249    /// [GUILD_WEBHOOKS]: Self::GUILD_WEBHOOKS
250    pub fn guild_webhooks(self) -> bool {
251        self.contains(Self::GUILD_WEBHOOKS)
252    }
253
254    /// Shorthand for checking that the set of intents contains the
255    /// [GUILD_INVITES] intent.
256    ///
257    /// [GUILD_INVITES]: Self::GUILD_INVITES
258    pub fn guild_invites(self) -> bool {
259        self.contains(Self::GUILD_INVITES)
260    }
261
262    /// Shorthand for checking that the set of intents contains the
263    /// [GUILD_VOICE_STATES] intent.
264    ///
265    /// [GUILD_VOICE_STATES]: Self::GUILD_VOICE_STATES
266    pub fn guild_voice_states(self) -> bool {
267        self.contains(Self::GUILD_VOICE_STATES)
268    }
269
270    /// Shorthand for checking that the set of intents contains the
271    /// [GUILD_PRESENCES] intent.
272    ///
273    /// [GUILD_PRESENCES]: Self::GUILD_PRESENCES
274    pub fn guild_presences(self) -> bool {
275        self.contains(Self::GUILD_PRESENCES)
276    }
277
278    /// Shorthand for checking that the set of intents contains the
279    /// [GUILD_MESSAGE_REACTIONS] intent.
280    ///
281    /// [GUILD_MESSAGE_REACTIONS]: Self::GUILD_MESSAGE_REACTIONS
282    pub fn guild_message_reactions(self) -> bool {
283        self.contains(Self::GUILD_MESSAGE_REACTIONS)
284    }
285
286    /// Shorthand for checking that the set of intents contains the
287    /// [GUILD_MESSAGE_TYPING] intent.
288    ///
289    /// [GUILD_MESSAGE_TYPING]: Self::GUILD_MESSAGE_TYPING
290    pub fn guild_message_typing(self) -> bool {
291        self.contains(Self::GUILD_MESSAGE_TYPING)
292    }
293
294    /// Shorthand for checking that the set of intents contains the
295    /// [DIRECT_MESSAGES] intent.
296    ///
297    /// [DIRECT_MESSAGES]: Self::DIRECT_MESSAGES
298    pub fn direct_messages(self) -> bool {
299        self.contains(Self::DIRECT_MESSAGES)
300    }
301
302    /// Shorthand for checking that the set of intents contains the
303    /// [DIRECT_MESSAGE_REACTIONS] intent.
304    ///
305    /// [DIRECT_MESSAGE_REACTIONS]: Self::DIRECT_MESSAGE_REACTIONS
306    pub fn direct_message_reactions(self) -> bool {
307        self.contains(Self::DIRECT_MESSAGE_REACTIONS)
308    }
309
310    /// Shorthand for checking that the set of intents contains the
311    /// [DIRECT_MESSAGE_TYPING] intent.
312    ///
313    /// [DIRECT_MESSAGE_TYPING]: Self::DIRECT_MESSAGE_TYPING
314    pub fn direct_message_typing(self) -> bool {
315        self.contains(Self::DIRECT_MESSAGE_TYPING)
316    }
317}