audon/webhooks.go

150 wiersze
4.3 KiB
Go
Czysty Zwykły widok Historia

2022-12-05 01:11:44 +00:00
package main
import (
2023-01-20 15:39:51 +00:00
"fmt"
2023-01-23 12:10:21 +00:00
"log"
2022-12-05 01:11:44 +00:00
"net/http"
2023-01-20 15:39:51 +00:00
"strings"
2023-01-23 12:10:21 +00:00
"time"
2022-12-05 01:11:44 +00:00
2023-01-23 12:10:21 +00:00
"github.com/jellydator/ttlcache/v3"
2022-12-05 01:11:44 +00:00
"github.com/labstack/echo/v4"
"github.com/livekit/protocol/auth"
"github.com/livekit/protocol/webhook"
2023-01-20 15:39:51 +00:00
mastodon "github.com/mattn/go-mastodon"
"github.com/nicksnyder/go-i18n/v2/i18n"
2023-01-23 12:10:21 +00:00
"golang.org/x/net/context"
2022-12-05 01:11:44 +00:00
)
func livekitWebhookHandler(c echo.Context) error {
authProvider := auth.NewSimpleKeyProvider(mainConfig.Livekit.APIKey, mainConfig.Livekit.APISecret)
event, err := webhook.ReceiveWebhookEvent(c.Request(), authProvider)
if err == webhook.ErrNoAuthHeader {
return echo.NewHTTPError(http.StatusForbidden)
}
if event.GetEvent() == webhook.EventRoomFinished {
2023-01-25 06:37:31 +00:00
lkRoom := event.GetRoom()
room, err := findRoomByID(c.Request().Context(), lkRoom.GetName())
2023-01-20 15:39:51 +00:00
if err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusNotFound)
}
if room.EndedAt.IsZero() {
if err := endRoom(c.Request().Context(), room); err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusInternalServerError)
2022-12-05 01:11:44 +00:00
}
}
2023-01-23 12:10:21 +00:00
} else if event.GetEvent() == webhook.EventParticipantLeft {
// Revert user's avatar
audonID := event.GetParticipant().GetIdentity()
user, err := findUserByID(c.Request().Context(), audonID)
if user == nil || err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusNotFound)
}
still, err := user.InLivekit(c.Request().Context())
if !still && err == nil {
2023-01-26 22:31:53 +00:00
data := userSessionCache.Get(audonID)
2023-01-23 12:10:21 +00:00
if data == nil {
return echo.NewHTTPError(http.StatusGone)
}
mastoClient := getMastodonClient(data.Value())
if mastoClient == nil {
c.Logger().Errorf("unable to get mastodon client: %v", data.Value().MastodonConfig)
return echo.NewHTTPError(http.StatusInternalServerError)
}
cached := webhookTimerCache.Get(audonID)
if cached != nil {
oldTimer := cached.Value()
if !oldTimer.Stop() {
<-oldTimer.C
}
}
2023-01-26 18:28:25 +00:00
countdown := time.NewTimer(60 * time.Second)
2023-01-23 12:10:21 +00:00
webhookTimerCache.Set(audonID, countdown, ttlcache.DefaultTTL)
2023-01-25 06:37:31 +00:00
go func() {
<-countdown.C
webhookTimerCache.Delete(audonID)
2023-01-26 18:28:25 +00:00
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
2023-01-25 06:37:31 +00:00
defer cancel()
2023-01-23 12:10:21 +00:00
2023-01-25 06:37:31 +00:00
stillAgain, err := user.InLivekit(ctx)
2023-01-23 12:10:21 +00:00
if err != nil {
2023-01-25 06:37:31 +00:00
log.Println(err)
2023-01-23 12:10:21 +00:00
}
2023-01-25 06:37:31 +00:00
if stillAgain {
return
2023-01-23 12:10:21 +00:00
}
2023-01-25 06:37:31 +00:00
nextUser, err := findUserByID(ctx, audonID)
if err == nil && nextUser.AvatarFile != "" {
log.Printf("restoring avatar: %s\n", audonID)
if err != nil {
log.Println(err)
return
}
avatar := nextUser.getAvatarImagePath(nextUser.AvatarFile)
_, err = updateAvatar(ctx, mastoClient, avatar)
if err != nil {
log.Println(err)
}
nextUser.ClearUserAvatar(ctx)
2023-01-26 22:31:53 +00:00
userSessionCache.Delete(audonID)
2023-01-25 06:37:31 +00:00
} else if err != nil {
log.Println(err)
}
}()
2023-01-23 12:10:21 +00:00
}
2023-01-20 15:39:51 +00:00
} else if event.GetEvent() == webhook.EventRoomStarted {
// Have the bot advertise the room
room, err := findRoomByID(c.Request().Context(), event.GetRoom().GetName())
if err != nil {
c.Logger().Error(err)
return echo.NewHTTPError(http.StatusNotFound)
}
if err == nil && mainConfig.Bot.Enable && room.Advertise != "" && room.Restriction == EVERYONE {
botClient := mastodon.NewClient(&mastodon.Config{
Server: mainConfig.Bot.Server.String(),
ClientID: mainConfig.Bot.ClientID,
ClientSecret: mainConfig.Bot.ClientSecret,
AccessToken: mainConfig.Bot.AccessToken,
})
botClient.UserAgent = USER_AGENT
localizer := i18n.NewLocalizer(localeBundle, room.Advertise)
header := localizer.MustLocalize(&i18n.LocalizeConfig{
DefaultMessage: &i18n.Message{
ID: "Advertise",
Other: "@{{.Host}} is streaming now!",
},
TemplateData: map[string]string{
"Host": room.Host.Webfinger,
},
})
messages := []string{
header,
2023-01-23 14:57:23 +00:00
fmt.Sprintf(":udon: %s\n🎙 https://%s/r/%s", room.Title, mainConfig.LocalDomain, room.RoomID),
2023-01-20 15:39:51 +00:00
}
if room.Description != "" {
messages = append(messages, room.Description)
}
messages = append(messages, "#Audon")
message := strings.Join(messages, "\n\n")
2022-12-05 01:11:44 +00:00
2023-01-20 15:39:51 +00:00
if _, err := botClient.PostStatus(c.Request().Context(), &mastodon.Toot{
Status: message,
Language: room.Advertise,
Visibility: "public",
}); err != nil {
c.Logger().Error(err)
}
}
2022-12-05 01:11:44 +00:00
}
2023-01-20 15:39:51 +00:00
return c.NoContent(http.StatusOK)
2022-12-05 01:11:44 +00:00
}