Skip to content

Commit

Permalink
feat: implement remaining automod.* topics
Browse files Browse the repository at this point in the history
  • Loading branch information
Nerixyz committed Nov 3, 2024
1 parent c00fb19 commit d14a2d5
Show file tree
Hide file tree
Showing 9 changed files with 568 additions and 4 deletions.
19 changes: 19 additions & 0 deletions src/eventsub/automod/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ use crate::types;
use serde_derive::{Deserialize, Serialize};

pub mod hold;
pub mod update;

#[doc(inline)]
pub use hold::{AutomodMessageHoldV1, AutomodMessageHoldV1Payload};
#[doc(inline)]
pub use update::{AutomodMessageUpdateV1, AutomodMessageUpdateV1Payload};

/// A message's Automod status
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "snake_case")]
pub enum AutomodMessageStatus {
/// The message was approved (shown in chat)
Approved,
/// The message was denied (not shown in chat)
Denied,
/// The message is too old, it can't be acted upon anymore.
Expired,
/// An unknown Automod message status, contains the raw string provided by Twitch.
#[serde(untagged)]
Unknown(String),
}
150 changes: 150 additions & 0 deletions src/eventsub/automod/message/update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#![doc(alias = "automod.message.update")]
//! a message in the automod queue had its status changed
use super::*;
/// [`automod.message.update`](https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types/#automodmessageupdate): a message in the automod queue had its status changed.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "typed-builder", derive(typed_builder::TypedBuilder))]
#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct AutomodMessageUpdateV1 {
/// User ID of the broadcaster (channel). Maximum: 1
#[cfg_attr(feature = "typed-builder", builder(setter(into)))]
pub broadcaster_user_id: types::UserId,
/// User ID of the moderator.
#[cfg_attr(feature = "typed-builder", builder(setter(into)))]
pub moderator_user_id: types::UserId,
}

impl AutomodMessageUpdateV1 {
/// Get automod update notifications for messages in this channel as a moderator
pub fn new(
broadcaster_user_id: impl Into<types::UserId>,
moderator_user_id: impl Into<types::UserId>,
) -> Self {
Self {
broadcaster_user_id: broadcaster_user_id.into(),
moderator_user_id: moderator_user_id.into(),
}
}

Check warning on line 29 in src/eventsub/automod/message/update.rs

View check run for this annotation

Codecov / codecov/patch

src/eventsub/automod/message/update.rs#L21-L29

Added lines #L21 - L29 were not covered by tests
}

impl EventSubscription for AutomodMessageUpdateV1 {
type Payload = AutomodMessageUpdateV1Payload;

const EVENT_TYPE: EventType = EventType::AutomodMessageUpdate;
#[cfg(feature = "twitch_oauth2")]
const SCOPE: twitch_oauth2::Validator =
twitch_oauth2::validator![twitch_oauth2::Scope::ModeratorManageAutoMod];
const VERSION: &'static str = "1";
}

/// [`automod.message.update`](AutomodMessageUpdateV1) response payload.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct AutomodMessageUpdateV1Payload {
/// The ID of the broadcaster specified in the request.
pub broadcaster_user_id: types::UserId,
/// The login of the broadcaster specified in the request.
pub broadcaster_user_login: types::UserName,
/// The user name of the broadcaster specified in the request.
pub broadcaster_user_name: types::DisplayName,

/// The message sender’s user ID.
pub user_id: types::UserId,
/// The message sender’s login name.
pub user_login: types::UserName,
/// The message sender’s display name.
pub user_name: types::DisplayName,

/// The ID of the moderator.
pub moderator_user_id: types::UserId,
/// The login of the moderator.
pub moderator_user_login: types::UserName,
/// The moderator’s user name.
pub moderator_user_name: types::DisplayName,

/// The ID of the message that was flagged by automod.
pub message_id: types::MsgId,
/// The body of the message.
pub message: crate::eventsub::channel::chat::Message,
/// The category of the message.
pub category: super::AutomodCategory,
/// The level of severity. Measured between 1 to 4.
pub level: u8,
/// The message’s status.
pub status: AutomodMessageStatus,
/// The timestamp of when automod saved the message.
pub held_at: types::Timestamp,
}

#[cfg(test)]
#[test]
fn parse_payload() {
use crate::eventsub::{Event, Message};

let payload = r##"
{
"subscription": {
"id": "79cc58a2-1c34-48e0-97fe-126d5d77bf10",
"status": "enabled",
"type": "automod.message.update",
"version": "1",
"condition": {
"broadcaster_user_id": "129546453",
"moderator_user_id": "129546453"
},
"transport": {
"method": "websocket",
"session_id": "AgoQZ12VWLotRG6u3pudLlbhvhIGY2VsbC1j"
},
"created_at": "2024-11-03T11:52:04.695680375Z",
"cost": 0
},
"event": {
"broadcaster_user_id": "129546453",
"broadcaster_user_login": "nerixyz",
"broadcaster_user_name": "nerixyz",
"user_id": "489584266",
"user_login": "uint128",
"user_name": "uint128",
"moderator_user_id": "129546453",
"moderator_user_login": "nerixyz",
"moderator_user_name": "nerixyz",
"message_id": "8b722958-741f-4013-8a8b-c7793d3aef9f",
"message": {
"text": "boobs",
"fragments": [
{
"type": "text",
"text": "boobs",
"cheermote": null,
"emote": null
}
]
},
"category": "sexwords",
"level": 4,
"status": "approved",
"held_at": "2024-11-03T11:53:45.331308397Z"
}
}
"##;

let val = Event::parse(payload).unwrap();
crate::tests::roundtrip(&val);

let Event::AutomodMessageUpdateV1(val) = val else {
panic!("invalid event type");

Check warning on line 139 in src/eventsub/automod/message/update.rs

View check run for this annotation

Codecov / codecov/patch

src/eventsub/automod/message/update.rs#L139

Added line #L139 was not covered by tests
};
let Message::Notification(notif) = val.message else {
panic!("invalid message type");

Check warning on line 142 in src/eventsub/automod/message/update.rs

View check run for this annotation

Codecov / codecov/patch

src/eventsub/automod/message/update.rs#L142

Added line #L142 was not covered by tests
};

assert_eq!(notif.broadcaster_user_id.as_str(), "129546453");
assert_eq!(notif.category, AutomodCategory::Sexwords);
assert_eq!(notif.level, 4);
assert_eq!(notif.status, AutomodMessageStatus::Approved);
assert_eq!(notif.message.fragments.len(), 1);
}
10 changes: 10 additions & 0 deletions src/eventsub/automod/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ use super::{EventSubscription, EventType};
use serde_derive::{Deserialize, Serialize};

pub mod message;
pub mod settings;
pub mod terms;

#[doc(inline)]
pub use message::{AutomodMessageHoldV1, AutomodMessageHoldV1Payload};
#[doc(inline)]
pub use message::{AutomodMessageUpdateV1, AutomodMessageUpdateV1Payload};

#[doc(inline)]
pub use terms::{AutomodTermsUpdateV1, AutomodTermsUpdateV1Payload};

#[doc(inline)]
pub use settings::{AutomodSettingsUpdateV1, AutomodSettingsUpdateV1Payload};

/// A category identified by automod for a message.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
Expand Down
10 changes: 10 additions & 0 deletions src/eventsub/automod/settings/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![doc(alias = "automod.settings")]
//! Events for Automod settings
use super::{EventSubscription, EventType};
use crate::types;
use serde_derive::{Deserialize, Serialize};

pub mod update;

#[doc(inline)]
pub use update::{AutomodSettingsUpdateV1, AutomodSettingsUpdateV1Payload};
Loading

0 comments on commit d14a2d5

Please sign in to comment.