Skip to content

Commit

Permalink
Guarantee the MessageComponentInteraction::message to not be partial (
Browse files Browse the repository at this point in the history
#1471)

As per a recent discord update, the `MessageComponentInteraction::message` field will not be partial for ephemeral messages anymore, and will include the full message object, see below screenshot[0].

[0]: https://user-images.githubusercontent.com/23212967/129490670-01cc2c4d-44ca-4db2-a605-67abfb793e46.png
  • Loading branch information
HarmoGlace committed Aug 20, 2021
1 parent 2a571d3 commit f915fee
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 83 deletions.
2 changes: 1 addition & 1 deletion src/collector/component_interaction_collector.rs
Expand Up @@ -156,7 +156,7 @@ impl ComponentInteractionFilter {
) -> bool {
// TODO: On next branch, switch filter arg to &T so this as_arc() call can be removed.
self.options.guild_id.map_or(true, |id| Some(id) == interaction.guild_id.map(|g| g.0))
&& self.options.message_id.map_or(true, |id| interaction.message.id().0 == id)
&& self.options.message_id.map_or(true, |id| interaction.message.id.0 == id)
&& self.options.channel_id.map_or(true, |id| id == interaction.channel_id.as_ref().0)
&& self.options.author_id.map_or(true, |id| id == interaction.user.id.0)
&& self.options.filter.as_ref().map_or(true, |f| f(&interaction.as_arc()))
Expand Down
2 changes: 1 addition & 1 deletion src/model/event.rs
Expand Up @@ -2223,7 +2223,7 @@ macro_rules! with_related_ids_for_event_types {
message_id: match &e.interaction {
Interaction::Ping(_) => None,
Interaction::ApplicationCommand(_) => None,
Interaction::MessageComponent(i) => Some(i.message.id()),
Interaction::MessageComponent(i) => Some(i.message.id),
},
},
#[cfg(feature = "unstable_discord_api")]
Expand Down
87 changes: 6 additions & 81 deletions src/model/interactions/message_component.rs
Expand Up @@ -28,7 +28,7 @@ pub struct MessageComponentInteraction {
pub data: MessageComponentInteractionData,
/// The message this interaction was triggered by, if
/// it is a component.
pub message: InteractionMessage,
pub message: Message,
/// The guild Id this interaction was sent from, if there is one.
#[serde(skip_serializing_if = "Option::is_none")]
pub guild_id: Option<GuildId>,
Expand Down Expand Up @@ -321,25 +321,11 @@ impl<'de> Deserialize<'de> for MessageComponentInteraction {
false => member.as_ref().expect("expected user or member").user.clone(),
};

let message = {
let message = map
.remove("message")
.ok_or_else(|| DeError::custom("expected message"))
.and_then(JsonMap::deserialize)
.map_err(DeError::custom)?;

let partial = !message.contains_key("author");

let value: Value = message.into();

if partial {
InteractionMessage::Ephemeral(
EphemeralMessage::deserialize(value).map_err(DeError::custom)?,
)
} else {
InteractionMessage::Regular(Message::deserialize(value).map_err(DeError::custom)?)
}
};
let message = map
.remove("message")
.ok_or_else(|| DeError::custom("expected message"))
.and_then(Message::deserialize)
.map_err(DeError::custom)?;

let token = map
.remove("token")
Expand Down Expand Up @@ -626,64 +612,3 @@ pub struct SelectMenuOption {
#[serde(default)]
pub default: bool,
}

/// The [`MessageComponentInteraction::message`] field.
#[derive(Clone, Debug, Deserialize)]
pub enum InteractionMessage {
Regular(Message),
Ephemeral(EphemeralMessage),
}

impl InteractionMessage {
/// Whether the message is ephemeral.
pub fn is_ephemeral(&self) -> bool {
matches!(self, InteractionMessage::Ephemeral(_))
}

/// Gets the message Id.
pub fn id(&self) -> MessageId {
match self {
InteractionMessage::Regular(m) => m.id,
InteractionMessage::Ephemeral(m) => m.id,
}
}

/// Converts this to a regular message,
/// if it is one.
pub fn regular(self) -> Option<Message> {
match self {
InteractionMessage::Regular(m) => Some(m),
InteractionMessage::Ephemeral(_) => None,
}
}

/// Converts this to an ephemeral message,
/// if it is one.
pub fn ephemeral(self) -> Option<EphemeralMessage> {
match self {
InteractionMessage::Regular(_) => None,
InteractionMessage::Ephemeral(m) => Some(m),
}
}
}

impl Serialize for InteractionMessage {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where
S: Serializer,
{
match self {
InteractionMessage::Regular(c) => Message::serialize(c, serializer),
InteractionMessage::Ephemeral(c) => EphemeralMessage::serialize(c, serializer),
}
}
}

/// An ephemeral message given in an interaction.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct EphemeralMessage {
/// The message flags.
pub flags: MessageFlags,
/// The message Id.
pub id: MessageId,
}

0 comments on commit f915fee

Please sign in to comment.