twilight_model/gateway/intents.rs
1use bitflags::bitflags;
2use serde::{
3 de::{Deserialize, Deserializer},
4 ser::{Serialize, Serializer},
5};
6
7bitflags! {
8 /// Gateway intents.
9 ///
10 /// Developers must specify intents when connecting to the gateway. The
11 /// intents specified correspond with the events received. To specify
12 /// multiple intents, create a union using the `|` operator. See
13 /// [Discord Docs/Gateway Intents].
14 ///
15 /// [Discord Docs/Gateway Intents]: https://discord.com/developers/docs/topics/gateway#gateway-intents
16 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
17 pub struct Intents: u64 {
18 /// Guilds intent.
19 ///
20 /// Event(s) received:
21 /// - [`GUILD_CREATE`]
22 /// - [`GUILD_UPDATE`]
23 /// - [`GUILD_DELETE`]
24 /// - [`GUILD_ROLE_CREATE`]
25 /// - [`GUILD_ROLE_UPDATE`]
26 /// - [`GUILD_ROLE_DELETE`]
27 /// - [`CHANNEL_CREATE`]
28 /// - [`CHANNEL_UPDATE`]
29 /// - [`CHANNEL_DELETE`]
30 /// - [`CHANNEL_PINS_UPDATE`]
31 /// - [`THREAD_CREATE`]
32 /// - [`THREAD_UPDATE`]
33 /// - [`THREAD_DELETE`]
34 /// - [`THREAD_LIST_SYNC`]
35 /// - [`THREAD_MEMBER_UPDATE`]
36 /// - [`THREAD_MEMBERS_UPDATE`]
37 /// - [`STAGE_INSTANCE_CREATE`]
38 /// - [`STAGE_INSTANCE_UPDATE`]
39 /// - [`STAGE_INSTANCE_DELETE`]
40 ///
41 /// [`GUILD_CREATE`]: super::event::Event::GuildCreate
42 /// [`GUILD_UPDATE`]: super::event::Event::GuildUpdate
43 /// [`GUILD_DELETE`]: super::event::Event::GuildDelete
44 /// [`GUILD_ROLE_CREATE`]: super::event::Event::RoleCreate
45 /// [`GUILD_ROLE_UPDATE`]: super::event::Event::RoleUpdate
46 /// [`GUILD_ROLE_DELETE`]: super::event::Event::RoleDelete
47 /// [`CHANNEL_CREATE`]: super::event::Event::ChannelCreate
48 /// [`CHANNEL_UPDATE`]: super::event::Event::ChannelUpdate
49 /// [`CHANNEL_DELETE`]: super::event::Event::ChannelDelete
50 /// [`CHANNEL_PINS_UPDATE`]: super::event::Event::ChannelPinsUpdate
51 /// [`THREAD_CREATE`]: super::event::Event::ThreadCreate
52 /// [`THREAD_UPDATE`]: super::event::Event::ThreadUpdate
53 /// [`THREAD_DELETE`]: super::event::Event::ThreadDelete
54 /// [`THREAD_LIST_SYNC`]: super::event::Event::ThreadListSync
55 /// [`THREAD_MEMBER_UPDATE`]: super::event::Event::ThreadMemberUpdate
56 /// [`THREAD_MEMBERS_UPDATE`]: super::event::Event::ThreadMembersUpdate
57 /// [`STAGE_INSTANCE_CREATE`]: super::event::Event::StageInstanceCreate
58 /// [`STAGE_INSTANCE_UPDATE`]: super::event::Event::StageInstanceUpdate
59 /// [`STAGE_INSTANCE_DELETE`]: super::event::Event::StageInstanceDelete
60 const GUILDS = 1;
61 /// Guild members intent.
62 ///
63 /// This intent is privileged. See [Discord Docs/Privileged Intents].
64 ///
65 /// Event(s) received:
66 /// - [`GUILD_MEMBER_ADD`]
67 /// - [`GUILD_MEMBER_UPDATE`]
68 /// - [`GUILD_MEMBER_REMOVE`]
69 /// - [`THREAD_MEMBERS_UPDATE`]
70 ///
71 /// [Discord Docs/Privileged Intents]: https://discord.com/developers/docs/topics/gateway#privileged-intents
72 /// [`GUILD_MEMBER_ADD`]: super::event::Event::MemberAdd
73 /// [`GUILD_MEMBER_UPDATE`]: super::event::Event::MemberUpdate
74 /// [`GUILD_MEMBER_REMOVE`]: super::event::Event::MemberRemove
75 /// [`THREAD_MEMBERS_UPDATE`]: super::event::Event::ThreadMembersUpdate
76 const GUILD_MEMBERS = 1 << 1;
77 /// Guild moderation intent.
78 ///
79 /// Event(s) received:
80 /// - [`GUILD_AUDIT_LOG_ENTRY_CREATE`]
81 /// - [`GUILD_BAN_ADD`]
82 /// - [`GUILD_BAN_REMOVE`]
83 ///
84 /// [`GUILD_AUDIT_LOG_ENTRY_CREATE`]: super::event::Event::
85 /// [`GUILD_BAN_ADD`]: super::event::Event::BanAdd
86 /// [`GUILD_BAN_REMOVE`]: super::event::Event::BanRemove
87 const GUILD_MODERATION = 1 << 2;
88 /// Guild emojis and stickers intent.
89 ///
90 /// Event(s) received:
91 /// - [`GUILD_EMOJIS_UPDATE`]
92 /// - [`GUILD_STICKERS_UPDATE`]
93 ///
94 /// [`GUILD_EMOJIS_UPDATE`]: super::event::Event::GuildEmojisUpdate
95 /// [`GUILD_STICKERS_UPDATE`]: super::event::Event::GuildStickersUpdate
96 const GUILD_EMOJIS_AND_STICKERS = 1 << 3;
97 /// Guild integrations intent.
98 ///
99 /// Event(s) received:
100 /// - [`GUILD_INTEGRATIONS_UPDATE`]
101 /// - [`INTEGRATION_CREATE`]
102 /// - [`INTEGRATION_UPDATE`]
103 /// - [`INTEGRATION_DELETE`]
104 ///
105 /// [`GUILD_INTEGRATIONS_UPDATE`]: super::event::Event::GuildIntegrationsUpdate
106 /// [`INTEGRATION_CREATE`]: super::event::Event::IntegrationCreate
107 /// [`INTEGRATION_UPDATE`]: super::event::Event::IntegrationUpdate
108 /// [`INTEGRATION_DELETE`]: super::event::Event::IntegrationDelete
109 const GUILD_INTEGRATIONS = 1 << 4;
110 /// Guild webhooks intent.
111 ///
112 /// Event(s) received:
113 /// - [`WEBHOOKS_UPDATE`]
114 ///
115 /// [`WEBHOOKS_UPDATE`]: super::event::Event::WebhooksUpdate
116 const GUILD_WEBHOOKS = 1 << 5;
117 /// Guild invites intent.
118 ///
119 /// Event(s) received:
120 /// - [`INVITE_CREATE`]
121 /// - [`INVITE_DELETE`]
122 ///
123 /// [`INVITE_CREATE`]: super::event::Event::InviteCreate
124 /// [`INVITE_DELETE`]: super::event::Event::InviteDelete
125 const GUILD_INVITES = 1 << 6;
126 /// Guild voice states intent.
127 ///
128 /// Event(s) received:
129 /// - [`VOICE_STATE_UPDATE`]
130 ///
131 /// [`VOICE_STATE_UPDATE`]: super::event::Event::VoiceStateUpdate
132 const GUILD_VOICE_STATES = 1 << 7;
133 /// Guild presences intent.
134 ///
135 /// This intent is privileged. See [Discord Docs/Privileged Intents].
136 ///
137 /// Event(s) received:
138 /// - [`PRESENCE_UPDATE`]
139 ///
140 /// [Discord Docs/Privileged Intents]: https://discord.com/developers/docs/topics/gateway#privileged-intents
141 /// [`PRESENCE_UPDATE`]: super::event::Event::PresenceUpdate
142 const GUILD_PRESENCES = 1 << 8;
143 /// Guild messages intent.
144 ///
145 /// Event(s) received:
146 /// - [`MESSAGE_CREATE`]
147 /// - [`MESSAGE_UPDATE`]
148 /// - [`MESSAGE_DELETE`]
149 /// - [`MESSAGE_DELETE_BULK`]
150 ///
151 /// [`MESSAGE_CREATE`]: super::event::Event::MessageCreate
152 /// [`MESSAGE_UPDATE`]: super::event::Event::MessageUpdate
153 /// [`MESSAGE_DELETE`]: super::event::Event::MessageDelete
154 /// [`MESSAGE_DELETE_BULK`]: super::event::Event::MessageDeleteBulk
155 const GUILD_MESSAGES = 1 << 9;
156 /// Guild message reactions intent.
157 ///
158 /// Event(s) received:
159 /// - [`MESSAGE_REACTION_ADD`]
160 /// - [`MESSAGE_REACTION_REMOVE`]
161 /// - [`MESSAGE_REACTION_REMOVE_ALL`]
162 /// - [`MESSAGE_REACTION_REMOVE_EMOJI`]
163 ///
164 /// [`MESSAGE_REACTION_ADD`]: super::event::Event::ReactionAdd
165 /// [`MESSAGE_REACTION_REMOVE`]: super::event::Event::ReactionRemove
166 /// [`MESSAGE_REACTION_REMOVE_ALL`]: super::event::Event::ReactionRemoveAll
167 /// [`MESSAGE_REACTION_REMOVE_EMOJI`]: super::event::Event::ReactionRemoveEmoji
168 const GUILD_MESSAGE_REACTIONS = 1 << 10;
169 /// Guild message typing intent.
170 ///
171 /// Event(s) received:
172 /// - [`TYPING_START`]
173 ///
174 /// [`TYPING_START`]: super::event::Event::TypingStart
175 const GUILD_MESSAGE_TYPING = 1 << 11;
176 /// Direct messages intent.
177 ///
178 /// Event(s) received:
179 /// - [`MESSAGE_CREATE`]
180 /// - [`MESSAGE_UPDATE`]
181 /// - [`MESSAGE_DELETE`]
182 /// - [`MESSAGE_DELETE_BULK`]
183 ///
184 /// This is different from the [`GUILD_MESSAGES`] intent in that the bot
185 /// will receive message events from locations other than guilds.
186 ///
187 /// [`MESSAGE_CREATE`]: super::event::Event::MessageCreate
188 /// [`MESSAGE_UPDATE`]: super::event::Event::MessageUpdate
189 /// [`MESSAGE_DELETE`]: super::event::Event::MessageDelete
190 /// [`MESSAGE_DELETE_BULK`]: super::event::Event::MessageDeleteBulk
191 /// [`GUILD_MESSAGES`]: Self::GUILD_MESSAGES
192 const DIRECT_MESSAGES = 1 << 12;
193 /// Direct message reactions intent.
194 ///
195 /// Event(s) received:
196 /// - [`MESSAGE_REACTION_ADD`]
197 /// - [`MESSAGE_REACTION_REMOVE`]
198 /// - [`MESSAGE_REACTION_REMOVE_ALL`]
199 /// - [`MESSAGE_REACTION_REMOVE_EMOJI`]
200 ///
201 /// This is different from the [`GUILD_MESSAGE_REACTIONS`] event in that
202 /// the bot will receive message reaction events from locations other
203 /// than guilds.
204 ///
205 /// [`MESSAGE_REACTION_ADD`]: super::event::Event::ReactionAdd
206 /// [`MESSAGE_REACTION_REMOVE`]: super::event::Event::ReactionRemove
207 /// [`MESSAGE_REACTION_REMOVE_ALL`]: super::event::Event::ReactionRemoveAll
208 /// [`MESSAGE_REACTION_REMOVE_EMOJI`]: super::event::Event::ReactionRemoveEmoji
209 /// [`GUILD_MESSAGE_REACTIONS`]: Self::GUILD_MESSAGE_REACTIONS
210 const DIRECT_MESSAGE_REACTIONS = 1 << 13;
211 /// Direct message typing intent.
212 ///
213 /// Event(s) received:
214 /// - [`TYPING_START`]
215 ///
216 /// This is different from the [`GUILD_MESSAGE_TYPING`] intent in that
217 /// the bot will receive typing start events from locations other than
218 /// guilds.
219 ///
220 /// [`TYPING_START`]: super::event::Event::TypingStart
221 /// [`GUILD_MESSAGE_TYPING`]: Self::GUILD_MESSAGE_TYPING
222 const DIRECT_MESSAGE_TYPING = 1 << 14;
223 /// Message content intent.
224 ///
225 /// This intent is privileged. See [Discord Docs/Privileged Intents].
226 ///
227 /// This intent allows you to receive the contents of all messages.
228 ///
229 /// [Discord Docs/Privileged Intents]: https://discord.com/developers/docs/topics/gateway#privileged-intents
230 const MESSAGE_CONTENT = 1 << 15;
231 /// Guild scheduled events intent.
232 ///
233 /// Event(s) received:
234 ///
235 /// - [`GUILD_SCHEDULED_EVENT_CREATE`]
236 /// - [`GUILD_SCHEDULED_EVENT_UPDATE`]
237 /// - [`GUILD_SCHEDULED_EVENT_DELETE`]
238 /// - [`GUILD_SCHEDULED_EVENT_USER_ADD`]
239 /// - [`GUILD_SCHEDULED_EVENT_USER_REMOVE`]
240 ///
241 /// [`GUILD_SCHEDULED_EVENT_CREATE`]: super::event::Event::GuildScheduledEventCreate
242 /// [`GUILD_SCHEDULED_EVENT_UPDATE`]: super::event::Event::GuildScheduledEventDelete
243 /// [`GUILD_SCHEDULED_EVENT_DELETE`]: super::event::Event::GuildScheduledEventUpdate
244 /// [`GUILD_SCHEDULED_EVENT_USER_ADD`]: super::event::Event::GuildScheduledEventUserAdd
245 /// [`GUILD_SCHEDULED_EVENT_USER_REMOVE`]: super::event::Event::GuildScheduledEventUserRemove
246 const GUILD_SCHEDULED_EVENTS = 1 << 16;
247 /// Auto moderation configuration intent.
248 ///
249 /// Event(s) received:
250 /// - [`AUTO_MODERATION_RULE_CREATE`]
251 /// - [`AUTO_MODERATION_RULE_DELETE`]
252 /// - [`AUTO_MODERATION_RULE_UPDATE`]
253 ///
254 /// [`AUTO_MODERATION_RULE_CREATE`]: super::event::Event::AutoModerationRuleCreate
255 /// [`AUTO_MODERATION_RULE_DELETE`]: super::event::Event::AutoModerationRuleDelete
256 /// [`AUTO_MODERATION_RULE_UPDATE`]: super::event::Event::AutoModerationRuleUpdate
257 const AUTO_MODERATION_CONFIGURATION = 1 << 20;
258 /// Auto moderation execution event.
259 ///
260 /// Event(s) received:
261 /// - [`AUTO_MODERATION_ACTION_EXECUTION`]
262 ///
263 /// [`AUTO_MODERATION_ACTION_EXECUTION`]: super::event::Event::AutoModerationActionExecution
264 const AUTO_MODERATION_EXECUTION = 1 << 21;
265 /// Guild polls intent.
266 ///
267 /// Event(s) received:
268 /// - [`MESSAGE_POLL_VOTE_ADD`]
269 /// - [`MESSAGE_POLL_VOTE_REMOVE`]
270 ///
271 /// [`MESSAGE_POLL_VOTE_ADD`]: super::event::Event::MessagePollVoteAdd
272 /// [`MESSAGE_POLL_VOTE_REMOVE`]: super::event::Event::MessagePollVoteRemove
273 const GUILD_MESSAGE_POLLS = 1 << 24;
274 /// Direct message polls intent.
275 ///
276 /// Event(s) received:
277 /// - [`MESSAGE_POLL_VOTE_ADD`]
278 /// - [`MESSAGE_POLL_VOTE_REMOVE`]
279 ///
280 /// [`MESSAGE_POLL_VOTE_ADD`]: super::event::Event::MessagePollVoteAdd
281 /// [`MESSAGE_POLL_VOTE_REMOVE`]: super::event::Event::MessagePollVoteRemove
282 const DIRECT_MESSAGE_POLLS = 1 << 25;
283 }
284}
285
286impl<'de> Deserialize<'de> for Intents {
287 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
288 Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?))
289 }
290}
291
292impl Serialize for Intents {
293 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
294 where
295 S: Serializer,
296 {
297 serializer.serialize_u64(self.bits())
298 }
299}
300
301#[cfg(test)]
302mod tests {
303 #![allow(deprecated)]
304
305 use super::Intents;
306 use serde::{Deserialize, Serialize};
307 use serde_test::Token;
308 use static_assertions::{assert_impl_all, const_assert_eq};
309 use std::{
310 fmt::{Binary, Debug, LowerHex, Octal, UpperHex},
311 hash::Hash,
312 ops::{
313 BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign,
314 },
315 };
316
317 assert_impl_all!(
318 Intents: Binary,
319 BitAnd,
320 BitAndAssign,
321 BitOr,
322 BitOrAssign,
323 BitXor,
324 BitXorAssign,
325 Clone,
326 Copy,
327 Debug,
328 Deserialize<'static>,
329 Eq,
330 Extend<Intents>,
331 FromIterator<Intents>,
332 Hash,
333 LowerHex,
334 Not,
335 Octal,
336 PartialEq,
337 Send,
338 Serialize,
339 Sub,
340 SubAssign,
341 Sync,
342 UpperHex
343 );
344 const_assert_eq!(Intents::GUILDS.bits(), 1);
345 const_assert_eq!(Intents::GUILD_MEMBERS.bits(), 1 << 1);
346 const_assert_eq!(Intents::GUILD_MODERATION.bits(), 1 << 2);
347 const_assert_eq!(Intents::GUILD_EMOJIS_AND_STICKERS.bits(), 1 << 3);
348 const_assert_eq!(Intents::GUILD_INTEGRATIONS.bits(), 1 << 4);
349 const_assert_eq!(Intents::GUILD_WEBHOOKS.bits(), 1 << 5);
350 const_assert_eq!(Intents::GUILD_INVITES.bits(), 1 << 6);
351 const_assert_eq!(Intents::GUILD_VOICE_STATES.bits(), 1 << 7);
352 const_assert_eq!(Intents::GUILD_PRESENCES.bits(), 1 << 8);
353 const_assert_eq!(Intents::GUILD_MESSAGES.bits(), 1 << 9);
354 const_assert_eq!(Intents::GUILD_MESSAGE_REACTIONS.bits(), 1 << 10);
355 const_assert_eq!(Intents::GUILD_MESSAGE_TYPING.bits(), 1 << 11);
356 const_assert_eq!(Intents::DIRECT_MESSAGES.bits(), 1 << 12);
357 const_assert_eq!(Intents::DIRECT_MESSAGE_REACTIONS.bits(), 1 << 13);
358 const_assert_eq!(Intents::DIRECT_MESSAGE_TYPING.bits(), 1 << 14);
359 const_assert_eq!(Intents::MESSAGE_CONTENT.bits(), 1 << 15);
360 const_assert_eq!(Intents::GUILD_SCHEDULED_EVENTS.bits(), 1 << 16);
361 const_assert_eq!(Intents::AUTO_MODERATION_CONFIGURATION.bits(), 1 << 20);
362 const_assert_eq!(Intents::AUTO_MODERATION_EXECUTION.bits(), 1 << 21);
363 const_assert_eq!(Intents::GUILD_MESSAGE_POLLS.bits(), 1 << 24);
364 const_assert_eq!(Intents::DIRECT_MESSAGE_POLLS.bits(), 1 << 25);
365
366 #[test]
367 fn serde() {
368 serde_test::assert_tokens(
369 &Intents::MESSAGE_CONTENT,
370 &[Token::U64(Intents::MESSAGE_CONTENT.bits())],
371 );
372 // Deserialization truncates unknown bits.
373 serde_test::assert_de_tokens(&Intents::empty(), &[Token::U64(1 << 63)]);
374 }
375}