From 3d3ebdd7ece89e1f880c64ab9ec391747c6e7c43 Mon Sep 17 00:00:00 2001 From: kangalioo Date: Tue, 11 Oct 2022 21:31:00 +0200 Subject: [PATCH 1/3] Rearrange Message fields to match Discord docs --- src/model/channel/message.rs | 62 ++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs index de6bc4f9a58..e415a10a963 100644 --- a/src/model/channel/message.rs +++ b/src/model/channel/message.rs @@ -48,30 +48,25 @@ pub struct Message { /// The unique Id of the message. Can be used to calculate the creation date /// of the message. pub id: MessageId, - /// An vector of the files attached to a message. - pub attachments: Vec, - /// The user that sent the message. - pub author: User, /// The Id of the [`Channel`] that the message was sent to. pub channel_id: ChannelId, + /// The user that sent the message. + pub author: User, /// The content of the message. pub content: String, + /// Initial message creation timestamp, calculated from its Id. + pub timestamp: Timestamp, /// The timestamp of the last time the message was updated, if it was. pub edited_timestamp: Option, - /// Array of embeds sent with the message. - pub embeds: Vec, - /// The Id of the [`Guild`] that the message was sent in. This value will - /// only be present if this message was received over the gateway. - pub guild_id: Option, - /// Indicator of the type of message this is, i.e. whether it is a regular - /// message or a system message. - #[serde(rename = "type")] - pub kind: MessageType, - /// A partial amount of data about the user's member data, if this message - /// was sent in a guild. - pub member: Option, + /// Indicator of whether the command is to be played back via + /// text-to-speech. + /// + /// In the client, this is done via the `/tts` slash command. + pub tts: bool, /// Indicator of whether the message mentions everyone. pub mention_everyone: bool, + /// Array of users mentioned in the message. + pub mentions: Vec, /// Array of [`Role`]s' Ids mentioned in the message. pub mention_roles: Vec, /// Channels specifically mentioned in this message. @@ -91,25 +86,24 @@ pub struct Message { /// [discord-docs]: https://discord.com/developers/docs/resources/channel#message-object #[serde(default = "Vec::new")] pub mention_channels: Vec, - /// Array of users mentioned in the message. - pub mentions: Vec, + /// An vector of the files attached to a message. + pub attachments: Vec, + /// Array of embeds sent with the message. + pub embeds: Vec, + /// Array of reactions performed on the message. + #[serde(default)] + pub reactions: Vec, /// Non-repeating number used for ensuring message order. #[serde(default)] pub nonce: Value, /// Indicator of whether the message is pinned. pub pinned: bool, - /// Array of reactions performed on the message. - #[serde(default)] - pub reactions: Vec, - /// Initial message creation timestamp, calculated from its Id. - pub timestamp: Timestamp, - /// Indicator of whether the command is to be played back via - /// text-to-speech. - /// - /// In the client, this is done via the `/tts` slash command. - pub tts: bool, /// The Id of the webhook that sent this message, if one did. pub webhook_id: Option, + /// Indicator of the type of message this is, i.e. whether it is a regular + /// message or a system message. + #[serde(rename = "type")] + pub kind: MessageType, /// Sent with Rich Presence-related chat embeds. pub activity: Option, /// Sent with Rich Presence-related chat embeds. @@ -118,9 +112,6 @@ pub struct Message { pub message_reference: Option, /// Bit flags describing extra features of the message. pub flags: Option, - /// Array of message sticker item objects. - #[serde(default)] - pub sticker_items: Vec, /// The message that was replied to using this message. pub referenced_message: Option>, // Boxed to avoid recursion /// Sent if the message is a response to an [`Interaction`]. @@ -130,6 +121,15 @@ pub struct Message { /// The components of this message #[serde(default)] pub components: Vec, + /// Array of message sticker item objects. + #[serde(default)] + pub sticker_items: Vec, + /// The Id of the [`Guild`] that the message was sent in. This value will + /// only be present if this message was received over the gateway. + pub guild_id: Option, + /// A partial amount of data about the user's member data, if this message + /// was sent in a guild. + pub member: Option, } #[cfg(feature = "model")] From d1fde2fb530a8019405e0ec2c787fe705f746d2c Mon Sep 17 00:00:00 2001 From: kangalioo Date: Tue, 11 Oct 2022 22:31:55 +0200 Subject: [PATCH 2/3] Add missing fields to Message and testing code New fields: - User::member - Message::thread - Message::application_id The first two I tested via the included command in the `testing` crate: I created a thread with the initial message `testmessage @USER`. The received Message should include the new thread field and the User struct in the mentions array should include the new member field. --- examples/testing/Cargo.toml | 9 ++++++++ examples/testing/Makefile.toml | 13 +++++++++++ examples/testing/src/main.rs | 42 ++++++++++++++++++++++++++++++++++ src/model/channel/message.rs | 9 +++++++- src/model/gateway.rs | 4 +++- src/model/user.rs | 8 +++++++ src/utils/custom_message.rs | 3 +++ 7 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 examples/testing/Cargo.toml create mode 100644 examples/testing/Makefile.toml create mode 100644 examples/testing/src/main.rs diff --git a/examples/testing/Cargo.toml b/examples/testing/Cargo.toml new file mode 100644 index 00000000000..5ba79f251a2 --- /dev/null +++ b/examples/testing/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "testing" +version = "0.1.0" +authors = ["my name "] +edition = "2018" + +[dependencies] +serenity = { path = "../../", default-features = false, features = ["client", "gateway", "rustls_backend", "model"] } +tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } diff --git a/examples/testing/Makefile.toml b/examples/testing/Makefile.toml new file mode 100644 index 00000000000..2e5db0b5e63 --- /dev/null +++ b/examples/testing/Makefile.toml @@ -0,0 +1,13 @@ +extend = "../../Makefile.toml" + +[tasks.examples_build] +alias = "build" + +[tasks.examples_build_release] +alias = "build_release" + +[tasks.examples_run] +alias = "run" + +[tasks.examples_run_release] +alias = "run_release" diff --git a/examples/testing/src/main.rs b/examples/testing/src/main.rs new file mode 100644 index 00000000000..a30421513df --- /dev/null +++ b/examples/testing/src/main.rs @@ -0,0 +1,42 @@ +use serenity::model::prelude::interaction::application_command::*; +use serenity::model::prelude::*; +use serenity::prelude::*; + +async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> { + if let Some(_args) = msg.content.strip_prefix("testmessage ") { + println!("command message: {:#?}", msg); + } else { + return Ok(()); + } + + msg.react(&ctx, '✅').await?; + Ok(()) +} + +async fn interaction( + _ctx: &Context, + _interaction: ApplicationCommandInteraction, +) -> Result<(), serenity::Error> { + Ok(()) +} + +struct Handler; +#[serenity::async_trait] +impl EventHandler for Handler { + async fn message(&self, ctx: Context, msg: Message) { + message(&ctx, msg).await.unwrap(); + } + + async fn interaction_create(&self, ctx: Context, i: Interaction) { + if let Interaction::ApplicationCommand(i) = i { + interaction(&ctx, i).await.unwrap(); + } + } +} + +#[tokio::main] +async fn main() -> Result<(), serenity::Error> { + let token = std::env::var("DISCORD_TOKEN").expect("Expected a token in the environment"); + let intents = GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT; + Client::builder(token, intents).event_handler(Handler).await?.start().await +} diff --git a/src/model/channel/message.rs b/src/model/channel/message.rs index e415a10a963..e128f41cb51 100644 --- a/src/model/channel/message.rs +++ b/src/model/channel/message.rs @@ -41,7 +41,8 @@ use crate::{ /// A representation of a message over a guild's text channel, a group, or a /// private channel. /// -/// [Discord docs](https://discord.com/developers/docs/resources/channel#message-object). +/// [Discord docs](https://discord.com/developers/docs/resources/channel#message-object) with some +/// [extra fields](https://discord.com/developers/docs/topics/gateway-events#message-create-message-create-extra-fields). #[derive(Clone, Debug, Deserialize, Serialize)] #[non_exhaustive] pub struct Message { @@ -108,6 +109,9 @@ pub struct Message { pub activity: Option, /// Sent with Rich Presence-related chat embeds. pub application: Option, + /// If the message is an Interaction or application-owned webhook, this is the id of the + /// application. + pub application_id: Option, /// Reference data sent with crossposted messages. pub message_reference: Option, /// Bit flags describing extra features of the message. @@ -118,12 +122,15 @@ pub struct Message { /// /// [`Interaction`]: crate::model::application::interaction::Interaction pub interaction: Option, + /// The thread that was started from this message, includes thread member object. + pub thread: Option, /// The components of this message #[serde(default)] pub components: Vec, /// Array of message sticker item objects. #[serde(default)] pub sticker_items: Vec, + // Field omitted: stickers (it's deprecated by Discord) /// The Id of the [`Guild`] that the message was sent in. This value will /// only be present if this message was received over the gateway. pub guild_id: Option, diff --git a/src/model/gateway.rs b/src/model/gateway.rs index 0dba65903fc..034f141846e 100644 --- a/src/model/gateway.rs +++ b/src/model/gateway.rs @@ -424,7 +424,7 @@ pub struct ClientStatus { /// Information about the user of a [`Presence`] event. /// -/// [Discord docs](https://discord.com/developers/docs/topics/gateway#presence-update). +/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#presence-update). #[derive(Clone, Default, Debug, Deserialize, Serialize)] #[non_exhaustive] #[serde(default)] @@ -457,6 +457,7 @@ impl PresenceUser { public_flags: self.public_flags, banner: None, accent_colour: None, + member: None, }) } @@ -476,6 +477,7 @@ impl PresenceUser { public_flags: self.public_flags, banner: None, accent_colour: None, + member: None, }) } diff --git a/src/model/user.rs b/src/model/user.rs index 96b429360c7..1582d5f3b94 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -654,6 +654,11 @@ pub struct User { #[cfg(not(feature = "utils"))] #[serde(rename = "accent_color")] pub accent_colour: Option, + /// Only included in [`Message::mentions`] for messages from the gateway. + /// + /// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-create-message-create-extra-fields). + // Box required to avoid infinitely recursive types + pub member: Option>, } bitflags! { @@ -713,6 +718,7 @@ impl Default for User { public_flags: None, banner: None, accent_colour: None, + member: None, } } } @@ -1185,6 +1191,7 @@ impl From for User { public_flags: user.public_flags, banner: user.banner, accent_colour: user.accent_colour, + member: None, } } } @@ -1200,6 +1207,7 @@ impl<'a> From<&'a CurrentUser> for User { public_flags: user.public_flags, banner: user.banner.clone(), accent_colour: user.accent_colour, + member: None, } } } diff --git a/src/utils/custom_message.rs b/src/utils/custom_message.rs index ecb2c1a0c3e..063f360a7a9 100644 --- a/src/utils/custom_message.rs +++ b/src/utils/custom_message.rs @@ -251,6 +251,7 @@ fn dummy_message() -> Message { public_flags: None, banner: None, accent_colour: None, + member: None, }, channel_id: ChannelId::default(), content: String::new(), @@ -277,5 +278,7 @@ fn dummy_message() -> Message { referenced_message: None, interaction: None, components: vec![], + application_id: None, + thread: None, } } From 94845c41081c12832dbf5ef81866f9459590460f Mon Sep 17 00:00:00 2001 From: kangalioo Date: Wed, 12 Oct 2022 20:04:27 +0200 Subject: [PATCH 3/3] Fix tests --- src/cache/mod.rs | 3 +++ src/model/channel/mod.rs | 1 + src/model/mention.rs | 1 + src/utils/content_safe.rs | 2 ++ 4 files changed, 7 insertions(+) diff --git a/src/cache/mod.rs b/src/cache/mod.rs index b6badd1c53b..6039da88b6f 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -1061,6 +1061,7 @@ mod test { name: "user 1".to_owned(), public_flags: None, banner: None, + member: None, accent_colour: None, }, channel_id: ChannelId(2), @@ -1088,6 +1089,8 @@ mod test { referenced_message: None, interaction: None, components: vec![], + application_id: None, + thread: None, }, }; diff --git a/src/model/channel/mod.rs b/src/model/channel/mod.rs index 9318e6e0a06..3a5d5458a73 100644 --- a/src/model/channel/mod.rs +++ b/src/model/channel/mod.rs @@ -557,6 +557,7 @@ mod test { public_flags: None, banner: None, accent_colour: None, + member: None, }, } } diff --git a/src/model/mention.rs b/src/model/mention.rs index f8ab114ba20..b24a69513bc 100644 --- a/src/model/mention.rs +++ b/src/model/mention.rs @@ -265,6 +265,7 @@ mod test { public_flags: None, banner: None, accent_colour: None, + member: None, }; let member = Member { deaf: false, diff --git a/src/utils/content_safe.rs b/src/utils/content_safe.rs index 55dc0bcc02e..8f1fee053dd 100644 --- a/src/utils/content_safe.rs +++ b/src/utils/content_safe.rs @@ -292,6 +292,7 @@ mod tests { public_flags: None, banner: None, accent_colour: None, + member: None, }; let outside_cache_user = User { @@ -303,6 +304,7 @@ mod tests { public_flags: None, banner: None, accent_colour: None, + member: None, }; let mut guild = Guild {