diff options
| author | Xe Iaso <me@xeiaso.net> | 2024-10-18 12:54:50 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2024-10-18 12:54:50 -0400 |
| commit | 0cf68872c0f726d0af169387d5c8e8060cec130d (patch) | |
| tree | c00d74978671baf769715377f9fe10c7f430cb68 /cmd | |
| parent | c758d20777cfbccfe02115c78dc9c24c836ea17d (diff) | |
| download | x-0cf68872c0f726d0af169387d5c8e8060cec130d.tar.xz x-0cf68872c0f726d0af169387d5c8e8060cec130d.zip | |
super yolo
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/mi/services/twitchevents/twitchevents.go | 129 |
1 files changed, 90 insertions, 39 deletions
diff --git a/cmd/mi/services/twitchevents/twitchevents.go b/cmd/mi/services/twitchevents/twitchevents.go index 3ff6563..20687e4 100644 --- a/cmd/mi/services/twitchevents/twitchevents.go +++ b/cmd/mi/services/twitchevents/twitchevents.go @@ -18,8 +18,14 @@ import ( "github.com/nicklaw5/helix/v2" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "golang.org/x/sync/errgroup" "within.website/x/cmd/mi/models" "within.website/x/proto/mimi/announce" + "within.website/x/web/mastodon" +) + +const ( + streamAnnouncement = "Xe is live on Twitch! https://twitch.tv/princessxen" ) var ( @@ -39,6 +45,8 @@ type Config struct { BlueskyAuthkey string BlueskyHandle string BlueskyPDS string + MastodonToken string + MastodonURL string MimiAnnounceURL string } @@ -58,10 +66,11 @@ func (c Config) BlueskyAgent(ctx context.Context) (*bsky.BskyAgent, error) { } type Server struct { - dao *models.DAO - mimi announce.Announce - cfg Config - twitch *helix.Client + dao *models.DAO + mimi announce.Post + mastodon *mastodon.Client + cfg Config + twitch *helix.Client } func New(ctx context.Context, dao *models.DAO, cfg Config) (*Server, error) { @@ -83,11 +92,17 @@ func New(ctx context.Context, dao *models.DAO, cfg Config) (*Server, error) { twitch.SetAppAccessToken(resp.Data.AccessToken) + mas, err := mastodon.Authenticated("mi_irl", "https://xeiaso.net", cfg.MastodonURL, cfg.MastodonToken) + if err != nil { + return nil, fmt.Errorf("failed to authenticate to mastodon: %w", err) + } + s := &Server{ - dao: dao, - mimi: announce.NewAnnounceProtobufClient(cfg.MimiAnnounceURL, &http.Client{}), - cfg: cfg, - twitch: twitch, + dao: dao, + mimi: announce.NewPostProtobufClient(cfg.MimiAnnounceURL, &http.Client{}), + mastodon: mas, + cfg: cfg, + twitch: twitch, } if err := s.maybeCreateWebhookSubscription(); err != nil { @@ -211,6 +226,8 @@ func (s *Server) handleNotification(ctx context.Context, lg *slog.Logger, w http return fmt.Errorf("can't decode notification: %w", err) } + lg = lg.With("event", data.Subscription.Type) + var err error switch data.Subscription.Type { case "stream.online": @@ -235,41 +252,75 @@ func (s *Server) handleNotification(ctx context.Context, lg *slog.Logger, w http func (s *Server) handleStreamUp(ctx context.Context, lg *slog.Logger, ev *helix.EventSubStreamOnlineEvent) error { lg.Info("broadcaster went online!", "username", ev.BroadcasterUserLogin) - bs, err := s.cfg.BlueskyAgent(ctx) - if err != nil { - return fmt.Errorf("can't create bluesky agent: %w", err) - } + g, gCtx := errgroup.WithContext(ctx) - u, err := url.Parse("https://twitch.tv/" + ev.BroadcasterUserLogin) - if err != nil { - return fmt.Errorf("[unexpected] can't create twitch URL: %w", err) - } + g.Go(func() error { + post, err := s.mastodon.CreateStatus(gCtx, mastodon.CreateStatusParams{ + Status: streamAnnouncement, + }) + if err != nil { + slog.Error("failed to announce to mastodon", "err", err) + return err + } + slog.Info("posted to mastodon", "mastodon_url", post.URL) + return nil + }) - q := u.Query() - q.Set("utm_campaign", "mi_irl") - q.Set("utm_medium", "social") - q.Set("utm_source", "bluesky") - u.RawQuery = q.Encode() - - var sb strings.Builder - fmt.Fprintln(&sb, "Xe is live on stream!") - fmt.Fprintln(&sb) - fmt.Fprint(&sb, u.String()) - - post, err := bsky.NewPostBuilder(sb.String()). - WithExternalLink("twitch.tv - princessxen", *u, "Xe on Twitch!"). - WithFacet(bsky.Facet_Link, u.String(), u.String()). - Build() - if err != nil { - return fmt.Errorf("can't build post: %w", err) - } + g.Go(func() error { + bs, err := s.cfg.BlueskyAgent(gCtx) + if err != nil { + return fmt.Errorf("can't create bluesky agent: %w", err) + } - cid, uri, err := bs.PostToFeed(ctx, post) - if err != nil { - return fmt.Errorf("can't post to feed: %w", err) - } + u, err := url.Parse("https://twitch.tv/" + ev.BroadcasterUserLogin) + if err != nil { + return fmt.Errorf("[unexpected] can't create twitch URL: %w", err) + } - lg.Info("posted to bluesky", "bluesky_cid", cid, "bluesky_uri", uri, "body", sb.String()) + q := u.Query() + q.Set("utm_campaign", "mi_irl") + q.Set("utm_medium", "social") + q.Set("utm_source", "bluesky") + u.RawQuery = q.Encode() + + var sb strings.Builder + fmt.Fprintln(&sb, "Xe is live on stream!") + fmt.Fprintln(&sb) + fmt.Fprint(&sb, u.String()) + + post, err := bsky.NewPostBuilder(sb.String()). + WithExternalLink("twitch.tv - princessxen", *u, "Xe on Twitch!"). + WithFacet(bsky.Facet_Link, u.String(), u.String()). + Build() + if err != nil { + return fmt.Errorf("can't build post: %w", err) + } + + cid, uri, err := bs.PostToFeed(gCtx, post) + if err != nil { + return fmt.Errorf("can't post to feed: %w", err) + } + + lg.Info("posted to bluesky", "bluesky_cid", cid, "bluesky_uri", uri, "body", sb.String()) + + return nil + }) + + g.Go(func() error { + if _, err := s.mimi.Post(gCtx, &announce.StatusUpdate{ + Body: streamAnnouncement, + }); err != nil { + return fmt.Errorf("can't announce to Mimi: %w", err) + } + + lg.Info("posted to Mimi") + + return nil + }) + + if err := g.Wait(); err != nil { + return err + } return nil } |
