diff --git a/pkg/twitch/eventsub.go b/pkg/twitch/eventsub.go index 6d798ab..7c8ddd2 100644 --- a/pkg/twitch/eventsub.go +++ b/pkg/twitch/eventsub.go @@ -52,6 +52,10 @@ const ( EventSubEventTypeChannelPointCustomRewardRedemptionAdd = "channel.channel_points_custom_reward_redemption.add" EventSubEventTypeUserAuthorizationRevoke = "user.authorization.revoke" + + EventSubTopicVersion1 = "1" + EventSubTopicVersion2 = "2" + EventSubTopicVersionBeta = "beta" ) type ( @@ -340,7 +344,11 @@ func (e *EventSubClient) PreFetchSubscriptions(ctx context.Context) error { return nil } -func (e *EventSubClient) RegisterEventSubHooks(event string, condition EventSubCondition, callback func(json.RawMessage) error) (func(), error) { +func (e *EventSubClient) RegisterEventSubHooks(event, version string, condition EventSubCondition, callback func(json.RawMessage) error) (func(), error) { + if version == "" { + version = EventSubTopicVersion1 + } + condHash, err := condition.Hash() if err != nil { return nil, errors.Wrap(err, "hashing condition") @@ -379,7 +387,7 @@ func (e *EventSubClient) RegisterEventSubHooks(event string, condition EventSubC newSub, err := e.twitchClient.createEventSubSubscription(ctx, eventSubSubscription{ Type: event, - Version: "1", + Version: version, Condition: condition, Transport: eventSubTransport{ Method: "webhook", diff --git a/pkg/twitch/scopes.go b/pkg/twitch/scopes.go index dcb25c3..134bcac 100644 --- a/pkg/twitch/scopes.go +++ b/pkg/twitch/scopes.go @@ -17,6 +17,7 @@ const ( ScopeModeratorManageChatMessages = "moderator:manage:chat_messages" ScopeModeratorManageChatSettings = "moderator:manage:chat_settings" ScopeModeratorManageShoutouts = "moderator:manage:shoutouts" + ScopeModeratorReadFollowers = "moderator:read:followers" ScopeUserManageChatColor = "user:manage:chat_color" // Deprecated v5 scope but used in chat diff --git a/scopes.go b/scopes.go index f757a9e..7ac6191 100644 --- a/scopes.go +++ b/scopes.go @@ -11,6 +11,7 @@ var ( twitch.ScopeChannelManageRaids: "start raids", twitch.ScopeChannelManageVIPS: "manage VIPs", twitch.ScopeChannelReadRedemptions: "see channel-point redemptions", + twitch.ScopeModeratorReadFollowers: "see who follows this channel", } botDefaultScopes = []string{ diff --git a/twitchWatcher.go b/twitchWatcher.go index 500fd70..2ec788c 100644 --- a/twitchWatcher.go +++ b/twitchWatcher.go @@ -18,6 +18,7 @@ type ( RequiredScopes []string AnyScope bool Hook func(json.RawMessage) error + Version string } twitchChannelState struct { @@ -124,8 +125,9 @@ func (t *twitchWatcher) getTopicRegistrations(userID string) []topicRegistration }, { Topic: twitch.EventSubEventTypeChannelFollow, + Version: twitch.EventSubTopicVersion1, // DEPRECATED, to be removed August 3, 2023 Condition: twitch.EventSubCondition{BroadcasterUserID: userID}, - RequiredScopes: nil, + RequiredScopes: nil, // Switch to []string{twitch.ScopeModeratorReadFollowers} after August 3, 2023 Hook: t.handleEventSubChannelFollow, }, { @@ -331,7 +333,7 @@ func (t *twitchWatcher) registerEventSubCallbacks(channel string) (func(), error } } - uf, err := twitchEventSubClient.RegisterEventSubHooks(tr.Topic, tr.Condition, tr.Hook) + uf, err := twitchEventSubClient.RegisterEventSubHooks(tr.Topic, tr.Version, tr.Condition, tr.Hook) if err != nil { logger.WithError(err).Error("Unable to register topic") @@ -356,6 +358,7 @@ func (t *twitchWatcher) registerEventSubCallbacks(channel string) (func(), error func (t *twitchWatcher) registerGlobalHooks() error { _, err := twitchEventSubClient.RegisterEventSubHooks( twitch.EventSubEventTypeUserAuthorizationRevoke, + twitch.EventSubTopicVersion1, twitch.EventSubCondition{ClientID: cfg.TwitchClient}, t.handleEventUserAuthRevoke, )