[editor] Add new moderator:read:followers scope and pin follow subscription version

refs https://discuss.dev.twitch.tv/t/follows-endpoints-and-eventsub-subscription-type-are-now-available-in-open-beta/43322

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2023-02-04 12:25:46 +01:00
parent b29688292d
commit 58f8cb7704
Signed by: luzifer
GPG key ID: D91C3E91E4CAD6F5
4 changed files with 17 additions and 4 deletions

View file

@ -52,6 +52,10 @@ const (
EventSubEventTypeChannelPointCustomRewardRedemptionAdd = "channel.channel_points_custom_reward_redemption.add" EventSubEventTypeChannelPointCustomRewardRedemptionAdd = "channel.channel_points_custom_reward_redemption.add"
EventSubEventTypeUserAuthorizationRevoke = "user.authorization.revoke" EventSubEventTypeUserAuthorizationRevoke = "user.authorization.revoke"
EventSubTopicVersion1 = "1"
EventSubTopicVersion2 = "2"
EventSubTopicVersionBeta = "beta"
) )
type ( type (
@ -340,7 +344,11 @@ func (e *EventSubClient) PreFetchSubscriptions(ctx context.Context) error {
return nil 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() condHash, err := condition.Hash()
if err != nil { if err != nil {
return nil, errors.Wrap(err, "hashing condition") 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{ newSub, err := e.twitchClient.createEventSubSubscription(ctx, eventSubSubscription{
Type: event, Type: event,
Version: "1", Version: version,
Condition: condition, Condition: condition,
Transport: eventSubTransport{ Transport: eventSubTransport{
Method: "webhook", Method: "webhook",

View file

@ -17,6 +17,7 @@ const (
ScopeModeratorManageChatMessages = "moderator:manage:chat_messages" ScopeModeratorManageChatMessages = "moderator:manage:chat_messages"
ScopeModeratorManageChatSettings = "moderator:manage:chat_settings" ScopeModeratorManageChatSettings = "moderator:manage:chat_settings"
ScopeModeratorManageShoutouts = "moderator:manage:shoutouts" ScopeModeratorManageShoutouts = "moderator:manage:shoutouts"
ScopeModeratorReadFollowers = "moderator:read:followers"
ScopeUserManageChatColor = "user:manage:chat_color" ScopeUserManageChatColor = "user:manage:chat_color"
// Deprecated v5 scope but used in chat // Deprecated v5 scope but used in chat

View file

@ -11,6 +11,7 @@ var (
twitch.ScopeChannelManageRaids: "start raids", twitch.ScopeChannelManageRaids: "start raids",
twitch.ScopeChannelManageVIPS: "manage VIPs", twitch.ScopeChannelManageVIPS: "manage VIPs",
twitch.ScopeChannelReadRedemptions: "see channel-point redemptions", twitch.ScopeChannelReadRedemptions: "see channel-point redemptions",
twitch.ScopeModeratorReadFollowers: "see who follows this channel",
} }
botDefaultScopes = []string{ botDefaultScopes = []string{

View file

@ -18,6 +18,7 @@ type (
RequiredScopes []string RequiredScopes []string
AnyScope bool AnyScope bool
Hook func(json.RawMessage) error Hook func(json.RawMessage) error
Version string
} }
twitchChannelState struct { twitchChannelState struct {
@ -124,8 +125,9 @@ func (t *twitchWatcher) getTopicRegistrations(userID string) []topicRegistration
}, },
{ {
Topic: twitch.EventSubEventTypeChannelFollow, Topic: twitch.EventSubEventTypeChannelFollow,
Version: twitch.EventSubTopicVersion1, // DEPRECATED, to be removed August 3, 2023
Condition: twitch.EventSubCondition{BroadcasterUserID: userID}, Condition: twitch.EventSubCondition{BroadcasterUserID: userID},
RequiredScopes: nil, RequiredScopes: nil, // Switch to []string{twitch.ScopeModeratorReadFollowers} after August 3, 2023
Hook: t.handleEventSubChannelFollow, 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 { if err != nil {
logger.WithError(err).Error("Unable to register topic") 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 { func (t *twitchWatcher) registerGlobalHooks() error {
_, err := twitchEventSubClient.RegisterEventSubHooks( _, err := twitchEventSubClient.RegisterEventSubHooks(
twitch.EventSubEventTypeUserAuthorizationRevoke, twitch.EventSubEventTypeUserAuthorizationRevoke,
twitch.EventSubTopicVersion1,
twitch.EventSubCondition{ClientID: cfg.TwitchClient}, twitch.EventSubCondition{ClientID: cfg.TwitchClient},
t.handleEventUserAuthRevoke, t.handleEventUserAuthRevoke,
) )