Skip to content

Commit

Permalink
fix(parsing): SubMysteryGift missing tag during SUBtember (#216)
Browse files Browse the repository at this point in the history
* fix(parsing): SubMysteryGift missing tag during SUBtember

- Tag `msg-param-sender-count` is missing during (some?) promotions
- Only seen with sender twitch, therefore handled as an edge case
- If sent by twitch and the tag is missing, then assume u64::MAX

* breaking(usernotice): Make sender_total_gifts optional

* docs(changelog): Correct Markdown linter warnings

* docs(usernotice): remove reference of SubMysteryGift being both submysterygift and anonsubmysterygift as it not anymore
  • Loading branch information
Larandar authored Oct 26, 2024
1 parent a3a3dd2 commit 5996f13
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 17 deletions.
12 changes: 7 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Version numbers follow [Semantic Versioning](https://semver.org/).
- Breaking: Removed `ban()`, `unban()`, `timeout()` and `untimeout()` since they are no longer supported by Twitch.
They were previously deprecated in v4.1.0 (#197)
- Breaking: Fixed typo in RoomStateMessage's follower mode (was `follwers_only`, is now `followers_only`. (#200)
- Breaking: `SubMysteryGift::sender_total_gifts` is now an `Option` because the tag is missing
when Twitch gift subs during SUBtember (#215)
- Minor: Added support for reply-parent tags (#189)
- Minor: Tokens in `CredentialsPair` and `UserAccessToken` are now redacted in their `Debug` output. Same
applies to the `client_secret` in `RefreshingLoginCredentials`. (#199)
Expand Down Expand Up @@ -57,7 +59,7 @@ Version numbers follow [Semantic Versioning](https://semver.org/).

## v4.1.0

- Minor: Mark `ban`, `unban`, `timeout` and `untimeout` methods as deprecated (Due to Twitch removing support for these commands on 2023-02-18: https://discuss.dev.twitch.tv/t/deprecation-of-chat-commands-through-irc/40486) (#181)
- Minor: Mark `ban`, `unban`, `timeout` and `untimeout` methods as deprecated (Due to Twitch removing support for these commands on 2023-02-18: <https://discuss.dev.twitch.tv/t/deprecation-of-chat-commands-through-irc/40486>) (#181)

## v4.0.0

Expand All @@ -81,9 +83,9 @@ Version numbers follow [Semantic Versioning](https://semver.org/).

## v3.0.0

- Breaking: Transports were refactored slightly:
Renamed `twitch_irc::TCPTransport` to `SecureTCPTransport`, added `PlainTCPTransport` for plain-text IRC connections.
Renamed `twitch_irc::WSSTransport` to `SecureWSTransport`, added `PlainWSTransport` for plain-text IRC-over-WebSocket-connections.
- Breaking: Transports were refactored slightly:
Renamed `twitch_irc::TCPTransport` to `SecureTCPTransport`, added `PlainTCPTransport` for plain-text IRC connections.
Renamed `twitch_irc::WSSTransport` to `SecureWSTransport`, added `PlainWSTransport` for plain-text IRC-over-WebSocket-connections.
Refactored feature flags: This crate used to only have the `transport-tcp` and `transport-wss` feature flags. The following is the new list of feature flags relevant to transports:
- `transport-tcp` enables `PlainTCPTransport`
- `transport-tcp-native-tls` enables `SecureTCPTransport` using OS-native TLS functionality (and using the root certificates configured in your operating system).
Expand All @@ -92,7 +94,7 @@ Version numbers follow [Semantic Versioning](https://semver.org/).
- `transport-ws` (notice this is now `ws` instead of `wss`) - Enables `PlainWSTransport`
- `transport-ws-native-tls` - Enables `SecureWSTransport` using native TLS (same as above)
- `transport-ws-rustls-webpki-roots` - Enables `SecureWSTransport` using rustls with Mozilla's root certificates (same as above)

Some accompanying items have also been made `pub` in the crate.
- Breaking: Updated `metrics` to version 0.16.
- Minor: Added `timeout`, `untimeout`, `ban` and `unban` methods to `TwitchIRCClient` (#110)
Expand Down
55 changes: 43 additions & 12 deletions src/message/commands/usernotice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,21 +209,13 @@ pub enum UserNoticeEvent {

/// This event precedes a wave of `subgift`/`anonsubgift` messages.
/// (`<User> is gifting <mass_gift_count> Tier 1 Subs to <Channel>'s community! They've gifted a total of <sender_total_gifts> in the channel!`)
///
/// This event combines `submysterygift` and `anonsubmysterygift`. In case of
/// `anonsubmysterygift` the sending user of the `USERNOTICE` carries no useful information,
/// it can be e.g. the channel owner or a service user like `AnAnonymousGifter`. You should
/// always check for `is_sender_anonymous` before using the sender of the `USERNOTICE`.
SubMysteryGift {
/// Indicates whether the user sending this `USERNOTICE` is a dummy or a real gifter.
/// If this is `true` the gift comes from an anonymous user, and the user sending the
/// `USERNOTICE` carries no useful information and should be ignored.
/// Number of gifts the sender just gifted.
mass_gift_count: u64,
/// Total number of gifts the sender has gifted in this channel. This includes the
/// number of gifts in this `submysterygift` or `anonsubmysterygift`.
/// Note tha
sender_total_gifts: u64,
/// Present in most case, but notably missing when Twitch match gifted subs during SUBtember.
sender_total_gifts: Option<u64>,
/// The type of sub plan the recipients were gifted.
/// `1000`, `2000` or `3000`, referring to tier 1, 2 or 3 subs respectively.
sub_plan: String,
Expand Down Expand Up @@ -424,7 +416,14 @@ impl TryFrom<IRCMessage> for UserNoticeMessage {
// this takes over all other cases of submysterygift.
"submysterygift" => UserNoticeEvent::SubMysteryGift {
mass_gift_count: source.try_get_number("msg-param-mass-gift-count")?,
sender_total_gifts: source.try_get_number("msg-param-sender-count")?,
sender_total_gifts: if sender.login != "twitch" {
Some(source.try_get_number("msg-param-sender-count")?)
} else {
// - this seems to be missing if sender the sender is twitch (user-id=12826) on subtembers
source
.try_get_number("msg-param-sender-count")
.map_or_else(|_| None, |v| Some(v))
},
sub_plan: source
.try_get_nonempty_tag_value("msg-param-sub-plan")?
.to_owned(),
Expand Down Expand Up @@ -775,7 +774,39 @@ mod tests {
msg.event,
UserNoticeEvent::SubMysteryGift {
mass_gift_count: 20,
sender_total_gifts: 100,
sender_total_gifts: Some(100),
sub_plan: "1000".to_owned(),
}
)
}

#[test]
pub fn test_submysterygift_twitch() {
let src = "@badge-info=;badges=sub-gifter/50;color=;display-name=twitch;emotes=;flags=;id=049e6371-7023-4fca-8605-7dec60e72e12;login=twitch;mod=0;msg-id=submysterygift;msg-param-mass-gift-count=20;msg-param-sender-count=50;msg-param-origin-id=1f\\sbe\\sbb\\s4a\\s81\\s9a\\s65\\sd1\\s4b\\s77\\sf5\\s23\\s16\\s4a\\sd3\\s13\\s09\\se7\\sbe\\s55;msg-param-sub-plan=1000;room-id=71092938;subscriber=0;system-msg=AdamAtReflectStudios\\sis\\sgifting\\s20\\sTier\\s1\\sSubs\\sto\\sxQcOW's\\scommunity!\\sThey've\\sgifted\\sa\\stotal\\sof\\s100\\sin\\sthe\\schannel!;tmi-sent-ts=1594583777669;user-id=12826;user-type= :tmi.twitch.tv USERNOTICE #xqcow";
let irc_message = IRCMessage::parse(src).unwrap();
let msg = UserNoticeMessage::try_from(irc_message).unwrap();

assert_eq!(
msg.event,
UserNoticeEvent::SubMysteryGift {
mass_gift_count: 20,
sender_total_gifts: Some(50),
sub_plan: "1000".to_owned(),
}
)
}

#[test]
pub fn test_submysterygift_twitch_missing_count() {
let src = "@badge-info=;badges=sub-gifter/50;color=;display-name=twitch;emotes=;flags=;id=049e6371-7023-4fca-8605-7dec60e72e12;login=twitch;mod=0;msg-id=submysterygift;msg-param-mass-gift-count=20;msg-param-origin-id=1f\\sbe\\sbb\\s4a\\s81\\s9a\\s65\\sd1\\s4b\\s77\\sf5\\s23\\s16\\s4a\\sd3\\s13\\s09\\se7\\sbe\\s55;msg-param-sub-plan=1000;room-id=71092938;subscriber=0;system-msg=AdamAtReflectStudios\\sis\\sgifting\\s20\\sTier\\s1\\sSubs\\sto\\sxQcOW's\\scommunity!\\sThey've\\sgifted\\sa\\stotal\\sof\\s100\\sin\\sthe\\schannel!;tmi-sent-ts=1594583777669;user-id=12826;user-type= :tmi.twitch.tv USERNOTICE #xqcow";
let irc_message = IRCMessage::parse(src).unwrap();
let msg = UserNoticeMessage::try_from(irc_message).unwrap();

assert_eq!(
msg.event,
UserNoticeEvent::SubMysteryGift {
mass_gift_count: 20,
sender_total_gifts: None,
sub_plan: "1000".to_owned(),
}
)
Expand Down

0 comments on commit 5996f13

Please sign in to comment.