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