Add support for beta Ad-Break event

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2023-10-21 16:43:44 +02:00
parent 803019e72d
commit a9e4931271
Signed by: luzifer
GPG key ID: D91C3E91E4CAD6F5
5 changed files with 68 additions and 23 deletions

View file

@ -16,6 +16,7 @@ var (
) )
var ( var (
eventTypeAdBreakBegin = ptrStr("adbreak_begin")
eventTypeAnnouncement = ptrStr("announcement") eventTypeAnnouncement = ptrStr("announcement")
eventTypeBan = ptrStr("ban") eventTypeBan = ptrStr("ban")
eventTypeBits = ptrStr("bits") eventTypeBits = ptrStr("bits")
@ -49,6 +50,7 @@ var (
eventTypeTwitchTitleUpdate = ptrStr("title_update") eventTypeTwitchTitleUpdate = ptrStr("title_update")
knownEvents = []*string{ knownEvents = []*string{
eventTypeAdBreakBegin,
eventTypeAnnouncement, eventTypeAnnouncement,
eventTypeBan, eventTypeBan,
eventTypeBits, eventTypeBits,

View file

@ -16,6 +16,7 @@ import (
) )
const ( const (
EventSubEventTypeChannelAdBreakBegin = "channel.ad_break.begin"
EventSubEventTypeChannelFollow = "channel.follow" EventSubEventTypeChannelFollow = "channel.follow"
EventSubEventTypeChannelPointCustomRewardRedemptionAdd = "channel.channel_points_custom_reward_redemption.add" EventSubEventTypeChannelPointCustomRewardRedemptionAdd = "channel.channel_points_custom_reward_redemption.add"
EventSubEventTypeChannelRaid = "channel.raid" EventSubEventTypeChannelRaid = "channel.raid"
@ -49,6 +50,16 @@ type (
ModeratorUserID string `json:"moderator_user_id,omitempty"` ModeratorUserID string `json:"moderator_user_id,omitempty"`
} }
EventSubEventAdBreakBegin struct {
Duration int64 `json:"duration"`
Timestamp time.Time `json:"timestamp"`
IsAutomatic bool `json:"is_automatic"`
BroadcasterUserID string `json:"broadcaster_user_id"`
BroadcasterUserLogin string `json:"broadcaster_user_login"`
BroadcasterUserName string `json:"broadcaster_user_name"`
RequesterUserID string `json:"requester_user_id"`
}
EventSubEventChannelPointCustomRewardRedemptionAdd struct { EventSubEventChannelPointCustomRewardRedemptionAdd struct {
ID string `json:"id"` ID string `json:"id"`
BroadcasterUserID string `json:"broadcaster_user_id"` BroadcasterUserID string `json:"broadcaster_user_id"`

View file

@ -2,7 +2,9 @@ package twitch
const ( const (
// API Scopes // API Scopes
ScopeChannelBot = "channel:bot"
ScopeChannelEditCommercial = "channel:edit:commercial" ScopeChannelEditCommercial = "channel:edit:commercial"
ScopeChannelManageAds = "channel:manage:ads"
ScopeChannelManageBroadcast = "channel:manage:broadcast" ScopeChannelManageBroadcast = "channel:manage:broadcast"
ScopeChannelManageModerators = "channel:manage:moderators" ScopeChannelManageModerators = "channel:manage:moderators"
ScopeChannelManagePolls = "channel:manage:polls" ScopeChannelManagePolls = "channel:manage:polls"
@ -10,11 +12,12 @@ const (
ScopeChannelManageRaids = "channel:manage:raids" ScopeChannelManageRaids = "channel:manage:raids"
ScopeChannelManageRedemptions = "channel:manage:redemptions" ScopeChannelManageRedemptions = "channel:manage:redemptions"
ScopeChannelManageVIPS = "channel:manage:vips" ScopeChannelManageVIPS = "channel:manage:vips"
ScopeClipsEdit = "clips:edit"
ScopeChannelManageWhispers = "user:manage:whispers" ScopeChannelManageWhispers = "user:manage:whispers"
ScopeChannelReadAds = "channel:read:ads"
ScopeChannelReadPolls = "channel:read:polls" ScopeChannelReadPolls = "channel:read:polls"
ScopeChannelReadRedemptions = "channel:read:redemptions" ScopeChannelReadRedemptions = "channel:read:redemptions"
ScopeChannelReadSubscriptions = "channel:read:subscriptions" ScopeChannelReadSubscriptions = "channel:read:subscriptions"
ScopeClipsEdit = "clips:edit"
ScopeModeratorManageAnnoucements = "moderator:manage:announcements" ScopeModeratorManageAnnoucements = "moderator:manage:announcements"
ScopeModeratorManageBannedUsers = "moderator:manage:banned_users" ScopeModeratorManageBannedUsers = "moderator:manage:banned_users"
ScopeModeratorManageChatMessages = "moderator:manage:chat_messages" ScopeModeratorManageChatMessages = "moderator:manage:chat_messages"
@ -23,8 +26,10 @@ const (
ScopeModeratorManageShoutouts = "moderator:manage:shoutouts" ScopeModeratorManageShoutouts = "moderator:manage:shoutouts"
ScopeModeratorReadFollowers = "moderator:read:followers" ScopeModeratorReadFollowers = "moderator:read:followers"
ScopeModeratorReadShoutouts = "moderator:read:shoutouts" ScopeModeratorReadShoutouts = "moderator:read:shoutouts"
ScopeUserBot = "user:bot"
ScopeUserManageChatColor = "user:manage:chat_color" ScopeUserManageChatColor = "user:manage:chat_color"
ScopeUserManageWhispers = "user:manage:whispers" ScopeUserManageWhispers = "user:manage:whispers"
ScopeUserReadChat = "user:read:chat"
// Deprecated v5 scope but used in chat // Deprecated v5 scope but used in chat
ScopeV5ChannelEditor = "channel_editor" ScopeV5ChannelEditor = "channel_editor"

View file

@ -10,6 +10,7 @@ var (
twitch.ScopeChannelManagePredictions: "manage predictions", twitch.ScopeChannelManagePredictions: "manage predictions",
twitch.ScopeChannelManageRaids: "start raids", twitch.ScopeChannelManageRaids: "start raids",
twitch.ScopeChannelManageVIPS: "manage VIPs", twitch.ScopeChannelManageVIPS: "manage VIPs",
twitch.ScopeChannelReadAds: "see when an ad-break starts",
twitch.ScopeChannelReadRedemptions: "see channel-point redemptions", twitch.ScopeChannelReadRedemptions: "see channel-point redemptions",
twitch.ScopeChannelReadSubscriptions: "see subscribed users / sub count / points", twitch.ScopeChannelReadSubscriptions: "see subscribed users / sub count / points",
twitch.ScopeClipsEdit: "create clips on behalf of this user", twitch.ScopeClipsEdit: "create clips on behalf of this user",

View file

@ -113,23 +113,11 @@ func (t *twitchWatcher) RemoveChannel(channel string) error {
func (t *twitchWatcher) getTopicRegistrations(userID string) []topicRegistration { func (t *twitchWatcher) getTopicRegistrations(userID string) []topicRegistration {
return []topicRegistration{ return []topicRegistration{
{ {
Topic: twitch.EventSubEventTypeChannelUpdate, Topic: twitch.EventSubEventTypeChannelAdBreakBegin,
Version: twitch.EventSubTopicVersion2, Version: twitch.EventSubTopicVersionBeta,
Condition: twitch.EventSubCondition{BroadcasterUserID: userID}, Condition: twitch.EventSubCondition{BroadcasterUserID: userID},
RequiredScopes: nil, RequiredScopes: []string{twitch.ScopeChannelReadAds},
Hook: t.handleEventSubChannelUpdate, Hook: t.handleEventSubChannelAdBreakBegin,
},
{
Topic: twitch.EventSubEventTypeStreamOffline,
Condition: twitch.EventSubCondition{BroadcasterUserID: userID},
RequiredScopes: nil,
Hook: t.handleEventSubStreamOnOff(false),
},
{
Topic: twitch.EventSubEventTypeStreamOnline,
Condition: twitch.EventSubCondition{BroadcasterUserID: userID},
RequiredScopes: nil,
Hook: t.handleEventSubStreamOnOff(true),
}, },
{ {
Topic: twitch.EventSubEventTypeChannelFollow, Topic: twitch.EventSubEventTypeChannelFollow,
@ -138,12 +126,6 @@ func (t *twitchWatcher) getTopicRegistrations(userID string) []topicRegistration
RequiredScopes: []string{twitch.ScopeModeratorReadFollowers}, RequiredScopes: []string{twitch.ScopeModeratorReadFollowers},
Hook: t.handleEventSubChannelFollow, Hook: t.handleEventSubChannelFollow,
}, },
{
Topic: twitch.EventSubEventTypeChannelRaid,
Condition: twitch.EventSubCondition{FromBroadcasterUserID: userID},
RequiredScopes: nil,
Hook: t.handleEventSubChannelOutboundRaid,
},
{ {
Topic: twitch.EventSubEventTypeChannelPointCustomRewardRedemptionAdd, Topic: twitch.EventSubEventTypeChannelPointCustomRewardRedemptionAdd,
Condition: twitch.EventSubCondition{BroadcasterUserID: userID}, Condition: twitch.EventSubCondition{BroadcasterUserID: userID},
@ -172,6 +154,12 @@ func (t *twitchWatcher) getTopicRegistrations(userID string) []topicRegistration
AnyScope: true, AnyScope: true,
Hook: t.handleEventSubChannelPollChange(eventTypePollProgress), Hook: t.handleEventSubChannelPollChange(eventTypePollProgress),
}, },
{
Topic: twitch.EventSubEventTypeChannelRaid,
Condition: twitch.EventSubCondition{FromBroadcasterUserID: userID},
RequiredScopes: nil,
Hook: t.handleEventSubChannelOutboundRaid,
},
{ {
Topic: twitch.EventSubEventTypeChannelShoutoutCreate, Topic: twitch.EventSubEventTypeChannelShoutoutCreate,
Condition: twitch.EventSubCondition{BroadcasterUserID: userID, ModeratorUserID: userID}, Condition: twitch.EventSubCondition{BroadcasterUserID: userID, ModeratorUserID: userID},
@ -186,9 +174,47 @@ func (t *twitchWatcher) getTopicRegistrations(userID string) []topicRegistration
AnyScope: true, AnyScope: true,
Hook: t.handleEventSubShoutoutReceived, Hook: t.handleEventSubShoutoutReceived,
}, },
{
Topic: twitch.EventSubEventTypeChannelUpdate,
Version: twitch.EventSubTopicVersion2,
Condition: twitch.EventSubCondition{BroadcasterUserID: userID},
RequiredScopes: nil,
Hook: t.handleEventSubChannelUpdate,
},
{
Topic: twitch.EventSubEventTypeStreamOffline,
Condition: twitch.EventSubCondition{BroadcasterUserID: userID},
RequiredScopes: nil,
Hook: t.handleEventSubStreamOnOff(false),
},
{
Topic: twitch.EventSubEventTypeStreamOnline,
Condition: twitch.EventSubCondition{BroadcasterUserID: userID},
RequiredScopes: nil,
Hook: t.handleEventSubStreamOnOff(true),
},
} }
} }
func (t *twitchWatcher) handleEventSubChannelAdBreakBegin(m json.RawMessage) error {
var payload twitch.EventSubEventAdBreakBegin
if err := json.Unmarshal(m, &payload); err != nil {
return errors.Wrap(err, "unmarshalling event")
}
fields := plugins.FieldCollectionFromData(map[string]any{
"channel": "#" + payload.BroadcasterUserLogin,
"duration": payload.Duration,
"is_automatic": payload.IsAutomatic,
"timestamp": payload.Timestamp,
})
log.WithFields(log.Fields(fields.Data())).Info("Ad-Break started")
go handleMessage(ircHdl.Client(), nil, eventTypeAdBreakBegin, fields)
return nil
}
func (t *twitchWatcher) handleEventSubChannelFollow(m json.RawMessage) error { func (t *twitchWatcher) handleEventSubChannelFollow(m json.RawMessage) error {
var payload twitch.EventSubEventFollow var payload twitch.EventSubEventFollow
if err := json.Unmarshal(m, &payload); err != nil { if err := json.Unmarshal(m, &payload); err != nil {