diff --git a/Cargo.toml b/Cargo.toml index f346a21..30dd107 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" tokio = {version = "1.27.0", features = ["rt", "macros", "rt-multi-thread"]} serde = {version = "1.0.159", features = ["derive"]} serde_json = "1.0.95" +serde-aux = "4.2.0" reqwest = {version = "0.11.16", features = ["multipart"]} url = "2.3.1" chrono = {version = "0.4.24", features = ["serde"]} diff --git a/src/api/types.rs b/src/api/types.rs index c87786b..7fc2207 100644 --- a/src/api/types.rs +++ b/src/api/types.rs @@ -4,9 +4,12 @@ https://discord.com/developers/docs . I do not feel like re-documenting all of this, as everything is already perfectly explained there. */ +use std::collections::HashMap; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use serde_json::from_value; +use serde_aux::field_attributes::deserialize_option_number_from_string; use crate::{api::limits::Limits, instance::Instance}; @@ -137,7 +140,7 @@ pub struct Error { #[derive(Serialize, Deserialize, Debug, Default)] pub struct UnavailableGuild { id: String, - unavailable: bool, + unavailable: Option, } /// See https://discord.com/developers/docs/resources/guild @@ -317,32 +320,35 @@ pub struct RoleObject { //pub tags: Option } -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)] pub struct UserObject { pub id: String, username: String, discriminator: String, avatar: Option, - bot: bool, + bot: Option, system: Option, mfa_enabled: Option, accent_color: Option, locale: Option, verified: Option, email: Option, - flags: String, + /// This field comes as either a string or a number as a string + /// So we need to account for that + #[serde(deserialize_with = "deserialize_option_number_from_string")] + flags: Option, premium_since: Option, - premium_type: i8, + premium_type: Option, pronouns: Option, - public_flags: Option, + public_flags: Option, banner: Option, - bio: String, + bio: Option, theme_colors: Option>, phone: Option, - nsfw_allowed: bool, - premium: bool, - purchased_flags: i32, - premium_usage_flags: i32, + nsfw_allowed: Option, + premium: Option, + purchased_flags: Option, + premium_usage_flags: Option, disabled: Option, } @@ -422,12 +428,43 @@ pub struct Message { } #[derive(Debug, Serialize, Deserialize, Default)] +/// See https://discord.com/developers/docs/topics/gateway-events#message-create pub struct MessageCreate { #[serde(flatten)] message: Message, guild_id: Option, member: Option, - mentions: Vec<(UserObject, GuildMember)>, // Not sure if this is correct: https://discord.com/developers/docs/topics/gateway-events#message-create + mentions: Vec, +} + +#[derive(Debug, Serialize, Deserialize, Default)] +/// See https://discord.com/developers/docs/topics/gateway-events#message-create-message-create-extra-fields +pub struct MessageCreateUser { + pub id: String, + username: String, + discriminator: String, + avatar: Option, + bot: Option, + system: Option, + mfa_enabled: Option, + accent_color: Option, + locale: Option, + verified: Option, + email: Option, + premium_since: Option, + premium_type: Option, + pronouns: Option, + public_flags: Option, + banner: Option, + bio: Option, + theme_colors: Option>, + phone: Option, + nsfw_allowed: Option, + premium: Option, + purchased_flags: Option, + premium_usage_flags: Option, + disabled: Option, + member: GuildMember } impl WebSocketEvent for MessageCreate {} @@ -724,17 +761,17 @@ pub struct MessageInteraction { pub member: Option, } -#[derive(Debug, Deserialize, Serialize, Clone)] +#[derive(Debug, Deserialize, Serialize, Clone, Default)] pub struct GuildMember { pub user: Option, pub nick: Option, pub avatar: Option, - pub roles: Vec, + pub roles: Vec, pub joined_at: String, pub premium_since: Option, pub deaf: bool, pub mute: bool, - pub flags: i32, + pub flags: Option, pub pending: Option, pub permissions: Option, pub communication_disabled_until: Option, @@ -845,6 +882,24 @@ pub struct IntegrationAccount { pub name: String, } +#[derive(Default, Debug, Deserialize, Serialize, Clone)] +/// See https://discord.com/developers/docs/resources/voice#voice-state-object +pub struct VoiceStateObject { + pub guild_id: Option, + pub channel_id: Option, + pub user_id: String, + pub member: Option, + pub session_id: String, + pub deaf: bool, + pub mute: bool, + pub self_deaf: bool, + pub self_mute: bool, + pub self_stream: Option, + pub self_video: bool, + pub suppress: bool, + pub request_to_speak_timestamp: Option> +} + #[derive(Default, Debug, Deserialize, Serialize, Clone)] /// See https://discord.com/developers/docs/resources/stage-instance#stage-instance-object pub struct StageInstance { @@ -922,11 +977,23 @@ impl WebSocketEvent for TypingStartEvent {} pub struct GatewayIdentifyPayload { pub token: String, pub properties: GatewayIdentifyConnectionProps, + #[serde(skip_serializing_if = "Option::is_none")] pub compress: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub large_threshold: Option, //default: 50 + #[serde(skip_serializing_if = "Option::is_none")] pub shard: Option>, + #[serde(skip_serializing_if = "Option::is_none")] pub presence: Option, - pub intents: i32, + pub capabilities: i32, +} + +impl GatewayIdentifyPayload { + pub fn default_w_client_capabilities() -> Self { + let mut def = Self::default(); + def.capabilities = 8189; // Default capabilities for a client + def + } } impl WebSocketEvent for GatewayIdentifyPayload {} @@ -1033,13 +1100,62 @@ pub struct GatewayReady { impl WebSocketEvent for GatewayReady {} +#[derive(Debug, Deserialize, Serialize, Default)] +/// Officially Undocumented +/// Sent after the READY event when a client has capabilities +/// {"t":"READY_SUPPLEMENTAL","s":2,"op":0,"d":{"merged_presences":{"guilds":[[{"user_id":"463640391196082177","status":"online","game":null,"client_status":{"web":"online"},"activities":[]}]],"friends":[{"user_id":"463640391196082177","status":"online","last_modified":1684053508443,"client_status":{"web":"online"},"activities":[]}]},"merged_members":[[{"user_id":"463640391196082177","roles":[],"premium_since":null,"pending":false,"nick":"pog","mute":false,"joined_at":"2021-05-30T15:24:08.763000+00:00","flags":0,"deaf":false,"communication_disabled_until":null,"avatar":null}]],"lazy_private_channels":[],"guilds":[{"voice_states":[],"id":"848582562217590824","embedded_activities":[]}],"disclose":["pomelo"]}} +pub struct GatewayReadySupplemental { + pub merged_presences: MergedPresences, + pub merged_members: Vec>, + // ? + pub lazy_private_channels: Vec, + pub guilds: Vec, + // ? pomelo + pub disclose: Vec, +} + +impl WebSocketEvent for GatewayReadySupplemental {} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct MergedPresences { + pub guilds: Vec>, + pub friends: Vec +} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct MergedPresenceFriend { + pub user_id: String, + pub status: String, + /// Looks like ms?? + pub last_modified: u128, + pub client_status: ClientStatusObject, + pub activities: Vec +} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct MergedPresenceGuild { + pub user_id: String, + pub status: String, + // ? + pub game: Option, + pub client_status: ClientStatusObject, + pub activities: Vec +} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct SupplimentalGuild { + pub voice_states: Vec, + pub id: String, + pub embedded_activities: Vec +} + #[derive(Debug, Deserialize, Serialize, Default)] /// See https://discord.com/developers/docs/topics/gateway-events#request-guild-members-request-guild-members-structure pub struct GatewayRequestGuildMembers { pub guild_id: String, pub query: Option, pub limit: u64, - pub presence: Option, + pub presences: Option, pub user_ids: Option, pub nonce: Option, } @@ -1117,8 +1233,8 @@ impl WebSocketEvent for GuildBanRemove {} #[derive(Debug, Default, Deserialize, Serialize)] /// See https://discord.com/developers/docs/topics/gateway-events#user-update -/// Not directly serialized, as the inner payload is the user object pub struct UserUpdate { + #[serde(flatten)] pub user: UserObject, } @@ -1126,8 +1242,8 @@ impl WebSocketEvent for UserUpdate {} #[derive(Debug, Default, Deserialize, Serialize)] /// See https://discord.com/developers/docs/topics/gateway-events#channel-create -/// Not directly serialized, as the inner payload is a channel object pub struct ChannelCreate { + #[serde(flatten)] pub channel: Channel, } @@ -1135,8 +1251,8 @@ impl WebSocketEvent for ChannelCreate {} #[derive(Debug, Default, Deserialize, Serialize)] /// See https://discord.com/developers/docs/topics/gateway-events#channel-update -/// Not directly serialized, as the inner payload is a channel object pub struct ChannelUpdate { + #[serde(flatten)] pub channel: Channel, } @@ -1144,8 +1260,8 @@ impl WebSocketEvent for ChannelUpdate {} #[derive(Debug, Default, Deserialize, Serialize)] /// See https://discord.com/developers/docs/topics/gateway-events#channel-delete -/// Not directly serialized, as the inner payload is a channel object pub struct ChannelDelete { + #[serde(flatten)] pub channel: Channel, } @@ -1153,8 +1269,8 @@ impl WebSocketEvent for ChannelDelete {} #[derive(Debug, Default, Deserialize, Serialize)] /// See https://discord.com/developers/docs/topics/gateway-events#thread-create -/// Not directly serialized, as the inner payload is a channel object pub struct ThreadCreate { + #[serde(flatten)] pub thread: Channel, } @@ -1162,8 +1278,8 @@ impl WebSocketEvent for ThreadCreate {} #[derive(Debug, Default, Deserialize, Serialize)] /// See https://discord.com/developers/docs/topics/gateway-events#thread-update -/// Not directly serialized, as the inner payload is a channel object pub struct ThreadUpdate { + #[serde(flatten)] pub thread: Channel, } @@ -1171,8 +1287,8 @@ impl WebSocketEvent for ThreadUpdate {} #[derive(Debug, Default, Deserialize, Serialize)] /// See https://discord.com/developers/docs/topics/gateway-events#thread-delete -/// Not directly serialized, as the inner payload is a channel object pub struct ThreadDelete { + #[serde(flatten)] pub thread: Channel, } @@ -1192,29 +1308,12 @@ impl WebSocketEvent for ThreadListSync {} #[derive(Debug, Default, Deserialize, Serialize)] /// See https://discord.com/developers/docs/topics/gateway-events#thread-member-update /// The inner payload is a thread member object with an extra field. -/// The extra field is a bit painful, because we can't just serialize a thread member object pub struct ThreadMemberUpdate { - pub id: Option, - pub user_id: Option, - pub join_timestamp: Option, - pub flags: Option, - pub member: Option, + #[serde(flatten)] + pub member: ThreadMember, pub guild_id: String, } -impl ThreadMemberUpdate { - /// Convert self to a thread member, losing the added guild_id field - pub fn to_thread_member(&self) -> ThreadMember { - ThreadMember { - id: self.id, - user_id: self.user_id, - join_timestamp: self.join_timestamp.clone(), - flags: self.flags, - member: self.member.clone(), - } - } -} - impl WebSocketEvent for ThreadMemberUpdate {} #[derive(Debug, Default, Deserialize, Serialize)] @@ -1234,6 +1333,7 @@ impl WebSocketEvent for ThreadMembersUpdate {} /// See https://discord.com/developers/docs/topics/gateway-events#guild-create /// This one is particularly painful, it can be a Guild object with extra field or an unavailbile guild object pub struct GuildCreate { + #[serde(flatten)] pub d: GuildCreateDataOption, } @@ -1250,6 +1350,111 @@ impl Default for GuildCreateDataOption { } impl WebSocketEvent for GuildCreate {} +#[derive(Debug, Default, Deserialize, Serialize)] +/// See https://discord.com/developers/docs/topics/gateway-events#guild-update +pub struct GuildUpdate { + #[serde(flatten)] + pub guild: Guild +} + +impl WebSocketEvent for GuildUpdate {} + +#[derive(Debug, Default, Deserialize, Serialize)] +/// See https://discord.com/developers/docs/topics/gateway-events#guild-delete +pub struct GuildDelete { + #[serde(flatten)] + pub guild: UnavailableGuild +} + +impl WebSocketEvent for GuildDelete {} + +#[derive(Debug, Default, Deserialize, Serialize)] +/// See https://discord.com/developers/docs/topics/gateway-events#guild-emojis-update +pub struct GuildEmojisUpdate { + pub guild_id: String, + pub emojis: Vec +} + +impl WebSocketEvent for GuildEmojisUpdate {} + +#[derive(Debug, Deserialize, Serialize, Default)] +/// Officially Undocumented +/// {"t":"CALL_CREATE","s":2,"op":0,"d":{"voice_states":[],"ringing":[],"region":"milan","message_id":"1107187514906775613","embedded_activities":[],"channel_id":"837609115475771392"}} +pub struct CallCreate { + pub voice_states: Vec, + /// Seems like a vec of channel ids + pub ringing: Vec, + pub region: String, // milan + pub message_id: String, + /// What is this? + pub embedded_activities: Vec, + pub channel_id: String, +} +impl WebSocketEvent for CallCreate {} + +#[derive(Debug, Deserialize, Serialize, Default)] +/// Officially Undocumented +/// {"t":"CALL_UPDATE","s":5,"op":0,"d":{"ringing":["837606544539254834"],"region":"milan","message_id":"1107191540234846308","guild_id":null,"channel_id":"837609115475771392"}} +pub struct CallUpdate { + /// Seems like a vec of channel ids + pub ringing: Vec, + pub region: String, // milan + pub message_id: String, + pub guild_id: Option, + pub channel_id: String, +} +impl WebSocketEvent for CallUpdate {} + +#[derive(Debug, Deserialize, Serialize, Default)] +/// Officially Undocumented +/// {"t":"CALL_DELETE","s":8,"op":0,"d":{"channel_id":"837609115475771392"}} +pub struct CallDelete { + pub channel_id: String, +} +impl WebSocketEvent for CallDelete {} + +#[derive(Debug, Deserialize, Serialize, Default)] +/// Officially Undocumented +/// See https://unofficial-discord-docs.vercel.app/gateway/op13 +/// {"op":13,"d":{"channel_id":"837609115475771392"}} +pub struct CallSync { + pub channel_id: String, +} +impl WebSocketEvent for CallSync {} + +#[derive(Debug, Deserialize, Serialize, Default)] +/// Officially Undocumented +/// See https://luna.gitlab.io/discord-unofficial-docs/lazy_guilds.html#op-14-lazy-request +/// {"op":14,"d":{"guild_id":"848582562217590824","typing":true,"activities":true,"threads":true}} +pub struct LazyRequest { + pub guild_id: String, + pub typing: bool, + pub activities: bool, + pub threads: bool, + #[serde(skip_serializing_if = "Option::is_none")] + pub members: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub channels: Option>>> +} +impl WebSocketEvent for LazyRequest {} + +#[derive(Debug, Deserialize, Serialize, Default)] +/// Officially Undocumented +/// Not documented anywhere unofficially +/// Apparently "Message ACK refers to marking a message as read for Discord's API." (https://github.com/Rapptz/discord.py/issues/1851) +/// I suspect this is sent and recieved from the gateway to let clients on other devices know the user has read a message +/// {"t":"MESSAGE_ACK","s":3,"op":0,"d":{"version":52,"message_id":"1107236673638633472","last_viewed":null,"flags":null,"channel_id":"967363950217936897"}} +pub struct MessageACK { + /// ? + pub version: u16, + pub message_id: String, + pub last_viewed: Option>, + /// What flags? + pub flags: Option, + pub channel_id: String, +} +impl WebSocketEvent for MessageACK {} + #[derive(Debug, Default, Deserialize, Serialize)] pub struct GatewayPayload { pub op: u8, diff --git a/src/gateway.rs b/src/gateway.rs index c79004f..a75a77d 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -93,6 +93,26 @@ impl GatewayHandle { self.send_json_event(4, to_send_value).await; } + + /// Sends a Call Sync + pub async fn send_call_sync(&self, to_send: CallSync) { + + let to_send_value = serde_json::to_value(&to_send).unwrap(); + + println!("GW: Sending Call Sync.."); + + self.send_json_event(13, to_send_value).await; + } + + /// Sends a Lazy Request + pub async fn send_lazy_request(&self, to_send: LazyRequest) { + + let to_send_value = serde_json::to_value(&to_send).unwrap(); + + println!("GW: Sending Lazy Request.."); + + self.send_json_event(14, to_send_value).await; + } } pub struct Gateway { @@ -167,9 +187,7 @@ impl Gateway { return; } - let msg_string = msg.to_string(); - - let gateway_payload: GatewayPayload = serde_json::from_str(&msg_string).unwrap(); + let gateway_payload: GatewayPayload = serde_json::from_str(msg.to_text().unwrap()).unwrap(); // See https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes match gateway_payload.op { @@ -183,7 +201,12 @@ impl Gateway { // See https://discord.com/developers/docs/topics/gateway-events#receive-events match gateway_payload_t.as_str() { "READY" => { - let _data: GatewayReady = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + let new_data: GatewayReady = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.ready.ready.update_data(new_data).await; + }, + "READY_SUPPLEMENTAL" => { + let new_data: GatewayReadySupplemental = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.ready.ready_supplimental.update_data(new_data).await; } "RESUMED" => {} "APPLICATION_COMMAND_PERMISSIONS_UPDATE" => {} @@ -192,37 +215,43 @@ impl Gateway { "AUTO_MODERATION_RULE_DELETE" => {} "AUTO_MODERATION_ACTION_EXECUTION" => {} "CHANNEL_CREATE" => { - let channel: Channel = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - let new_data = ChannelCreate {channel}; + let new_data: ChannelCreate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.channel.create.update_data(new_data).await; } "CHANNEL_UPDATE" => { - let channel: Channel = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - let new_data = ChannelUpdate {channel}; + let new_data: ChannelUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.channel.update.update_data(new_data).await; } "CHANNEL_DELETE" => { - let channel: Channel = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - let new_data = ChannelDelete {channel}; + let new_data: ChannelDelete = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.channel.delete.update_data(new_data).await; } "CHANNEL_PINS_UPDATE" => { let new_data: ChannelPinsUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.channel.pins_update.update_data(new_data).await; } + "CALL_CREATE" => { + let new_data: CallCreate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.call.create.update_data(new_data).await; + }, + "CALL_UPDATE" => { + let new_data: CallUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.call.update.update_data(new_data).await; + } + "CALL_DELETE" => { + let new_data: CallDelete = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.call.delete.update_data(new_data).await; + } "THREAD_CREATE" => { - let thread: Channel = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - let new_data = ThreadCreate {thread}; + let new_data: ThreadCreate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.thread.create.update_data(new_data).await; } "THREAD_UPDATE" => { - let thread: Channel = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - let new_data = ThreadUpdate {thread}; + let new_data: ThreadUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.thread.update.update_data(new_data).await; } "THREAD_DELETE" => { - let thread: Channel = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - let new_data = ThreadDelete {thread}; + let new_data: ThreadDelete = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.thread.delete.update_data(new_data).await; } "THREAD_LIST_SYNC" => { @@ -238,21 +267,30 @@ impl Gateway { self.events.lock().await.thread.members_update.update_data(new_data).await; } "GUILD_CREATE" => { - let new_data: GuildCreate = serde_json::from_str(&msg_string).unwrap(); + let new_data: GuildCreate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.guild.create.update_data(new_data).await; } - "GUILD_UPDATE" => {} + "GUILD_UPDATE" => { + let new_data: GuildUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.guild.update.update_data(new_data).await; + } "GUILD_DELETE" => { - let _new_data: UnavailableGuild = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + let new_data: GuildDelete = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.guild.delete.update_data(new_data).await; } "GUILD_AUDIT_LOG_ENTRY_CREATE" => {} "GUILD_BAN_ADD" => { - let _new_data: GuildBanAdd = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + let new_data: GuildBanAdd = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.guild.ban_add.update_data(new_data).await; } "GUILD_BAN_REMOVE" => { - let _new_data: GuildBanRemove = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + let new_data: GuildBanRemove = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.guild.ban_remove.update_data(new_data).await; + } + "GUILD_EMOJIS_UPDATE" => { + let new_data: GuildEmojisUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.guild.emojis_update.update_data(new_data).await; } - "GUILD_EMOJIS_UPDATE" => {} "GUILD_STICKERS_UPDATE" => {} "GUILD_INTEGRATIONS_UPDATE" => {} "GUILD_MEMBER_ADD" => {} @@ -304,6 +342,10 @@ impl Gateway { "MESSAGE_REACTION_REMOVE_EMOJI" => { let new_data: MessageReactionRemoveEmoji= serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.message.reaction_remove_emoji.update_data(new_data).await; + }, + "MESSAGE_ACK" => { + let new_data: MessageACK = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); + self.events.lock().await.message.ack.update_data(new_data).await; } "PRESENCE_UPDATE" => { let new_data: PresenceUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); @@ -319,8 +361,7 @@ impl Gateway { self.events.lock().await.user.typing_start_event.update_data(new_data).await; } "USER_UPDATE" => { - let user: UserObject = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); - let new_data = UserUpdate {user}; + let new_data: UserUpdate = serde_json::from_value(gateway_payload.d.unwrap()).unwrap(); self.events.lock().await.user.update.update_data(new_data).await; } "VOICE_STATE_UPDATE" => {} @@ -512,15 +553,23 @@ mod events { use super::*; #[derive(Default, Debug)] pub struct Events { + pub ready: Ready, pub message: Message, pub user: User, pub channel: Channel, pub thread: Thread, pub guild: Guild, + pub call: Call, pub gateway_identify_payload: GatewayEvent, pub gateway_resume: GatewayEvent, } + #[derive(Default, Debug)] + pub struct Ready { + pub ready: GatewayEvent, + pub ready_supplimental: GatewayEvent + } + #[derive(Default, Debug)] pub struct Message { pub create: GatewayEvent, @@ -531,6 +580,7 @@ mod events { pub reaction_remove: GatewayEvent, pub reaction_remove_all: GatewayEvent, pub reaction_remove_emoji: GatewayEvent, + pub ack: GatewayEvent } #[derive(Default, Debug)] @@ -561,13 +611,13 @@ mod events { #[derive(Default, Debug)] pub struct Guild { pub create: GatewayEvent, - /*pub update: GatewayEvent, - pub delete: GatewayEvent, - pub audit_log_entry_create: GatewayEvent, - pub ban_add: GatewayEvent, - pub ban_remove: GatewayEvent, - pub emojis_update: GatewayEvent, - pub stickers_update: GatewayEvent, + pub update: GatewayEvent, + pub delete: GatewayEvent, + //pub audit_log_entry_create: GatewayEvent, + pub ban_add: GatewayEvent, + pub ban_remove: GatewayEvent, + pub emojis_update: GatewayEvent, + /*pub stickers_update: GatewayEvent, pub integrations_update: GatewayEvent, pub member_add: GatewayEvent, pub member_remove: GatewayEvent, @@ -582,6 +632,13 @@ mod events { pub role_scheduled_event_user_add: GatewayEvent, pub role_scheduled_event_user_remove: GatewayEvent,*/ } + + #[derive(Default, Debug)] + pub struct Call { + pub create: GatewayEvent, + pub update: GatewayEvent, + pub delete: GatewayEvent + } } #[cfg(test)]