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}