From e993de4eb159b47557b16e8f447af74342040cac Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:46:27 +0100 Subject: [PATCH] make eventsub events work on multiple channels --- cmd/nourybot/eventsub.go | 10 ++++++---- cmd/nourybot/router.go | 31 +++++++++++++++++-------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/cmd/nourybot/eventsub.go b/cmd/nourybot/eventsub.go index 0578d5c..0389a22 100644 --- a/cmd/nourybot/eventsub.go +++ b/cmd/nourybot/eventsub.go @@ -31,7 +31,7 @@ func (app *application) createLiveSubscription(target, channel string) string { }, Transport: helix.EventSubTransport{ Method: "webhook", - Callback: "https://bot.noury.li/eventsub", + Callback: fmt.Sprintf("https://bot.noury.li/eventsub/%v", target), Secret: app.Config.eventSubSecret, }, }) @@ -78,7 +78,8 @@ func (app *application) deleteLiveSubscription(target, channel string) string { // which one has the type we want for this event. Then use this ones ID. var eventSubID string for i := 0; i < len(resp.Data.EventSubSubscriptions); i++ { - if resp.Data.EventSubSubscriptions[i].Type == "stream.online" { + if resp.Data.EventSubSubscriptions[i].Type == "stream.online" && + resp.Data.EventSubSubscriptions[i].Transport.Callback == fmt.Sprintf("https://bot.noury.li/eventsub/%s", target) { eventSubID = resp.Data.EventSubSubscriptions[i].ID } } @@ -117,7 +118,7 @@ func (app *application) createOfflineSubscription(target, channel string) string }, Transport: helix.EventSubTransport{ Method: "webhook", - Callback: "https://bot.noury.li/eventsub", + Callback: fmt.Sprintf("https://bot.noury.li/eventsub/%v", target), Secret: app.Config.eventSubSecret, }, }) @@ -164,7 +165,8 @@ func (app *application) deleteOfflineSubscription(target, channel string) string // which one has the type we want for this event. Then use this ones ID. var eventSubID string for i := 0; i < len(resp.Data.EventSubSubscriptions); i++ { - if resp.Data.EventSubSubscriptions[i].Type == "stream.offline" { + if resp.Data.EventSubSubscriptions[i].Type == "stream.offline" && + resp.Data.EventSubSubscriptions[i].Transport.Callback == fmt.Sprintf("https://bot.noury.li/eventsub/%s", target) { eventSubID = resp.Data.EventSubSubscriptions[i].ID } } diff --git a/cmd/nourybot/router.go b/cmd/nourybot/router.go index 6176bfa..25dc259 100644 --- a/cmd/nourybot/router.go +++ b/cmd/nourybot/router.go @@ -10,7 +10,6 @@ import ( "net/http" "os" "sort" - "time" "github.com/julienschmidt/httprouter" "github.com/lyx0/nourybot/internal/data" @@ -23,7 +22,7 @@ func (app *application) startRouter() { router := httprouter.New() router.GET("/", app.homeRoute) router.GET("/status", app.statusPageRoute) - router.POST("/eventsub", app.eventsubFollow) + router.POST("/eventsub/:channel", app.eventsubFollow) router.GET("/commands", app.commandsRoute) router.GET("/commands/:channel", app.channelCommandsRoute) router.GET("/timer", app.timersRoute) @@ -46,9 +45,10 @@ type eventSubNotification struct { // eventsubMessageId stores the last message id of an event sub. Twitch resends events // if it is unsure that you have gotten them so we check if the last event has the same // message id and if it does discard the event. -var lastEventSubSubscriptionId = "" +var lastEventSubSubscriptionId = []string{"xd"} -func (app *application) eventsubFollow(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { +func (app *application) eventsubFollow(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + channel := ps.ByName("channel") body, err := io.ReadAll(r.Body) if err != nil { log.Println(err) @@ -74,11 +74,16 @@ func (app *application) eventsubFollow(w http.ResponseWriter, r *http.Request, _ w.Write([]byte(vals.Challenge)) return } + //r.Body.Close() - if vals.Subscription.ID == lastEventSubSubscriptionId { - return - } else { - lastEventSubSubscriptionId = vals.Subscription.ID + // Check if the current events subscription id equals the last events. + // If it does ignore the event since it's a repeated event. + for i := 0; i < len(lastEventSubSubscriptionId); i++ { + if vals.Subscription.ID == lastEventSubSubscriptionId[i] { + return + } else { + lastEventSubSubscriptionId[i] = vals.Subscription.ID + } } switch vals.Subscription.Type { @@ -86,24 +91,22 @@ func (app *application) eventsubFollow(w http.ResponseWriter, r *http.Request, _ var liveEvent helix.EventSubStreamOnlineEvent err = json.NewDecoder(bytes.NewReader(vals.Event)).Decode(&liveEvent) - log.Printf("got stream online event webhook: %s is live\n", liveEvent.BroadcasterUserName) + log.Printf("got stream online event webhook: [%s]: %s is live\n", channel, liveEvent.BroadcasterUserName) w.WriteHeader(200) w.Write([]byte("ok")) - time.Sleep(5 * time.Second) - game := ivr.GameByUsername(liveEvent.BroadcasterUserLogin) title := ivr.TitleByUsername(liveEvent.BroadcasterUserLogin) - app.SendNoBanphrase("nouryxd", fmt.Sprintf("%s went live FeelsGoodMan Game: %s; Title: %s; https://twitch.tv/%s", liveEvent.BroadcasterUserName, game, title, liveEvent.BroadcasterUserLogin)) + app.SendNoBanphrase(channel, fmt.Sprintf("%s went live FeelsGoodMan Game: %s; Title: %s; https://twitch.tv/%s", liveEvent.BroadcasterUserName, game, title, liveEvent.BroadcasterUserLogin)) case helix.EventSubTypeStreamOffline: var offlineEvent helix.EventSubStreamOfflineEvent err = json.NewDecoder(bytes.NewReader(vals.Event)).Decode(&offlineEvent) - log.Printf("got stream offline event webhook: %s is now offline\n", offlineEvent.BroadcasterUserName) + log.Printf("got stream online event webhook: [%s]: %s is live\n", channel, offlineEvent.BroadcasterUserName) w.WriteHeader(200) w.Write([]byte("ok")) - app.SendNoBanphrase("nouryxd", fmt.Sprintf("%s went offline FeelsBadMan", offlineEvent.BroadcasterUserName)) + app.SendNoBanphrase(channel, fmt.Sprintf("%s went offline FeelsBadMan", offlineEvent.BroadcasterUserName)) } }