diff --git a/CHANGELOG.md b/CHANGELOG.md index c18fc99a..a1e08b09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,7 @@ - Bugfix: Fixed color input thinking blue is also red. (#5982) - Bugfix: Fixed an issue where commands would sometimes reset if Chatterino was improperly shut down. (#6011) - Dev: Subscriptions to PubSub channel points redemption topics now use no auth token, making it continue to work during PubSub shutdown. (#5947) -- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916, #5930, #5935, #5932, #5943, #5952, #5953, #5968, #5973, #5974, #5980, #5981, #5985, #5990, #5992, #5993, #5996, #5995, #6000, #6001, #6002, #6003, #6005, #6007, #6010, #6008) +- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916, #5930, #5935, #5932, #5943, #5952, #5953, #5968, #5973, #5974, #5980, #5981, #5985, #5990, #5992, #5993, #5996, #5995, #6000, #6001, #6002, #6003, #6005, #6007, #6010, #6008, #6012) - Dev: Remove unneeded platform specifier for toasts. (#5914) - Dev: Highlight checks now use non-capturing groups for the boundaries. (#5784) - Dev: Removed unused PubSub whisper code. (#5898) diff --git a/src/providers/twitch/TwitchChannel.cpp b/src/providers/twitch/TwitchChannel.cpp index 58e36d68..4707e21c 100644 --- a/src/providers/twitch/TwitchChannel.cpp +++ b/src/providers/twitch/TwitchChannel.cpp @@ -1554,6 +1554,22 @@ void TwitchChannel::refreshPubSub() }, }, }); + this->eventSubSuspiciousUserUpdateHandle = + getApp()->getEventSub()->subscribe(eventsub::SubscriptionRequest{ + .subscriptionType = "channel.suspicious_user.update", + .subscriptionVersion = "1", + .conditions = + { + { + "broadcaster_user_id", + roomId, + }, + { + "moderator_user_id", + currentAccount->getUserId(), + }, + }, + }); this->eventSubChannelChatUserMessageHoldHandle.reset(); this->eventSubChannelChatUserMessageUpdateHandle.reset(); @@ -1564,6 +1580,7 @@ void TwitchChannel::refreshPubSub() this->eventSubAutomodMessageHoldHandle.reset(); this->eventSubAutomodMessageUpdateHandle.reset(); this->eventSubSuspiciousUserMessageHandle.reset(); + this->eventSubSuspiciousUserUpdateHandle.reset(); this->eventSubChannelChatUserMessageHoldHandle = getApp()->getEventSub()->subscribe(eventsub::SubscriptionRequest{ diff --git a/src/providers/twitch/TwitchChannel.hpp b/src/providers/twitch/TwitchChannel.hpp index 334bcfca..968934e0 100644 --- a/src/providers/twitch/TwitchChannel.hpp +++ b/src/providers/twitch/TwitchChannel.hpp @@ -512,6 +512,7 @@ private: eventsub::SubscriptionHandle eventSubAutomodMessageHoldHandle; eventsub::SubscriptionHandle eventSubAutomodMessageUpdateHandle; eventsub::SubscriptionHandle eventSubSuspiciousUserMessageHandle; + eventsub::SubscriptionHandle eventSubSuspiciousUserUpdateHandle; eventsub::SubscriptionHandle eventSubChannelChatUserMessageHoldHandle; eventsub::SubscriptionHandle eventSubChannelChatUserMessageUpdateHandle; diff --git a/src/providers/twitch/eventsub/Connection.cpp b/src/providers/twitch/eventsub/Connection.cpp index 9bef7f0c..422096b3 100644 --- a/src/providers/twitch/eventsub/Connection.cpp +++ b/src/providers/twitch/eventsub/Connection.cpp @@ -300,9 +300,25 @@ void Connection::onChannelSuspiciousUserUpdate( const lib::messages::Metadata &metadata, const lib::payload::channel_suspicious_user_update::v1::Payload &payload) { - (void)metadata; - qCDebug(LOG) << "On channel suspicious user update for" - << payload.event.broadcasterUserLogin.qt(); + auto *channel = dynamic_cast( + getApp() + ->getTwitch() + ->getChannelOrEmpty(payload.event.broadcasterUserLogin.qt()) + .get()); + if (!channel || channel->isEmpty()) + { + qCDebug(LOG) << "Channel Suspicious User Update for broadcaster we're " + "not interested in" + << payload.event.broadcasterUserLogin.qt(); + return; + } + + auto time = chronoToQDateTime(metadata.messageTimestamp); + auto message = makeSuspiciousUserUpdate(channel, time, payload.event); + + runInGuiThread([channel, message] { + channel->addMessage(message, MessageContext::Original); + }); } void Connection::onChannelChatUserMessageHold( diff --git a/src/providers/twitch/eventsub/MessageBuilder.cpp b/src/providers/twitch/eventsub/MessageBuilder.cpp index 76901a37..d703c103 100644 --- a/src/providers/twitch/eventsub/MessageBuilder.cpp +++ b/src/providers/twitch/eventsub/MessageBuilder.cpp @@ -756,6 +756,50 @@ MessagePtr makeSuspiciousUserMessageBody( return builder.release(); } +MessagePtr makeSuspiciousUserUpdate( + TwitchChannel *channel, const QDateTime &time, + const lib::payload::channel_suspicious_user_update::v1::Event &event) +{ + EventSubMessageBuilder builder(channel, time); + builder->flags.set(MessageFlag::DoNotTriggerNotification); + builder->loginName = event.moderatorUserLogin.qt(); + + QString text; + builder.appendUser(event.moderatorUserName, event.moderatorUserLogin, text); + + switch (event.lowTrustStatus) + { + case lib::suspicious_users::Status::None: { + builder.emplaceSystemTextAndUpdate(u"removed"_s, text); + builder.appendUser(event.userName, event.userLogin, text); + builder.emplaceSystemTextAndUpdate( + u"from the suspicious user list."_s, text); + } + break; + + case lib::suspicious_users::Status::ActiveMonitoring: { + builder.emplaceSystemTextAndUpdate(u"added"_s, text); + builder.appendUser(event.userName, event.userLogin, text); + builder.emplaceSystemTextAndUpdate( + u"as a monitored suspicious chatter."_s, text); + } + break; + + case lib::suspicious_users::Status::Restricted: { + builder.emplaceSystemTextAndUpdate(u"added"_s, text); + builder.appendUser(event.userName, event.userLogin, text); + builder.emplaceSystemTextAndUpdate( + u"as a restricted suspicious chatter."_s, text); + } + break; + } + + builder->messageText = text; + builder->searchText = text; + + return builder.release(); +} + MessagePtr makeUserMessageHeldMessage( TwitchChannel *channel, const QDateTime &time, const lib::payload::channel_chat_user_message_hold::v1::Event &event) diff --git a/src/providers/twitch/eventsub/MessageBuilder.hpp b/src/providers/twitch/eventsub/MessageBuilder.hpp index 7c75da08..956d2b54 100644 --- a/src/providers/twitch/eventsub/MessageBuilder.hpp +++ b/src/providers/twitch/eventsub/MessageBuilder.hpp @@ -7,6 +7,7 @@ #include "twitch-eventsub-ws/payloads/channel-chat-user-message-update-v1.hpp" #include "twitch-eventsub-ws/payloads/channel-moderate-v2.hpp" #include "twitch-eventsub-ws/payloads/channel-suspicious-user-message-v1.hpp" +#include "twitch-eventsub-ws/payloads/channel-suspicious-user-update-v1.hpp" #include @@ -167,6 +168,10 @@ MessagePtr makeSuspiciousUserMessageBody( TwitchChannel *channel, const QDateTime &time, const lib::payload::channel_suspicious_user_message::v1::Event &event); +MessagePtr makeSuspiciousUserUpdate( + TwitchChannel *channel, const QDateTime &time, + const lib::payload::channel_suspicious_user_update::v1::Event &event); + MessagePtr makeUserMessageHeldMessage( TwitchChannel *channel, const QDateTime &time, const lib::payload::channel_chat_user_message_hold::v1::Event &event); diff --git a/tests/snapshots/EventSub/channel-suspicious-user-update/monitored.json b/tests/snapshots/EventSub/channel-suspicious-user-update/monitored.json new file mode 100644 index 00000000..946669d4 --- /dev/null +++ b/tests/snapshots/EventSub/channel-suspicious-user-update/monitored.json @@ -0,0 +1,134 @@ +{ + "input": { + "broadcaster_user_id": "11148817", + "broadcaster_user_login": "pajlada", + "broadcaster_user_name": "pajlada", + "low_trust_status": "monitored", + "moderator_user_id": "489584266", + "moderator_user_login": "uint128", + "moderator_user_name": "uint128", + "user_id": "129546453", + "user_login": "nerixyz", + "user_name": "nerixyz" + }, + "output": [ + { + "badgeInfos": { + }, + "badges": [ + ], + "channelName": "", + "count": 1, + "displayName": "", + "elements": [ + { + "element": { + "color": "System", + "flags": "Timestamp", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "12:31" + ] + }, + "flags": "Timestamp", + "format": "", + "link": { + "type": "None", + "value": "" + }, + "time": "12:31:47", + "tooltip": "", + "trailingSpace": true, + "type": "TimestampElement" + }, + { + "color": "Text", + "fallbackColor": "System", + "flags": "Text|Mention", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "MentionElement", + "userColor": "System", + "userLoginName": "uint128", + "words": [ + "uint128" + ] + }, + { + "color": "System", + "flags": "Text", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "removed" + ] + }, + { + "color": "Text", + "fallbackColor": "System", + "flags": "Text|Mention", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "MentionElement", + "userColor": "System", + "userLoginName": "nerixyz", + "words": [ + "nerixyz" + ] + }, + { + "color": "System", + "flags": "Text", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "from", + "the", + "suspicious", + "user", + "list." + ] + } + ], + "flags": "System|Timeout|DoNotTriggerNotification|EventSub", + "id": "", + "localizedName": "", + "loginName": "uint128", + "messageText": "uint128 removed nerixyz from the suspicious user list. ", + "searchText": "uint128 removed nerixyz from the suspicious user list. ", + "serverReceivedTime": "2024-05-14T12:31:47Z", + "timeoutUser": "", + "userID": "", + "usernameColor": "#ff000000" + } + ] +} diff --git a/tests/snapshots/EventSub/channel-suspicious-user-update/no-treatment.json b/tests/snapshots/EventSub/channel-suspicious-user-update/no-treatment.json new file mode 100644 index 00000000..1b686bf1 --- /dev/null +++ b/tests/snapshots/EventSub/channel-suspicious-user-update/no-treatment.json @@ -0,0 +1,134 @@ +{ + "input": { + "broadcaster_user_id": "11148817", + "broadcaster_user_login": "pajlada", + "broadcaster_user_name": "pajlada", + "low_trust_status": "no_treatment", + "moderator_user_id": "489584266", + "moderator_user_login": "uint128", + "moderator_user_name": "uint128", + "user_id": "129546453", + "user_login": "nerixyz", + "user_name": "nerixyz" + }, + "output": [ + { + "badgeInfos": { + }, + "badges": [ + ], + "channelName": "", + "count": 1, + "displayName": "", + "elements": [ + { + "element": { + "color": "System", + "flags": "Timestamp", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "12:31" + ] + }, + "flags": "Timestamp", + "format": "", + "link": { + "type": "None", + "value": "" + }, + "time": "12:31:47", + "tooltip": "", + "trailingSpace": true, + "type": "TimestampElement" + }, + { + "color": "Text", + "fallbackColor": "System", + "flags": "Text|Mention", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "MentionElement", + "userColor": "System", + "userLoginName": "uint128", + "words": [ + "uint128" + ] + }, + { + "color": "System", + "flags": "Text", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "removed" + ] + }, + { + "color": "Text", + "fallbackColor": "System", + "flags": "Text|Mention", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "MentionElement", + "userColor": "System", + "userLoginName": "nerixyz", + "words": [ + "nerixyz" + ] + }, + { + "color": "System", + "flags": "Text", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "from", + "the", + "suspicious", + "user", + "list." + ] + } + ], + "flags": "System|Timeout|DoNotTriggerNotification|EventSub", + "id": "", + "localizedName": "", + "loginName": "uint128", + "messageText": "uint128 removed nerixyz from the suspicious user list. ", + "searchText": "uint128 removed nerixyz from the suspicious user list. ", + "serverReceivedTime": "2024-05-14T12:31:47Z", + "timeoutUser": "", + "userID": "", + "usernameColor": "#ff000000" + } + ] +} diff --git a/tests/snapshots/EventSub/channel-suspicious-user-update/restricted.json b/tests/snapshots/EventSub/channel-suspicious-user-update/restricted.json new file mode 100644 index 00000000..a5f80244 --- /dev/null +++ b/tests/snapshots/EventSub/channel-suspicious-user-update/restricted.json @@ -0,0 +1,134 @@ +{ + "input": { + "broadcaster_user_id": "11148817", + "broadcaster_user_login": "pajlada", + "broadcaster_user_name": "pajlada", + "low_trust_status": "restricted", + "moderator_user_id": "489584266", + "moderator_user_login": "uint128", + "moderator_user_name": "uint128", + "user_id": "129546453", + "user_login": "nerixyz", + "user_name": "nerixyz" + }, + "output": [ + { + "badgeInfos": { + }, + "badges": [ + ], + "channelName": "", + "count": 1, + "displayName": "", + "elements": [ + { + "element": { + "color": "System", + "flags": "Timestamp", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "12:31" + ] + }, + "flags": "Timestamp", + "format": "", + "link": { + "type": "None", + "value": "" + }, + "time": "12:31:47", + "tooltip": "", + "trailingSpace": true, + "type": "TimestampElement" + }, + { + "color": "Text", + "fallbackColor": "System", + "flags": "Text|Mention", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "MentionElement", + "userColor": "System", + "userLoginName": "uint128", + "words": [ + "uint128" + ] + }, + { + "color": "System", + "flags": "Text", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "added" + ] + }, + { + "color": "Text", + "fallbackColor": "System", + "flags": "Text|Mention", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "MentionElement", + "userColor": "System", + "userLoginName": "nerixyz", + "words": [ + "nerixyz" + ] + }, + { + "color": "System", + "flags": "Text", + "link": { + "type": "None", + "value": "" + }, + "style": "ChatMedium", + "tooltip": "", + "trailingSpace": true, + "type": "TextElement", + "words": [ + "as", + "a", + "restricted", + "suspicious", + "chatter." + ] + } + ], + "flags": "System|Timeout|DoNotTriggerNotification|EventSub", + "id": "", + "localizedName": "", + "loginName": "uint128", + "messageText": "uint128 added nerixyz as a restricted suspicious chatter. ", + "searchText": "uint128 added nerixyz as a restricted suspicious chatter. ", + "serverReceivedTime": "2024-05-14T12:31:47Z", + "timeoutUser": "", + "userID": "", + "usernameColor": "#ff000000" + } + ] +} diff --git a/tests/src/EventSubMessages.cpp b/tests/src/EventSubMessages.cpp index c6084a15..723dc75c 100644 --- a/tests/src/EventSubMessages.cpp +++ b/tests/src/EventSubMessages.cpp @@ -120,6 +120,25 @@ const std::map "cost": 0 })", }, + { + "channel-suspicious-user-update", + R"({ + "id": "a3122e32-6498-4847-8675-109b9b94f29c", + "status": "enabled", + "type": "channel.suspicious_user.update", + "version": "1", + "condition": { + "broadcaster_user_id": "489584266", + "moderator_user_id": "489584266" + }, + "transport": { + "method":"websocket", + "session_id":"AgoQ59RRLw0mS6S000QtK8f54BIGY2VsbC1j" + }, + "created_at": "2025-02-28T15:55:37.85489173Z", + "cost": 0 + })", + }, { "channel-chat-user-message-hold", R"({