titanium_model/
reaction.rs

1//! Reaction types for Discord message reactions.
2//!
3//! Reactions are emoji added to messages by users.
4
5use crate::Snowflake;
6use crate::TitanString;
7use serde::{Deserialize, Serialize};
8
9/// Event data for MESSAGE_REACTION_ADD.
10#[derive(Debug, Clone, Deserialize, Serialize)]
11pub struct MessageReactionAddEvent<'a> {
12    /// ID of the user.
13    pub user_id: Snowflake,
14
15    /// ID of the channel.
16    pub channel_id: Snowflake,
17
18    /// ID of the message.
19    pub message_id: Snowflake,
20
21    /// ID of the guild.
22    #[serde(default)]
23    pub guild_id: Option<Snowflake>,
24
25    /// Member who reacted if in a guild.
26    #[serde(default)]
27    pub member: Option<super::member::GuildMember<'a>>,
28
29    /// The emoji used to react.
30    pub emoji: ReactionEmoji<'a>,
31
32    /// ID of the user who authored the message.
33    #[serde(default)]
34    pub message_author_id: Option<Snowflake>,
35
36    /// Whether this is a super-reaction.
37    #[serde(default)]
38    pub burst: bool,
39
40    /// Colors used for super-reaction animation (hex format).
41    #[serde(default)]
42    pub burst_colors: Vec<String>,
43
44    /// The type of reaction.
45    #[serde(default, rename = "type")]
46    pub reaction_type: u8,
47}
48
49/// Event data for MESSAGE_REACTION_REMOVE.
50#[derive(Debug, Clone, Deserialize, Serialize)]
51pub struct MessageReactionRemoveEvent<'a> {
52    /// ID of the user.
53    pub user_id: Snowflake,
54
55    /// ID of the channel.
56    pub channel_id: Snowflake,
57
58    /// ID of the message.
59    pub message_id: Snowflake,
60
61    /// ID of the guild.
62    #[serde(default)]
63    pub guild_id: Option<Snowflake>,
64
65    /// The emoji used to react.
66    pub emoji: ReactionEmoji<'a>,
67
68    /// Whether this was a super-reaction.
69    #[serde(default)]
70    pub burst: bool,
71
72    /// The type of reaction.
73    #[serde(default, rename = "type")]
74    pub reaction_type: u8,
75}
76
77/// Event data for MESSAGE_REACTION_REMOVE_ALL.
78#[derive(Debug, Clone, Deserialize, Serialize)]
79pub struct MessageReactionRemoveAllEvent {
80    /// ID of the channel.
81    pub channel_id: Snowflake,
82
83    /// ID of the message.
84    pub message_id: Snowflake,
85
86    /// ID of the guild.
87    #[serde(default)]
88    pub guild_id: Option<Snowflake>,
89}
90
91/// Event data for MESSAGE_REACTION_REMOVE_EMOJI.
92#[derive(Debug, Clone, Deserialize, Serialize)]
93pub struct MessageReactionRemoveEmojiEvent<'a> {
94    /// ID of the channel.
95    pub channel_id: Snowflake,
96
97    /// ID of the message.
98    pub message_id: Snowflake,
99
100    /// ID of the guild.
101    #[serde(default)]
102    pub guild_id: Option<Snowflake>,
103
104    /// The emoji that was removed.
105    pub emoji: ReactionEmoji<'a>,
106}
107
108/// Emoji used in a reaction.
109#[derive(Debug, Clone, Deserialize, Serialize)]
110pub struct ReactionEmoji<'a> {
111    /// Emoji ID (null for standard emoji).
112    #[serde(default)]
113    pub id: Option<Snowflake>,
114
115    /// Emoji name.
116    #[serde(default)]
117    pub name: Option<TitanString<'a>>,
118
119    /// Whether this emoji is animated.
120    #[serde(default)]
121    pub animated: bool,
122}
123
124#[cfg(test)]
125mod tests {
126    use super::*;
127
128    #[test]
129    fn test_reaction_add_event() {
130        let json = r#"{
131            "user_id": "123",
132            "channel_id": "456",
133            "message_id": "789",
134            "emoji": {"name": "👍"}
135        }"#;
136
137        let event: MessageReactionAddEvent = crate::json::from_str(json).unwrap();
138        assert_eq!(event.emoji.name, Some(TitanString::Borrowed("👍")));
139    }
140
141    #[test]
142    fn test_custom_emoji() {
143        let json = r#"{
144            "id": "123456789",
145            "name": "custom_emoji",
146            "animated": true
147        }"#;
148
149        let emoji: ReactionEmoji = crate::json::from_str(json).unwrap();
150        assert!(emoji.animated);
151        assert!(emoji.id.is_some());
152    }
153}