diff options
| author | Xe Iaso <me@xeiaso.net> | 2024-10-25 14:06:42 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2024-10-25 14:06:42 -0400 |
| commit | afa4bc6c01297af78885bf0562e2dae7ff83605b (patch) | |
| tree | 97a1149d5646cf9b1c7aa2892d6e849c589219cc /cmd/stealthmountain | |
| parent | 797eec6d94e193ae684db977179ea4a422b2499f (diff) | |
| download | x-afa4bc6c01297af78885bf0562e2dae7ff83605b.tar.xz x-afa4bc6c01297af78885bf0562e2dae7ff83605b.zip | |
cmd: add amano and stealthmountain
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd/stealthmountain')
| -rw-r--r-- | cmd/stealthmountain/main.go | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/cmd/stealthmountain/main.go b/cmd/stealthmountain/main.go new file mode 100644 index 0000000..a8a17fb --- /dev/null +++ b/cmd/stealthmountain/main.go @@ -0,0 +1,152 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log/slog" + "os" + "regexp" + "time" + + comatproto "github.com/bluesky-social/indigo/api/atproto" + bskyData "github.com/bluesky-social/indigo/api/bsky" + jsModels "github.com/bluesky-social/jetstream/pkg/models" + bsky "github.com/danrusei/gobot-bsky" + "github.com/goccy/go-json" + "github.com/nats-io/nats.go" + "within.website/x/internal" +) + +const ( + PostTopic = "amano:commit:app.bsky.feed.post" +) + +var ( + blueskyAuthkey = flag.String("bsky-authkey", "", "Bluesky authkey") + blueskyHandle = flag.String("bsky-handle", "", "Bluesky handle") + blueskyPDS = flag.String("bsky-pds", "https://bsky.social", "Bluesky PDS") + natsURL = flag.String("nats-url", "nats://localhost:4222", "nats url") + + sneakPeakRegex = regexp.MustCompile("(?i)sneak peak") +) + +func main() { + internal.HandleStartup() + + slog.Info("starting up", + "have-bsky-authkey", *blueskyAuthkey != "", + "bsky-handle", *blueskyHandle, + "bsky-pds", *blueskyPDS, + "nats-url", *natsURL, + ) + + nc, err := nats.Connect(*natsURL) + if err != nil { + slog.Error("can't connect to NATS", "err", err) + os.Exit(1) + } + defer nc.Close() + slog.Info("connected to NATS") + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + bsAgent, err := bskyAuth(ctx, *blueskyPDS, *blueskyHandle, *blueskyAuthkey) + if err != nil { + slog.Error("can't auth to bluesky", "err", err) + os.Exit(1) + } + + sub, err := nc.SubscribeSync(PostTopic) + if err != nil { + slog.Error("can't subscribe to post feed", "err", err) + os.Exit(1) + } + defer sub.Drain() + + for { + m, err := sub.NextMsg(time.Second) + if err != nil { + slog.Error("can't read message", "err", err) + continue + } + + var commit jsModels.Commit + if err := json.Unmarshal(m.Data, &commit); err != nil { + slog.Error("can't unmarshal commit", "err", err) + continue + } + + if commit.Operation == "delete" { + continue + } + + var post bskyData.FeedPost + if err := json.Unmarshal(commit.Record, &post); err != nil { + slog.Error("can't unmarshal post", "err", err) + continue + } + + if sneakPeakRegex.MatchString(post.Text) { + actorID := m.Header.Get("bsky-actor-did") + slog.Info("found a stealth mountain!", "id", commit.Rev, "actor", actorID) + reply, err := bsky.NewPostBuilder(`I think you mean "sneak peek"`).Build() + if err != nil { + slog.Error("can't build reply post", "err", err) + } + parent := comatproto.RepoStrongRef{ + LexiconTypeID: "app.bsky.feed.post", + Uri: fmt.Sprintf("at://%s/app.bsky.feed.post/%s", actorID, commit.RKey), + Cid: commit.CID, + } + root := parent + + if post.Reply != nil { + root = *post.Reply.Root + } + + reply.Reply = &bskyData.FeedPost_ReplyRef{ + Parent: &parent, + Root: &root, + } + + reply.CreatedAt = time.Now().UTC().Format(time.RFC3339) + + cid, uri, err := bsAgent.PostToFeed(ctx, reply) + if err != nil { + slog.Error("cannot post to feed", "err", err) + continue + } + + slog.Info("posted to bluesky", "bluesky_cid", cid, "bluesky_uri", uri) + } + } +} + +func bskyAuth(ctx context.Context, pds, handle, authkey string) (*bsky.BskyAgent, error) { + bluesky := bsky.NewAgent(ctx, pds, handle, authkey) + if err := bluesky.Connect(ctx); err != nil { + slog.Error("failed to connect to bluesky", "err", err) + return nil, err + } + + go func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + t := time.NewTicker(5 * time.Minute) + defer t.Stop() + for range t.C { + if err := bluesky.Connect(ctx); err != nil { + slog.Error("can't reauth to bluesky", "err", err) + } + } + }() + + if err := bluesky.Connect(ctx); err != nil { + slog.Error("failed to connect to bluesky", "err", err) + return nil, err + } + + return &bluesky, nil +} |
