From f066b3fd2a3b2de11b4d91769e3c789383b1fd85 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Tue, 21 Mar 2023 10:51:34 +0100 Subject: [PATCH] [eventsub] Add `shoutout_created` event Signed-off-by: Knut Ahlers --- events.go | 1 + pkg/twitch/eventsub.go | 17 +++++++++++++++++ scopes.go | 2 +- twitchWatcher.go | 26 ++++++++++++++++++++++++++ wiki/Events.md | 11 +++++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/events.go b/events.go index c4e5519..1cc26b9 100644 --- a/events.go +++ b/events.go @@ -32,6 +32,7 @@ var ( eventTypePermit = ptrStr("permit") eventTypeRaid = ptrStr("raid") eventTypeResub = ptrStr("resub") + eventTypeShoutoutCreated = ptrStr("shoutout_created") eventTypeShoutoutReceived = ptrStr("shoutout_received") eventTypeSubgift = ptrStr("subgift") eventTypeSubmysterygift = ptrStr("submysterygift") diff --git a/pkg/twitch/eventsub.go b/pkg/twitch/eventsub.go index 9bc5d77..82c60a6 100644 --- a/pkg/twitch/eventsub.go +++ b/pkg/twitch/eventsub.go @@ -46,6 +46,7 @@ const ( EventSubEventTypeChannelFollow = "channel.follow" EventSubEventTypeChannelPointCustomRewardRedemptionAdd = "channel.channel_points_custom_reward_redemption.add" EventSubEventTypeChannelRaid = "channel.raid" + EventSubEventTypeChannelShoutoutCreate = "channel.shoutout.create" EventSubEventTypeChannelShoutoutReceive = "channel.shoutout.receive" EventSubEventTypeChannelUpdate = "channel.update" EventSubEventTypeStreamOffline = "stream.offline" @@ -133,6 +134,22 @@ type ( Viewers int64 `json:"viewers"` } + EventSubEventShoutoutCreated struct { + BroadcasterUserID string `json:"broadcaster_user_id"` + BroadcasterUserLogin string `json:"broadcaster_user_login"` + BroadcasterUserName string `json:"broadcaster_user_name"` + ModeratorUserID string `json:"moderator_user_id"` + ModeratorUserLogin string `json:"moderator_user_login"` + ModeratorUserName string `json:"moderator_user_name"` + ToBroadcasterUserID string `json:"to_broadcaster_user_id"` + ToBroadcasterUserLogin string `json:"to_broadcaster_user_login"` + ToBroadcasterUserName string `json:"to_broadcaster_user_name"` + ViewerCount int64 `json:"viewer_count"` + StartedAt time.Time `json:"started_at"` + CooldownEndsAt time.Time `json:"cooldown_ends_at"` + TargetCooldownEndsAt time.Time `json:"target_cooldown_ends_at"` + } + EventSubEventShoutoutReceived struct { BroadcasterUserID string `json:"broadcaster_user_id"` BroadcasterUserLogin string `json:"broadcaster_user_login"` diff --git a/scopes.go b/scopes.go index a93b6b7..becc094 100644 --- a/scopes.go +++ b/scopes.go @@ -12,7 +12,7 @@ var ( twitch.ScopeChannelManageVIPS: "manage VIPs", twitch.ScopeChannelReadRedemptions: "see channel-point redemptions", twitch.ScopeModeratorReadFollowers: "see who follows this channel", - twitch.ScopeModeratorReadShoutouts: "see shoutouts received", + twitch.ScopeModeratorReadShoutouts: "see shoutouts created / received", } botDefaultScopes = []string{ diff --git a/twitchWatcher.go b/twitchWatcher.go index e652019..3366f89 100644 --- a/twitchWatcher.go +++ b/twitchWatcher.go @@ -143,6 +143,13 @@ func (t *twitchWatcher) getTopicRegistrations(userID string) []topicRegistration AnyScope: true, Hook: t.handleEventSubChannelPointCustomRewardRedemptionAdd, }, + { + Topic: twitch.EventSubEventTypeChannelShoutoutCreate, + Condition: twitch.EventSubCondition{BroadcasterUserID: userID, ModeratorUserID: userID}, + RequiredScopes: []string{twitch.ScopeModeratorManageShoutouts, twitch.ScopeModeratorReadShoutouts}, + AnyScope: true, + Hook: t.handleEventSubShoutoutCreated, + }, { Topic: twitch.EventSubEventTypeChannelShoutoutReceive, Condition: twitch.EventSubCondition{BroadcasterUserID: userID, ModeratorUserID: userID}, @@ -225,6 +232,25 @@ func (t *twitchWatcher) handleEventSubChannelUpdate(m json.RawMessage) error { return nil } +func (t *twitchWatcher) handleEventSubShoutoutCreated(m json.RawMessage) error { + var payload twitch.EventSubEventShoutoutCreated + if err := json.Unmarshal(m, &payload); err != nil { + return errors.Wrap(err, "unmarshalling event") + } + + fields := plugins.FieldCollectionFromData(map[string]any{ + "channel": "#" + payload.BroadcasterUserLogin, + "to_id": payload.ToBroadcasterUserID, + "to": payload.ToBroadcasterUserLogin, + "viewers": payload.ViewerCount, + }) + + log.WithFields(log.Fields(fields.Data())).Info("Shoutout created") + go handleMessage(ircHdl.Client(), nil, eventTypeShoutoutCreated, fields) + + return nil +} + func (t *twitchWatcher) handleEventSubShoutoutReceived(m json.RawMessage) error { var payload twitch.EventSubEventShoutoutReceived if err := json.Unmarshal(m, &payload); err != nil { diff --git a/wiki/Events.md b/wiki/Events.md index 1533440..c92dc4a 100644 --- a/wiki/Events.md +++ b/wiki/Events.md @@ -149,6 +149,17 @@ Fields: - `subscribed_months` - How long have they been subscribed - `username` - The login-name of the user who resubscribed +## `shoutout_created` + +The channel gave another streamer a (Twitch native) shoutout + +Fields: + +- `channel` - The channel the event occurred in +- `to_id` - The ID of the channel who received the shoutout +- `to` - The login-name of the channel who received the shoutout +- `viewers` - The amount of viewers the shoutout was shown to + ## `shoutout_received` The channel received a (Twitch native) shoutout by another channel.