serenity/model/
event.rs

1//! All the events this library handles.
2//!
3//! Every event includes the gateway intent required to receive it, as well as a link to the
4//! Discord documentation for the event.
5
6// Just for MessageUpdateEvent (for some reason the #[allow] doesn't work when placed directly)
7#![allow(clippy::option_option)]
8
9use serde::de::Error as DeError;
10use serde::Serialize;
11
12use crate::constants::Opcode;
13use crate::model::prelude::*;
14use crate::model::utils::{
15    deserialize_val,
16    emojis,
17    members,
18    remove_from_map,
19    remove_from_map_opt,
20    stickers,
21};
22
23/// Requires no gateway intents.
24///
25/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#application-command-permissions-update).
26#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
27#[derive(Clone, Debug, Deserialize, Serialize)]
28#[serde(transparent)]
29#[non_exhaustive]
30pub struct CommandPermissionsUpdateEvent {
31    pub permission: CommandPermissions,
32}
33
34/// Requires [`GatewayIntents::AUTO_MODERATION_CONFIGURATION`].
35///
36/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-create).
37#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
38#[derive(Clone, Debug, Deserialize, Serialize)]
39#[serde(transparent)]
40#[non_exhaustive]
41pub struct AutoModRuleCreateEvent {
42    pub rule: Rule,
43}
44
45/// Requires [`GatewayIntents::AUTO_MODERATION_CONFIGURATION`].
46///
47/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-update).
48#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
49#[derive(Clone, Debug, Deserialize, Serialize)]
50#[serde(transparent)]
51#[non_exhaustive]
52pub struct AutoModRuleUpdateEvent {
53    pub rule: Rule,
54}
55
56/// Requires [`GatewayIntents::AUTO_MODERATION_CONFIGURATION`].
57///
58/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-delete).
59#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
60#[derive(Clone, Debug, Deserialize, Serialize)]
61#[serde(transparent)]
62#[non_exhaustive]
63pub struct AutoModRuleDeleteEvent {
64    pub rule: Rule,
65}
66
67/// Requires [`GatewayIntents::AUTO_MODERATION_EXECUTION`].
68///
69/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#auto-moderation-action-execution).
70#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
71#[derive(Clone, Debug, Deserialize, Serialize)]
72#[serde(transparent)]
73#[non_exhaustive]
74pub struct AutoModActionExecutionEvent {
75    pub execution: ActionExecution,
76}
77
78/// Event data for the channel creation event.
79///
80/// This is fired when:
81/// - A [`Channel`] is created in a [`Guild`]
82///
83/// Requires [`GatewayIntents::GUILDS`].
84///
85/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#channel-create).
86#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
87#[derive(Clone, Debug, Deserialize, Serialize)]
88#[serde(transparent)]
89#[non_exhaustive]
90pub struct ChannelCreateEvent {
91    /// The channel that was created.
92    pub channel: GuildChannel,
93}
94
95/// Requires [`GatewayIntents::GUILDS`].
96///
97/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#channel-delete).
98#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
99#[derive(Clone, Debug, Deserialize, Serialize)]
100#[serde(transparent)]
101#[non_exhaustive]
102pub struct ChannelDeleteEvent {
103    pub channel: GuildChannel,
104}
105
106/// Requires [`GatewayIntents::GUILDS`] or [`GatewayIntents::DIRECT_MESSAGES`].
107///
108/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#channel-pins-update).
109#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
110#[derive(Clone, Debug, Deserialize, Serialize)]
111#[non_exhaustive]
112pub struct ChannelPinsUpdateEvent {
113    pub guild_id: Option<GuildId>,
114    pub channel_id: ChannelId,
115    pub last_pin_timestamp: Option<Timestamp>,
116}
117
118/// Requires [`GatewayIntents::GUILDS`].
119///
120/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#channel-update).
121#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
122#[derive(Clone, Debug, Deserialize, Serialize)]
123#[serde(transparent)]
124#[non_exhaustive]
125pub struct ChannelUpdateEvent {
126    pub channel: GuildChannel,
127}
128
129/// Requires [`GatewayIntents::GUILD_MODERATION`] and [`Permissions::VIEW_AUDIT_LOG`].
130///
131/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-audit-log-entry-create).
132#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
133#[derive(Clone, Debug, Deserialize, Serialize)]
134#[non_exhaustive]
135pub struct GuildAuditLogEntryCreateEvent {
136    pub guild_id: GuildId,
137    #[serde(flatten)]
138    pub entry: AuditLogEntry,
139}
140
141/// Requires [`GatewayIntents::GUILD_MODERATION`].
142///
143/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-ban-add).
144#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
145#[derive(Clone, Debug, Deserialize, Serialize)]
146#[non_exhaustive]
147pub struct GuildBanAddEvent {
148    pub guild_id: GuildId,
149    pub user: User,
150}
151
152/// Requires [`GatewayIntents::GUILD_MODERATION`].
153///
154/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-ban-remove).
155#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
156#[derive(Clone, Debug, Deserialize, Serialize)]
157#[non_exhaustive]
158pub struct GuildBanRemoveEvent {
159    pub guild_id: GuildId,
160    pub user: User,
161}
162
163/// Requires [`GatewayIntents::GUILDS`].
164///
165/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-create).
166#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
167#[derive(Clone, Debug, Serialize)]
168#[serde(transparent)]
169#[non_exhaustive]
170pub struct GuildCreateEvent {
171    pub guild: Guild,
172}
173
174// Manual impl needed to insert guild_id fields in GuildChannel, Member, Role
175impl<'de> Deserialize<'de> for GuildCreateEvent {
176    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
177        let mut guild: Guild = Guild::deserialize(deserializer)?;
178        guild.channels.values_mut().for_each(|x| x.guild_id = guild.id);
179        guild.members.values_mut().for_each(|x| x.guild_id = guild.id);
180        guild.roles.values_mut().for_each(|x| x.guild_id = guild.id);
181        Ok(Self {
182            guild,
183        })
184    }
185}
186
187/// Requires [`GatewayIntents::GUILDS`].
188///
189/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-delete).
190#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
191#[derive(Clone, Debug, Deserialize, Serialize)]
192#[serde(transparent)]
193#[non_exhaustive]
194pub struct GuildDeleteEvent {
195    pub guild: UnavailableGuild,
196}
197
198/// Requires [`GatewayIntents::GUILD_EMOJIS_AND_STICKERS`].
199///
200/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-emojis-update).
201#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
202#[derive(Clone, Debug, Deserialize, Serialize)]
203#[non_exhaustive]
204pub struct GuildEmojisUpdateEvent {
205    #[serde(with = "emojis")]
206    pub emojis: HashMap<EmojiId, Emoji>,
207    pub guild_id: GuildId,
208}
209
210/// Requires [`GatewayIntents::GUILD_INTEGRATIONS`].
211///
212/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-integrations-update).
213#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
214#[derive(Clone, Debug, Deserialize, Serialize)]
215#[non_exhaustive]
216pub struct GuildIntegrationsUpdateEvent {
217    pub guild_id: GuildId,
218}
219
220/// Requires [`GatewayIntents::GUILD_MEMBERS`].
221///
222/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-member-add).
223#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
224#[derive(Clone, Debug, Deserialize, Serialize)]
225#[serde(transparent)]
226#[non_exhaustive]
227pub struct GuildMemberAddEvent {
228    pub member: Member,
229}
230
231/// Requires [`GatewayIntents::GUILD_MEMBERS`].
232///
233/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-member-remove).
234#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
235#[derive(Clone, Debug, Deserialize, Serialize)]
236#[non_exhaustive]
237pub struct GuildMemberRemoveEvent {
238    pub guild_id: GuildId,
239    pub user: User,
240}
241
242/// Requires [`GatewayIntents::GUILD_MEMBERS`].
243///
244/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-member-update).
245#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
246#[derive(Clone, Debug, Deserialize, Serialize)]
247#[non_exhaustive]
248pub struct GuildMemberUpdateEvent {
249    pub guild_id: GuildId,
250    pub nick: Option<String>,
251    pub joined_at: Timestamp,
252    pub roles: Vec<RoleId>,
253    pub user: User,
254    pub premium_since: Option<Timestamp>,
255    #[serde(default)]
256    pub pending: bool,
257    #[serde(default)]
258    pub deaf: bool,
259    #[serde(default)]
260    pub mute: bool,
261    pub avatar: Option<ImageHash>,
262    pub communication_disabled_until: Option<Timestamp>,
263    pub unusual_dm_activity_until: Option<Timestamp>,
264}
265
266/// Requires no gateway intents.
267///
268/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-members-chunk).
269#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
270#[derive(Clone, Debug, Deserialize, Serialize)]
271#[serde(remote = "Self")]
272#[non_exhaustive]
273pub struct GuildMembersChunkEvent {
274    /// ID of the guild.
275    pub guild_id: GuildId,
276    /// Set of guild members.
277    #[serde(with = "members")]
278    pub members: HashMap<UserId, Member>,
279    /// Chunk index in the expected chunks for this response (0 <= chunk_index < chunk_count).
280    pub chunk_index: u32,
281    /// Total number of expected chunks for this response.
282    pub chunk_count: u32,
283    /// When passing an invalid ID to [`crate::gateway::ShardRunnerMessage::ChunkGuild`], it will
284    /// be returned here.
285    #[serde(default)]
286    pub not_found: Vec<GenericId>,
287    /// When passing true to [`crate::gateway::ShardRunnerMessage::ChunkGuild`], presences of the
288    /// returned members will be here.
289    pub presences: Option<Vec<Presence>>,
290    /// Nonce used in the [`crate::gateway::ShardRunnerMessage::ChunkGuild`] request.
291    pub nonce: Option<String>,
292}
293
294// Manual impl needed to insert guild_id fields in Member
295impl<'de> Deserialize<'de> for GuildMembersChunkEvent {
296    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
297        let mut event = Self::deserialize(deserializer)?; // calls #[serde(remote)]-generated inherent method
298        event.members.values_mut().for_each(|m| m.guild_id = event.guild_id);
299        Ok(event)
300    }
301}
302
303impl Serialize for GuildMembersChunkEvent {
304    fn serialize<S: serde::Serializer>(&self, serializer: S) -> StdResult<S::Ok, S::Error> {
305        Self::serialize(self, serializer) // calls #[serde(remote)]-generated inherent method
306    }
307}
308
309/// Helper to deserialize `GuildRoleCreateEvent` and `GuildRoleUpdateEvent`.
310#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
311#[derive(Deserialize)]
312struct RoleEventHelper {
313    guild_id: GuildId,
314    role: Role,
315}
316
317/// Requires [`GatewayIntents::GUILDS`].
318///
319/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-role-create).
320#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
321#[derive(Clone, Debug, Serialize)]
322#[non_exhaustive]
323pub struct GuildRoleCreateEvent {
324    pub role: Role,
325}
326
327// Manual impl needed to insert guild_id field in Role
328impl<'de> Deserialize<'de> for GuildRoleCreateEvent {
329    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
330        let mut event = RoleEventHelper::deserialize(deserializer)?;
331        event.role.guild_id = event.guild_id;
332        Ok(Self {
333            role: event.role,
334        })
335    }
336}
337
338/// Requires [`GatewayIntents::GUILDS`].
339///
340/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-role-delete).
341#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
342#[derive(Clone, Debug, Deserialize, Serialize)]
343#[non_exhaustive]
344pub struct GuildRoleDeleteEvent {
345    pub guild_id: GuildId,
346    pub role_id: RoleId,
347}
348
349/// Requires [`GatewayIntents::GUILDS`].
350///
351/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-role-update).
352#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
353#[derive(Clone, Debug, Serialize)]
354#[non_exhaustive]
355pub struct GuildRoleUpdateEvent {
356    pub role: Role,
357}
358
359// Manual impl needed to insert guild_id field in Role
360impl<'de> Deserialize<'de> for GuildRoleUpdateEvent {
361    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
362        let mut event = RoleEventHelper::deserialize(deserializer)?;
363        event.role.guild_id = event.guild_id;
364        Ok(Self {
365            role: event.role,
366        })
367    }
368}
369
370/// Requires [`GatewayIntents::GUILD_EMOJIS_AND_STICKERS`].
371///
372/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-stickers-update).
373#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
374#[derive(Clone, Debug, Deserialize, Serialize)]
375#[non_exhaustive]
376pub struct GuildStickersUpdateEvent {
377    #[serde(with = "stickers")]
378    pub stickers: HashMap<StickerId, Sticker>,
379    pub guild_id: GuildId,
380}
381
382/// Requires [`GatewayIntents::GUILD_INVITES`] and [`Permissions::MANAGE_CHANNELS´] permission.
383///
384/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#invite-create).
385#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
386#[derive(Clone, Debug, Deserialize, Serialize)]
387#[non_exhaustive]
388pub struct InviteCreateEvent {
389    /// Whether or not the invite is temporary (invited users will be kicked on disconnect unless
390    /// Channel the invite is for.
391    pub channel_id: ChannelId,
392    /// Unique invite [code](Invite::code).
393    pub code: String,
394    /// Time at which the invite was created.
395    pub created_at: Timestamp,
396    /// Guild of the invite.
397    pub guild_id: Option<GuildId>,
398    /// User that created the invite.
399    pub inviter: Option<User>,
400    /// How long the invite is valid for (in seconds).
401    pub max_age: u32,
402    /// Maximum number of times the invite can be used.
403    pub max_uses: u8,
404    /// Type of target for this voice channel invite.
405    pub target_type: Option<InviteTargetType>,
406    /// User whose stream to display for this voice channel stream invite.
407    pub target_user: Option<User>,
408    /// Embedded application to open for this voice channel embedded application invite.
409    pub target_application: Option<Value>,
410    /// they're assigned a role).
411    pub temporary: bool,
412    /// How many times the invite has been used (always will be 0).
413    pub uses: u64,
414}
415
416/// Requires [`GatewayIntents::GUILD_INVITES`] and [`Permissions::MANAGE_CHANNELS´] permission.
417///
418/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#invite-delete).
419#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
420#[derive(Clone, Debug, Deserialize, Serialize)]
421#[non_exhaustive]
422pub struct InviteDeleteEvent {
423    pub channel_id: ChannelId,
424    pub guild_id: Option<GuildId>,
425    pub code: String,
426}
427
428/// Requires [`GatewayIntents::GUILDS`].
429///
430/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-update).
431#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
432#[derive(Clone, Debug, Deserialize, Serialize)]
433#[serde(transparent)]
434#[non_exhaustive]
435pub struct GuildUpdateEvent {
436    /// GuildUpdateEvent doesn't have GuildCreate's extra fields, so this is a partial guild
437    pub guild: PartialGuild,
438}
439
440/// Requires [`GatewayIntents::GUILD_MESSAGES`] or [`GatewayIntents::DIRECT_MESSAGES`].
441///
442/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-create).
443#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
444#[derive(Clone, Debug, Deserialize, Serialize)]
445#[serde(transparent)]
446#[non_exhaustive]
447pub struct MessageCreateEvent {
448    pub message: Message,
449}
450
451/// Requires [`GatewayIntents::GUILD_MESSAGES`] or [`GatewayIntents::DIRECT_MESSAGES`].
452///
453/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-delete-bulk).
454#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
455#[derive(Clone, Debug, Deserialize, Serialize)]
456#[non_exhaustive]
457pub struct MessageDeleteBulkEvent {
458    pub guild_id: Option<GuildId>,
459    pub channel_id: ChannelId,
460    pub ids: Vec<MessageId>,
461}
462
463/// Requires [`GatewayIntents::GUILD_MESSAGES`] or [`GatewayIntents::DIRECT_MESSAGES`].
464///
465/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-delete).
466#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
467#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
468#[non_exhaustive]
469pub struct MessageDeleteEvent {
470    pub guild_id: Option<GuildId>,
471    pub channel_id: ChannelId,
472    #[serde(rename = "id")]
473    pub message_id: MessageId,
474}
475
476// Any value that is present is considered Some value, including null.
477// Taken from https://github.com/serde-rs/serde/issues/984#issuecomment-314143738
478fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
479where
480    T: Deserialize<'de>,
481    D: Deserializer<'de>,
482{
483    Deserialize::deserialize(deserializer).map(Some)
484}
485
486/// Requires [`GatewayIntents::GUILD_MESSAGES`].
487///
488/// Contains identical fields to [`Message`], except everything but `id` and `channel_id` are
489/// optional. Even fields that cannot change in a message update event are included, because Discord
490/// may include them anyways, independent from whether they have actually changed (like
491/// [`Self::guild_id`])
492///
493/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-update).
494#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
495#[derive(Clone, Debug, Deserialize, Serialize)]
496#[non_exhaustive]
497pub struct MessageUpdateEvent {
498    pub id: MessageId,
499    pub channel_id: ChannelId,
500    pub author: Option<User>,
501    pub content: Option<String>,
502    pub timestamp: Option<Timestamp>,
503    pub edited_timestamp: Option<Timestamp>,
504    pub tts: Option<bool>,
505    pub mention_everyone: Option<bool>,
506    pub mentions: Option<Vec<User>>,
507    pub mention_roles: Option<Vec<RoleId>>,
508    pub mention_channels: Option<Vec<ChannelMention>>,
509    pub attachments: Option<Vec<Attachment>>,
510    pub embeds: Option<Vec<Embed>>,
511    pub reactions: Option<Vec<MessageReaction>>,
512    pub pinned: Option<bool>,
513    #[serde(default, deserialize_with = "deserialize_some")]
514    pub webhook_id: Option<Option<WebhookId>>,
515    #[serde(rename = "type")]
516    pub kind: Option<MessageType>,
517    #[serde(default, deserialize_with = "deserialize_some")]
518    pub activity: Option<Option<MessageActivity>>,
519    #[serde(default, deserialize_with = "deserialize_some")]
520    pub application: Option<Option<MessageApplication>>,
521    #[serde(default, deserialize_with = "deserialize_some")]
522    pub application_id: Option<Option<ApplicationId>>,
523    pub message_reference: Option<Option<MessageReference>>,
524    #[serde(default, deserialize_with = "deserialize_some")]
525    pub flags: Option<Option<MessageFlags>>,
526    #[serde(default, deserialize_with = "deserialize_some")]
527    pub referenced_message: Option<Option<Box<Message>>>,
528    #[cfg_attr(not(ignore_serenity_deprecated), deprecated = "Use interaction_metadata")]
529    #[serde(default, deserialize_with = "deserialize_some")]
530    pub interaction: Option<Option<Box<MessageInteraction>>>,
531    pub interaction_metadata: Option<Option<Box<MessageInteractionMetadata>>>,
532    #[serde(default, deserialize_with = "deserialize_some")]
533    pub thread: Option<Option<GuildChannel>>,
534    pub components: Option<Vec<ActionRow>>,
535    pub sticker_items: Option<Vec<StickerItem>>,
536    pub position: Option<Option<u64>>,
537    pub role_subscription_data: Option<Option<RoleSubscriptionData>>,
538    pub guild_id: Option<GuildId>,
539    pub member: Option<Option<Box<PartialMember>>>,
540}
541
542impl MessageUpdateEvent {
543    #[allow(clippy::clone_on_copy)] // For consistency between fields
544    #[rustfmt::skip]
545    /// Writes the updated data in this message update event into the given [`Message`].
546    pub fn apply_to_message(&self, message: &mut Message) {
547        // Destructure, so we get an `unused` warning when we forget to process one of the fields
548        // in this method
549        #[allow(deprecated)] // yes rust, exhaustive means exhaustive, even the deprecated ones
550        let Self {
551            id,
552            channel_id,
553            author,
554            content,
555            timestamp,
556            edited_timestamp,
557            tts,
558            mention_everyone,
559            mentions,
560            mention_roles,
561            mention_channels,
562            attachments,
563            embeds,
564            reactions,
565            pinned,
566            webhook_id,
567            kind,
568            activity,
569            application,
570            application_id,
571            message_reference,
572            flags,
573            referenced_message,
574            interaction,
575            interaction_metadata,
576            thread,
577            components,
578            sticker_items,
579            position,
580            role_subscription_data,
581            guild_id,
582            member,
583        } = self;
584
585        // Discord won't send a MessageUpdateEvent with a different MessageId and ChannelId than we
586        // already have. But let's set the fields anyways, in case the user calls this method with
587        // a self-constructed MessageUpdateEvent that does change these fields.
588        message.id = *id;
589        message.channel_id = *channel_id;
590
591        if let Some(x) = author { message.author = x.clone() }
592        if let Some(x) = content { message.content.clone_from(x) }
593        if let Some(x) = timestamp { message.timestamp = x.clone() }
594        message.edited_timestamp = *edited_timestamp;
595        if let Some(x) = tts { message.tts = x.clone() }
596        if let Some(x) = mention_everyone { message.mention_everyone = x.clone() }
597        if let Some(x) = mentions { message.mentions.clone_from(x) }
598        if let Some(x) = mention_roles { message.mention_roles.clone_from(x) }
599        if let Some(x) = mention_channels { message.mention_channels.clone_from(x) }
600        if let Some(x) = attachments { message.attachments.clone_from(x) }
601        if let Some(x) = embeds { message.embeds.clone_from(x) }
602        if let Some(x) = reactions { message.reactions.clone_from(x) }
603        if let Some(x) = pinned { message.pinned = x.clone() }
604        if let Some(x) = webhook_id { message.webhook_id.clone_from(x) }
605        if let Some(x) = kind { message.kind = x.clone() }
606        if let Some(x) = activity { message.activity.clone_from(x) }
607        if let Some(x) = application { message.application.clone_from(x) }
608        if let Some(x) = application_id { message.application_id.clone_from(x) }
609        if let Some(x) = message_reference { message.message_reference.clone_from(x) }
610        if let Some(x) = flags { message.flags.clone_from(x) }
611        if let Some(x) = referenced_message { message.referenced_message.clone_from(x) }
612        if let Some(x) = interaction { message.interaction.clone_from(x) }
613        if let Some(x) = interaction_metadata { message.interaction_metadata.clone_from(x) }
614        if let Some(x) = thread { message.thread.clone_from(x) }
615        if let Some(x) = components { message.components.clone_from(x) }
616        if let Some(x) = sticker_items { message.sticker_items.clone_from(x) }
617        if let Some(x) = position { message.position.clone_from(x) }
618        if let Some(x) = role_subscription_data { message.role_subscription_data.clone_from(x) }
619        message.guild_id = *guild_id;
620        if let Some(x) = member { message.member.clone_from(x) }
621    }
622}
623
624/// Requires [`GatewayIntents::GUILD_PRESENCES`].
625///
626/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#presence-update).
627#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
628#[derive(Clone, Debug, Deserialize, Serialize)]
629#[serde(transparent)]
630#[non_exhaustive]
631pub struct PresenceUpdateEvent {
632    pub presence: Presence,
633}
634
635/// Not officially documented.
636#[cfg_attr(not(ignore_serenity_deprecated), deprecated = "This event doesn't exist")]
637#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
638#[derive(Clone, Debug, Deserialize, Serialize)]
639#[serde(transparent)]
640#[non_exhaustive]
641pub struct PresencesReplaceEvent {
642    pub presences: Vec<Presence>,
643}
644
645/// Requires [`GatewayIntents::GUILD_MESSAGE_REACTIONS`] or
646/// [`GatewayIntents::DIRECT_MESSAGE_REACTIONS`].
647///
648/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-reaction-add).
649#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
650#[derive(Clone, Debug, Deserialize, Serialize)]
651#[serde(transparent)]
652#[non_exhaustive]
653pub struct ReactionAddEvent {
654    pub reaction: Reaction,
655}
656
657/// Requires [`GatewayIntents::GUILD_MESSAGE_REACTIONS`] or
658/// [`GatewayIntents::DIRECT_MESSAGE_REACTIONS`].
659///
660/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-reaction-remove).
661#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
662#[derive(Clone, Debug, Deserialize, Serialize)]
663#[serde(transparent)]
664#[non_exhaustive]
665pub struct ReactionRemoveEvent {
666    // The Discord API doesn't share the same schema for Reaction Remove Event and Reaction Add
667    // Event (which [`Reaction`] is), but the two currently match up well enough, so re-using the
668    // [`Reaction`] struct here is fine.
669    pub reaction: Reaction,
670}
671
672/// Requires [`GatewayIntents::GUILD_MESSAGE_REACTIONS`] or
673/// [`GatewayIntents::DIRECT_MESSAGE_REACTIONS`].
674///
675/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-reaction-remove-all).
676#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
677#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
678#[non_exhaustive]
679pub struct ReactionRemoveAllEvent {
680    pub channel_id: ChannelId,
681    pub message_id: MessageId,
682    pub guild_id: Option<GuildId>,
683}
684
685/// Requires [`GatewayIntents::GUILD_MESSAGE_REACTIONS`] or
686/// [`GatewayIntents::DIRECT_MESSAGE_REACTIONS`].
687///
688/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-reaction-remove-emoji-message-reaction-remove-emoji-event-fields).
689#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
690#[derive(Clone, Debug, Deserialize, Serialize)]
691#[serde(transparent)]
692#[non_exhaustive]
693pub struct ReactionRemoveEmojiEvent {
694    pub reaction: Reaction,
695}
696
697/// The "Ready" event, containing initial ready cache
698///
699/// Requires no gateway intents.
700///
701/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#ready).
702#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
703#[derive(Clone, Debug, Deserialize, Serialize)]
704#[serde(transparent)]
705#[non_exhaustive]
706pub struct ReadyEvent {
707    pub ready: Ready,
708}
709
710/// Requires no gateway intents.
711///
712/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#resumed).
713#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
714#[derive(Clone, Debug, Deserialize, Serialize)]
715#[non_exhaustive]
716pub struct ResumedEvent {}
717
718/// Requires [`GatewayIntents::GUILD_MESSAGE_TYPING`] or [`GatewayIntents::DIRECT_MESSAGE_TYPING`].
719///
720/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#typing-start).
721#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
722#[derive(Clone, Debug, Deserialize, Serialize)]
723#[non_exhaustive]
724pub struct TypingStartEvent {
725    /// ID of the channel.
726    pub channel_id: ChannelId,
727    /// ID of the guild.
728    pub guild_id: Option<GuildId>,
729    /// ID of the user.
730    pub user_id: UserId,
731    /// Timestamp of when the user started typing.
732    pub timestamp: u64,
733    /// Member who started typing if this happened in a guild.
734    pub member: Option<Member>,
735}
736
737#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
738#[derive(Clone, Debug, Deserialize, Serialize)]
739#[non_exhaustive]
740pub struct UnknownEvent {
741    #[serde(rename = "t")]
742    pub kind: String,
743    #[serde(rename = "d")]
744    pub value: Value,
745}
746
747/// Sent when properties about the current bot's user change.
748///
749/// Requires no gateway intents.
750///
751/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#user-update).
752#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
753#[derive(Clone, Debug, Deserialize, Serialize)]
754#[serde(transparent)]
755#[non_exhaustive]
756pub struct UserUpdateEvent {
757    pub current_user: CurrentUser,
758}
759
760/// Requires no gateway intents.
761///
762/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#voice-server-update).
763#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
764#[derive(Clone, Debug, Deserialize, Serialize)]
765#[non_exhaustive]
766pub struct VoiceServerUpdateEvent {
767    pub token: String,
768    pub guild_id: Option<GuildId>,
769    pub endpoint: Option<String>,
770}
771
772/// Requires [`GatewayIntents::GUILD_VOICE_STATES`].
773///
774/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#voice-state-update).
775#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
776#[derive(Clone, Debug, Deserialize, Serialize)]
777#[serde(transparent)]
778#[non_exhaustive]
779pub struct VoiceStateUpdateEvent {
780    pub voice_state: VoiceState,
781}
782
783/// Requires [`GatewayIntents::GUILDS`].
784///
785/// [Incomplete documentation](https://github.com/discord/discord-api-docs/pull/6398)
786#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
787#[derive(Clone, Debug, Deserialize, Serialize)]
788#[non_exhaustive]
789pub struct VoiceChannelStatusUpdateEvent {
790    pub status: Option<String>,
791    pub id: ChannelId,
792    pub guild_id: GuildId,
793}
794
795/// Requires [`GatewayIntents::GUILD_WEBHOOKS`].
796///
797/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#webhooks-update).
798#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
799#[derive(Clone, Debug, Deserialize, Serialize)]
800#[non_exhaustive]
801pub struct WebhookUpdateEvent {
802    pub channel_id: ChannelId,
803    pub guild_id: GuildId,
804}
805
806/// Requires no gateway intents.
807///
808/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#interaction-create).
809#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
810#[derive(Clone, Debug, Deserialize, Serialize)]
811#[serde(transparent)]
812#[non_exhaustive]
813pub struct InteractionCreateEvent {
814    pub interaction: Interaction,
815}
816
817/// Requires [`GatewayIntents::GUILD_INTEGRATIONS`].
818///
819/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#integration-create).
820#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
821#[derive(Clone, Debug, Deserialize, Serialize)]
822#[serde(transparent)]
823#[non_exhaustive]
824pub struct IntegrationCreateEvent {
825    pub integration: Integration,
826}
827
828/// Requires [`GatewayIntents::GUILD_INTEGRATIONS`].
829///
830/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#integration-update).
831#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
832#[derive(Clone, Debug, Deserialize, Serialize)]
833#[serde(transparent)]
834#[non_exhaustive]
835pub struct IntegrationUpdateEvent {
836    pub integration: Integration,
837}
838
839/// Requires [`GatewayIntents::GUILD_INTEGRATIONS`].
840///
841/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#integration-delete).
842#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
843#[derive(Clone, Debug, Serialize, Deserialize)]
844#[non_exhaustive]
845pub struct IntegrationDeleteEvent {
846    pub id: IntegrationId,
847    pub guild_id: GuildId,
848    pub application_id: Option<ApplicationId>,
849}
850
851/// Requires [`GatewayIntents::GUILDS`].
852///
853/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#stage-instance-create).
854#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
855#[derive(Clone, Debug, Deserialize, Serialize)]
856#[serde(transparent)]
857#[non_exhaustive]
858pub struct StageInstanceCreateEvent {
859    pub stage_instance: StageInstance,
860}
861
862/// Requires [`GatewayIntents::GUILDS`].
863///
864/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#stage-instance-update).
865#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
866#[derive(Clone, Debug, Deserialize, Serialize)]
867#[serde(transparent)]
868#[non_exhaustive]
869pub struct StageInstanceUpdateEvent {
870    pub stage_instance: StageInstance,
871}
872
873/// Requires [`GatewayIntents::GUILDS`].
874///
875/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#stage-instance-delete).
876#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
877#[derive(Clone, Debug, Deserialize, Serialize)]
878#[serde(transparent)]
879#[non_exhaustive]
880pub struct StageInstanceDeleteEvent {
881    pub stage_instance: StageInstance,
882}
883
884/// Requires [`GatewayIntents::GUILDS`].
885///
886/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#thread-create).
887#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
888#[derive(Clone, Debug, Deserialize, Serialize)]
889#[serde(transparent)]
890#[non_exhaustive]
891pub struct ThreadCreateEvent {
892    pub thread: GuildChannel,
893}
894
895/// Requires [`GatewayIntents::GUILDS`].
896///
897/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#thread-update).
898#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
899#[derive(Clone, Debug, Deserialize, Serialize)]
900#[serde(transparent)]
901#[non_exhaustive]
902pub struct ThreadUpdateEvent {
903    pub thread: GuildChannel,
904}
905
906/// Requires [`GatewayIntents::GUILDS`].
907///
908/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#thread-delete).
909#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
910#[derive(Clone, Debug, Deserialize, Serialize)]
911#[serde(transparent)]
912#[non_exhaustive]
913pub struct ThreadDeleteEvent {
914    pub thread: PartialGuildChannel,
915}
916
917/// Requires [`GatewayIntents::GUILDS`].
918///
919/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#thread-list-sync).
920#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
921#[derive(Clone, Debug, Deserialize, Serialize)]
922#[non_exhaustive]
923pub struct ThreadListSyncEvent {
924    /// The guild Id.
925    pub guild_id: GuildId,
926    /// The parent channel Id whose threads are being synced. If omitted, then threads were synced
927    /// for the entire guild. This array may contain channel Ids that have no active threads as
928    /// well, so you know to clear that data.
929    pub channel_ids: Option<Vec<ChannelId>>,
930    /// All active threads in the given channels that the current user can access.
931    pub threads: Vec<GuildChannel>,
932    /// All thread member objects from the synced threads for the current user, indicating which
933    /// threads the current user has been added to
934    pub members: Vec<ThreadMember>,
935}
936
937/// Requires [`GatewayIntents::GUILDS`], and, to receive this event for other users,
938/// [`GatewayIntents::GUILD_MEMBERS`].
939///
940/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#thread-member-update).
941#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
942#[derive(Clone, Debug, Deserialize, Serialize)]
943#[serde(transparent)]
944#[non_exhaustive]
945pub struct ThreadMemberUpdateEvent {
946    pub member: ThreadMember,
947}
948
949/// Requires [`GatewayIntents::GUILD_MEMBERS`].
950///
951/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#thread-members-update).
952#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
953#[derive(Clone, Debug, Deserialize, Serialize)]
954#[non_exhaustive]
955pub struct ThreadMembersUpdateEvent {
956    /// The id of the thread.
957    pub id: ChannelId,
958    /// The id of the Guild.
959    pub guild_id: GuildId,
960    /// The approximate number of members in the thread, capped at 50.
961    ///
962    /// NOTE: This count has been observed to be above 50, or below 0.
963    /// See: <https://github.com/discord/discord-api-docs/issues/5139>
964    pub member_count: i16,
965    /// The users who were added to the thread.
966    #[serde(default)]
967    pub added_members: Vec<ThreadMember>,
968    /// The ids of the users who were removed from the thread.
969    #[serde(default)]
970    pub removed_member_ids: Vec<UserId>,
971}
972
973/// Requires [`GatewayIntents::GUILD_SCHEDULED_EVENTS`].
974///
975/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-create).
976#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
977#[derive(Clone, Debug, Deserialize, Serialize)]
978#[serde(transparent)]
979#[non_exhaustive]
980pub struct GuildScheduledEventCreateEvent {
981    pub event: ScheduledEvent,
982}
983
984/// Requires [`GatewayIntents::GUILD_SCHEDULED_EVENTS`].
985///
986/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-update).
987#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
988#[derive(Clone, Debug, Deserialize, Serialize)]
989#[serde(transparent)]
990#[non_exhaustive]
991pub struct GuildScheduledEventUpdateEvent {
992    pub event: ScheduledEvent,
993}
994
995/// Requires [`GatewayIntents::GUILD_SCHEDULED_EVENTS`].
996///
997/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-delete).
998#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
999#[derive(Clone, Debug, Deserialize, Serialize)]
1000#[serde(transparent)]
1001#[non_exhaustive]
1002pub struct GuildScheduledEventDeleteEvent {
1003    pub event: ScheduledEvent,
1004}
1005
1006/// Requires [`GatewayIntents::GUILD_SCHEDULED_EVENTS`].
1007///
1008/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-user-add).
1009#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1010#[derive(Clone, Debug, Deserialize, Serialize)]
1011#[non_exhaustive]
1012pub struct GuildScheduledEventUserAddEvent {
1013    #[serde(rename = "guild_scheduled_event_id")]
1014    pub scheduled_event_id: ScheduledEventId,
1015    pub user_id: UserId,
1016    pub guild_id: GuildId,
1017}
1018
1019/// Requires [`GatewayIntents::GUILD_SCHEDULED_EVENTS`].
1020///
1021/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-user-remove).
1022#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1023#[derive(Clone, Debug, Deserialize, Serialize)]
1024#[non_exhaustive]
1025pub struct GuildScheduledEventUserRemoveEvent {
1026    #[serde(rename = "guild_scheduled_event_id")]
1027    pub scheduled_event_id: ScheduledEventId,
1028    pub user_id: UserId,
1029    pub guild_id: GuildId,
1030}
1031
1032/// Requires no gateway intents.
1033///
1034/// [Discord docs](https://discord.com/developers/docs/monetization/entitlements#new-entitlement)
1035#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1036#[derive(Clone, Debug, Deserialize, Serialize)]
1037#[serde(transparent)]
1038#[non_exhaustive]
1039pub struct EntitlementCreateEvent {
1040    pub entitlement: Entitlement,
1041}
1042
1043/// Requires no gateway intents.
1044///
1045/// [Discord docs](https://discord.com/developers/docs/monetization/entitlements#new-entitlement)
1046#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1047#[derive(Clone, Debug, Deserialize, Serialize)]
1048#[serde(transparent)]
1049#[non_exhaustive]
1050pub struct EntitlementUpdateEvent {
1051    pub entitlement: Entitlement,
1052}
1053
1054/// Requires no gateway intents.
1055///
1056/// [Discord docs](https://discord.com/developers/docs/monetization/entitlements#new-entitlement)
1057#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1058#[derive(Clone, Debug, Deserialize, Serialize)]
1059#[serde(transparent)]
1060#[non_exhaustive]
1061pub struct EntitlementDeleteEvent {
1062    pub entitlement: Entitlement,
1063}
1064
1065/// Requires [`GatewayIntents::GUILD_MESSAGE_POLLS`] or [`GatewayIntents::DIRECT_MESSAGE_POLLS`].
1066///
1067/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-poll-vote-add)
1068#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1069#[derive(Clone, Debug, Deserialize, Serialize)]
1070#[non_exhaustive]
1071pub struct MessagePollVoteAddEvent {
1072    pub user_id: UserId,
1073    pub channel_id: ChannelId,
1074    pub message_id: MessageId,
1075    pub guild_id: Option<GuildId>,
1076    pub answer_id: AnswerId,
1077}
1078
1079/// Requires [`GatewayIntents::GUILD_MESSAGE_POLLS`] or [`GatewayIntents::DIRECT_MESSAGE_POLLS`].
1080///
1081/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-poll-vote-remove)
1082#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1083#[derive(Clone, Debug, Deserialize, Serialize)]
1084#[non_exhaustive]
1085pub struct MessagePollVoteRemoveEvent {
1086    pub user_id: UserId,
1087    pub channel_id: ChannelId,
1088    pub message_id: MessageId,
1089    pub guild_id: Option<GuildId>,
1090    pub answer_id: AnswerId,
1091}
1092
1093/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#payload-structure).
1094#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1095#[allow(clippy::large_enum_variant)]
1096#[derive(Debug, Clone, Serialize)]
1097#[non_exhaustive]
1098#[serde(untagged)]
1099pub enum GatewayEvent {
1100    Dispatch(u64, Event),
1101    Heartbeat(u64),
1102    Reconnect,
1103    /// Whether the session can be resumed.
1104    InvalidateSession(bool),
1105    Hello(u64),
1106    HeartbeatAck,
1107}
1108
1109// Manual impl needed to emulate integer enum tags
1110impl<'de> Deserialize<'de> for GatewayEvent {
1111    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
1112        let mut map = JsonMap::deserialize(deserializer)?;
1113        let seq = remove_from_map_opt(&mut map, "s")?.flatten();
1114
1115        Ok(match remove_from_map(&mut map, "op")? {
1116            Opcode::Dispatch => Self::Dispatch(
1117                seq.ok_or_else(|| DeError::missing_field("s"))?,
1118                deserialize_val(Value::from(map))?,
1119            ),
1120            Opcode::Heartbeat => {
1121                GatewayEvent::Heartbeat(seq.ok_or_else(|| DeError::missing_field("s"))?)
1122            },
1123            Opcode::InvalidSession => {
1124                GatewayEvent::InvalidateSession(remove_from_map(&mut map, "d")?)
1125            },
1126            Opcode::Hello => {
1127                #[derive(Deserialize)]
1128                struct HelloPayload {
1129                    heartbeat_interval: u64,
1130                }
1131
1132                let inner: HelloPayload = remove_from_map(&mut map, "d")?;
1133                GatewayEvent::Hello(inner.heartbeat_interval)
1134            },
1135            Opcode::Reconnect => GatewayEvent::Reconnect,
1136            Opcode::HeartbeatAck => GatewayEvent::HeartbeatAck,
1137            _ => return Err(DeError::custom("invalid opcode")),
1138        })
1139    }
1140}
1141
1142/// Event received over a websocket connection
1143///
1144/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#receive-events).
1145#[allow(clippy::large_enum_variant)]
1146#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
1147#[derive(Clone, Debug, Deserialize, Serialize)]
1148#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
1149#[serde(tag = "t", content = "d")]
1150#[non_exhaustive]
1151pub enum Event {
1152    /// The permissions of an [`Command`] was changed.
1153    ///
1154    /// Fires the [`EventHandler::command_permissions_update`] event.
1155    ///
1156    /// [`Command`]: crate::model::application::Command
1157    /// [`EventHandler::command_permissions_update`]: crate::client::EventHandler::command_permissions_update
1158    #[serde(rename = "APPLICATION_COMMAND_PERMISSIONS_UPDATE")]
1159    CommandPermissionsUpdate(CommandPermissionsUpdateEvent),
1160    /// A [`Rule`] was created.
1161    ///
1162    /// Fires the [`EventHandler::auto_moderation_rule_create`] event.
1163    ///
1164    /// [`EventHandler::auto_moderation_rule_create`]:
1165    /// crate::client::EventHandler::auto_moderation_rule_create
1166    #[serde(rename = "AUTO_MODERATION_RULE_CREATE")]
1167    AutoModRuleCreate(AutoModRuleCreateEvent),
1168    /// A [`Rule`] has been updated.
1169    ///
1170    /// Fires the [`EventHandler::auto_moderation_rule_update`] event.
1171    ///
1172    /// [`EventHandler::auto_moderation_rule_update`]:
1173    /// crate::client::EventHandler::auto_moderation_rule_update
1174    #[serde(rename = "AUTO_MODERATION_RULE_UPDATE")]
1175    AutoModRuleUpdate(AutoModRuleUpdateEvent),
1176    /// A [`Rule`] was deleted.
1177    ///
1178    /// Fires the [`EventHandler::auto_moderation_rule_delete`] event.
1179    ///
1180    /// [`EventHandler::auto_moderation_rule_delete`]:
1181    /// crate::client::EventHandler::auto_moderation_rule_delete
1182    #[serde(rename = "AUTO_MODERATION_RULE_DELETE")]
1183    AutoModRuleDelete(AutoModRuleDeleteEvent),
1184    /// A [`Rule`] was triggered and an action was executed.
1185    ///
1186    /// Fires the [`EventHandler::auto_moderation_action_execution`] event.
1187    ///
1188    /// [`EventHandler::auto_moderation_action_execution`]:
1189    /// crate::client::EventHandler::auto_moderation_action_execution
1190    #[serde(rename = "AUTO_MODERATION_ACTION_EXECUTION")]
1191    AutoModActionExecution(AutoModActionExecutionEvent),
1192    /// A [`Channel`] was created.
1193    ///
1194    /// Fires the [`EventHandler::channel_create`] event.
1195    ///
1196    /// [`EventHandler::channel_create`]: crate::client::EventHandler::channel_create
1197    ChannelCreate(ChannelCreateEvent),
1198    /// A [`Channel`] has been deleted.
1199    ///
1200    /// Fires the [`EventHandler::channel_delete`] event.
1201    ///
1202    /// [`EventHandler::channel_delete`]: crate::client::EventHandler::channel_delete
1203    ChannelDelete(ChannelDeleteEvent),
1204    /// The pins for a [`Channel`] have been updated.
1205    ///
1206    /// Fires the [`EventHandler::channel_pins_update`] event.
1207    ///
1208    /// [`EventHandler::channel_pins_update`]: crate::client::EventHandler::channel_pins_update
1209    ChannelPinsUpdate(ChannelPinsUpdateEvent),
1210    /// A [`Channel`] has been updated.
1211    ///
1212    /// Fires the [`EventHandler::channel_update`] event.
1213    ///
1214    /// [`EventHandler::channel_update`]: crate::client::EventHandler::channel_update
1215    ChannelUpdate(ChannelUpdateEvent),
1216    GuildAuditLogEntryCreate(GuildAuditLogEntryCreateEvent),
1217    GuildBanAdd(GuildBanAddEvent),
1218    GuildBanRemove(GuildBanRemoveEvent),
1219    GuildCreate(GuildCreateEvent),
1220    GuildDelete(GuildDeleteEvent),
1221    GuildEmojisUpdate(GuildEmojisUpdateEvent),
1222    GuildIntegrationsUpdate(GuildIntegrationsUpdateEvent),
1223    GuildMemberAdd(GuildMemberAddEvent),
1224    GuildMemberRemove(GuildMemberRemoveEvent),
1225    /// A member's roles have changed
1226    GuildMemberUpdate(GuildMemberUpdateEvent),
1227    GuildMembersChunk(GuildMembersChunkEvent),
1228    GuildRoleCreate(GuildRoleCreateEvent),
1229    GuildRoleDelete(GuildRoleDeleteEvent),
1230    GuildRoleUpdate(GuildRoleUpdateEvent),
1231    /// A [`Sticker`] was created, updated, or deleted
1232    GuildStickersUpdate(GuildStickersUpdateEvent),
1233    GuildUpdate(GuildUpdateEvent),
1234    /// An [`Invite`] was created.
1235    ///
1236    /// Fires the [`EventHandler::invite_create`] event handler.
1237    ///
1238    /// [`EventHandler::invite_create`]: crate::client::EventHandler::invite_create
1239    InviteCreate(InviteCreateEvent),
1240    /// An [`Invite`] was deleted.
1241    ///
1242    /// Fires the [`EventHandler::invite_delete`] event handler.
1243    ///
1244    /// [`EventHandler::invite_delete`]: crate::client::EventHandler::invite_delete
1245    InviteDelete(InviteDeleteEvent),
1246    MessageCreate(MessageCreateEvent),
1247    MessageDelete(MessageDeleteEvent),
1248    MessageDeleteBulk(MessageDeleteBulkEvent),
1249    /// A message has been edited, either by the user or the system
1250    MessageUpdate(MessageUpdateEvent),
1251    /// A member's presence state (or username or avatar) has changed
1252    PresenceUpdate(PresenceUpdateEvent),
1253    /// The presence list of the user's friends should be replaced entirely
1254    #[cfg_attr(not(ignore_serenity_deprecated), deprecated = "This event doesn't exist")]
1255    PresencesReplace(PresencesReplaceEvent),
1256    /// A reaction was added to a message.
1257    ///
1258    /// Fires the [`EventHandler::reaction_add`] event handler.
1259    ///
1260    /// [`EventHandler::reaction_add`]: crate::client::EventHandler::reaction_add
1261    #[serde(rename = "MESSAGE_REACTION_ADD")]
1262    ReactionAdd(ReactionAddEvent),
1263    /// A reaction was removed to a message.
1264    ///
1265    /// Fires the [`EventHandler::reaction_remove`] event handler.
1266    ///
1267    /// [`EventHandler::reaction_remove`]: crate::client::EventHandler::reaction_remove
1268    #[serde(rename = "MESSAGE_REACTION_REMOVE")]
1269    ReactionRemove(ReactionRemoveEvent),
1270    /// A request was issued to remove all [`Reaction`]s from a [`Message`].
1271    ///
1272    /// Fires the [`EventHandler::reaction_remove_all`] event handler.
1273    ///
1274    /// [`EventHandler::reaction_remove_all`]: crate::client::EventHandler::reaction_remove_all
1275    #[serde(rename = "MESSAGE_REACTION_REMOVE_ALL")]
1276    ReactionRemoveAll(ReactionRemoveAllEvent),
1277    /// Sent when a bot removes all instances of a given emoji from the reactions of a message.
1278    ///
1279    /// Fires the [`EventHandler::reaction_remove_emoji`] event handler.
1280    ///
1281    /// [`EventHandler::reaction_remove_emoji`]: crate::client::EventHandler::reaction_remove_emoji
1282    #[serde(rename = "MESSAGE_REACTION_REMOVE_EMOJI")]
1283    ReactionRemoveEmoji(ReactionRemoveEmojiEvent),
1284    /// The first event in a connection, containing the initial ready cache.
1285    ///
1286    /// May also be received at a later time in the event of a reconnect.
1287    Ready(ReadyEvent),
1288    /// The connection has successfully resumed after a disconnect.
1289    Resumed(ResumedEvent),
1290    /// A user is typing; considered to last 5 seconds
1291    TypingStart(TypingStartEvent),
1292    /// Update to the logged-in user's information
1293    UserUpdate(UserUpdateEvent),
1294    /// A member's voice state has changed
1295    VoiceStateUpdate(VoiceStateUpdateEvent),
1296    /// Voice server information is available
1297    VoiceServerUpdate(VoiceServerUpdateEvent),
1298    /// Fired when the status of a Voice Channel changes.
1299    VoiceChannelStatusUpdate(VoiceChannelStatusUpdateEvent),
1300    /// A webhook for a [channel][`GuildChannel`] was updated in a [`Guild`].
1301    #[serde(rename = "WEBHOOKS_UPDATE")]
1302    WebhookUpdate(WebhookUpdateEvent),
1303    /// An interaction was created.
1304    InteractionCreate(InteractionCreateEvent),
1305    /// A guild integration was created
1306    IntegrationCreate(IntegrationCreateEvent),
1307    /// A guild integration was updated
1308    IntegrationUpdate(IntegrationUpdateEvent),
1309    /// A guild integration was deleted
1310    IntegrationDelete(IntegrationDeleteEvent),
1311    /// A stage instance was created.
1312    StageInstanceCreate(StageInstanceCreateEvent),
1313    /// A stage instance was updated.
1314    StageInstanceUpdate(StageInstanceUpdateEvent),
1315    /// A stage instance was deleted.
1316    StageInstanceDelete(StageInstanceDeleteEvent),
1317    /// A thread was created or the current user was added
1318    /// to a private thread.
1319    ThreadCreate(ThreadCreateEvent),
1320    /// A thread was updated.
1321    ThreadUpdate(ThreadUpdateEvent),
1322    /// A thread was deleted.
1323    ThreadDelete(ThreadDeleteEvent),
1324    /// The current user gains access to a channel.
1325    ThreadListSync(ThreadListSyncEvent),
1326    /// The [`ThreadMember`] object for the current user is updated.
1327    ThreadMemberUpdate(ThreadMemberUpdateEvent),
1328    /// Anyone is added to or removed from a thread.
1329    ThreadMembersUpdate(ThreadMembersUpdateEvent),
1330    /// A scheduled event was created.
1331    GuildScheduledEventCreate(GuildScheduledEventCreateEvent),
1332    /// A scheduled event was updated.
1333    GuildScheduledEventUpdate(GuildScheduledEventUpdateEvent),
1334    /// A scheduled event was deleted.
1335    GuildScheduledEventDelete(GuildScheduledEventDeleteEvent),
1336    /// A guild member has subscribed to a scheduled event.
1337    GuildScheduledEventUserAdd(GuildScheduledEventUserAddEvent),
1338    /// A guild member has unsubscribed from a scheduled event.
1339    GuildScheduledEventUserRemove(GuildScheduledEventUserRemoveEvent),
1340    /// A user subscribed to a SKU.
1341    EntitlementCreate(EntitlementCreateEvent),
1342    /// A user's entitlement was updated or renewed.
1343    EntitlementUpdate(EntitlementUpdateEvent),
1344    /// A user's entitlement was deleted by Discord, or refunded.
1345    EntitlementDelete(EntitlementDeleteEvent),
1346    /// A user has voted on a Message Poll.
1347    MessagePollVoteAdd(MessagePollVoteAddEvent),
1348    /// A user has removed a previous vote on a Message Poll.
1349    MessagePollVoteRemove(MessagePollVoteRemoveEvent),
1350    /// An event type not covered by the above
1351    #[serde(untagged)]
1352    Unknown(UnknownEvent),
1353}
1354
1355impl Event {
1356    /// Return the event name of this event. Returns [`None`] if the event is
1357    /// [`Unknown`](Event::Unknown).
1358    #[must_use]
1359    pub fn name(&self) -> Option<String> {
1360        if let Self::Unknown(_) = self {
1361            None
1362        } else {
1363            let map = serde_json::to_value(self).ok()?;
1364            Some(map.get("t")?.as_str()?.to_string())
1365        }
1366    }
1367}