twilight_model/gateway/payload/incoming/
auto_moderation_action_execution.rs

1use crate::{
2    guild::auto_moderation::{AutoModerationAction, AutoModerationTriggerType},
3    id::{
4        marker::{AutoModerationRuleMarker, ChannelMarker, GuildMarker, MessageMarker, UserMarker},
5        Id,
6    },
7};
8use serde::{Deserialize, Serialize};
9
10/// Message has been blocked by AutoMod according to a rule.
11///
12/// Requires [`Permissions::MANAGE_GUILD`].
13///
14/// [`Permissions::MANAGE_GUILD`]: crate::guild::Permissions::MANAGE_GUILD
15#[allow(clippy::doc_markdown)]
16#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
17pub struct AutoModerationActionExecution {
18    /// Action which was executed.
19    pub action: AutoModerationAction,
20    /// ID of any system auto moderation messages posted as a result of this
21    /// action.
22    ///
23    /// Will not exist if this event does not correspond to an action with type
24    /// [`SendAlertMessage`].
25    ///
26    /// [`SendAlertMessage`]: crate::guild::auto_moderation::AutoModerationActionType::SendAlertMessage
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub alert_system_message_id: Option<Id<MessageMarker>>,
29    /// ID of the channel in which user content was posted.
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub channel_id: Option<Id<ChannelMarker>>,
32    /// User generated text content.
33    ///
34    /// Requires [`Intents::MESSAGE_CONTENT`].
35    ///
36    /// [`Intents::MESSAGE_CONTENT`]: crate::gateway::Intents::MESSAGE_CONTENT
37    pub content: String,
38    /// ID of the guild in which action was executed.
39    pub guild_id: Id<GuildMarker>,
40    /// Substring in content that triggered the rule.
41    ///
42    /// Requires [`Intents::MESSAGE_CONTENT`].
43    ///
44    /// [`Intents::MESSAGE_CONTENT`]: crate::gateway::Intents::MESSAGE_CONTENT
45    pub matched_content: Option<String>,
46    /// Word or phrase configured in the rule that triggered the rule.
47    pub matched_keyword: Option<String>,
48    /// ID of any user message which content belongs to.
49    ///
50    /// Will not exist if message was blocked by AutoMod or content was not part
51    /// of any message.
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub message_id: Option<Id<MessageMarker>>,
54    /// ID of the rule which action belongs to.
55    pub rule_id: Id<AutoModerationRuleMarker>,
56    /// Type of rule which was triggered.
57    pub rule_trigger_type: AutoModerationTriggerType,
58    /// ID of the user which generated the content which triggered the rule.
59    pub user_id: Id<UserMarker>,
60}
61
62#[cfg(test)]
63mod tests {
64    use super::AutoModerationActionExecution;
65    use crate::{
66        guild::auto_moderation::{
67            AutoModerationAction, AutoModerationActionType, AutoModerationTriggerType,
68        },
69        id::{
70            marker::{
71                AutoModerationRuleMarker, ChannelMarker, GuildMarker, MessageMarker, UserMarker,
72            },
73            Id,
74        },
75    };
76    use serde::{Deserialize, Serialize};
77    use serde_test::Token;
78    use static_assertions::{assert_fields, assert_impl_all};
79    use std::{fmt::Debug, hash::Hash};
80
81    assert_fields!(
82        AutoModerationActionExecution: action,
83        alert_system_message_id,
84        channel_id,
85        content,
86        guild_id,
87        matched_content,
88        matched_keyword,
89        message_id,
90        rule_id,
91        rule_trigger_type,
92        user_id
93    );
94    assert_impl_all!(
95        AutoModerationActionExecution: Clone,
96        Debug,
97        Deserialize<'static>,
98        Eq,
99        Hash,
100        PartialEq,
101        Serialize,
102        Send,
103        Sync
104    );
105
106    #[test]
107    fn action_execution() {
108        const ALERT_SYSTEM_MESSAGE_ID: Id<MessageMarker> = Id::new(1);
109        const CHANNEL_ID: Id<ChannelMarker> = Id::new(2);
110        const GUILD_ID: Id<GuildMarker> = Id::new(3);
111        const MESSAGE_ID: Id<MessageMarker> = Id::new(4);
112        const RULE_ID: Id<AutoModerationRuleMarker> = Id::new(5);
113        const USER_ID: Id<UserMarker> = Id::new(6);
114
115        let value = AutoModerationActionExecution {
116            action: AutoModerationAction {
117                kind: AutoModerationActionType::BlockMessage,
118                metadata: None,
119            },
120            alert_system_message_id: Some(ALERT_SYSTEM_MESSAGE_ID),
121            channel_id: Some(CHANNEL_ID),
122            content: "darn".into(),
123            guild_id: GUILD_ID,
124            matched_content: Some("darn".into()),
125            matched_keyword: Some("darn".into()),
126            message_id: Some(MESSAGE_ID),
127            rule_id: RULE_ID,
128            rule_trigger_type: AutoModerationTriggerType::Keyword,
129            user_id: USER_ID,
130        };
131
132        serde_test::assert_tokens(
133            &value,
134            &[
135                Token::Struct {
136                    name: "AutoModerationActionExecution",
137                    len: 11,
138                },
139                Token::Str("action"),
140                Token::Struct {
141                    name: "AutoModerationAction",
142                    len: 1,
143                },
144                Token::Str("type"),
145                Token::U8(u8::from(AutoModerationActionType::BlockMessage)),
146                Token::StructEnd,
147                Token::Str("alert_system_message_id"),
148                Token::Some,
149                Token::NewtypeStruct { name: "Id" },
150                Token::Str("1"),
151                Token::Str("channel_id"),
152                Token::Some,
153                Token::NewtypeStruct { name: "Id" },
154                Token::Str("2"),
155                Token::Str("content"),
156                Token::Str("darn"),
157                Token::Str("guild_id"),
158                Token::NewtypeStruct { name: "Id" },
159                Token::Str("3"),
160                Token::Str("matched_content"),
161                Token::Some,
162                Token::Str("darn"),
163                Token::Str("matched_keyword"),
164                Token::Some,
165                Token::Str("darn"),
166                Token::Str("message_id"),
167                Token::Some,
168                Token::NewtypeStruct { name: "Id" },
169                Token::Str("4"),
170                Token::Str("rule_id"),
171                Token::NewtypeStruct { name: "Id" },
172                Token::Str("5"),
173                Token::Str("rule_trigger_type"),
174                Token::U8(u8::from(AutoModerationTriggerType::Keyword)),
175                Token::Str("user_id"),
176                Token::NewtypeStruct { name: "Id" },
177                Token::Str("6"),
178                Token::StructEnd,
179            ],
180        );
181    }
182}