porting all github actions from bluesky-social/indigo to tangled CI
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 98 lines 2.9 kB view raw
1package main 2 3import ( 4 "context" 5 "fmt" 6 "log/slog" 7 "os" 8 "strings" 9 10 appbsky "github.com/bluesky-social/indigo/api/bsky" 11 "github.com/bluesky-social/indigo/atproto/identity" 12 "github.com/bluesky-social/indigo/atproto/syntax" 13 14 "github.com/urfave/cli/v2" 15) 16 17type MentionChecker struct { 18 slackWebhookURL string 19 mentionDIDs []syntax.DID 20 logger *slog.Logger 21 directory identity.Directory 22 minimumWords int 23} 24 25func (mc *MentionChecker) ProcessPost(ctx context.Context, did syntax.DID, rkey syntax.RecordKey, post appbsky.FeedPost) error { 26 mc.logger.Debug("processing post record", "did", did, "rkey", rkey) 27 28 if mc.minimumWords > 0 { 29 words := strings.Split(post.Text, " ") 30 if len(words) < mc.minimumWords { 31 return nil 32 } 33 } 34 35 for _, facet := range post.Facets { 36 for _, feature := range facet.Features { 37 mention := feature.RichtextFacet_Mention 38 if mention == nil { 39 continue 40 } 41 for _, d := range mc.mentionDIDs { 42 if mention.Did == d.String() { 43 mc.logger.Info("found mention", "target", d, "author", did, "rkey", rkey) 44 targetIdent, err := mc.directory.LookupDID(ctx, syntax.DID(mention.Did)) 45 if err != nil { 46 return err 47 } 48 authorIdent, err := mc.directory.LookupDID(ctx, did) 49 if err != nil { 50 return err 51 } 52 msg := fmt.Sprintf("Mention of `@%s` by `@%s` (<https://bsky.app/profile/%s/post/%s|post link>):\n```%s```", targetIdent.Handle, authorIdent.Handle, did, rkey, post.Text) 53 if post.Embed != nil && (post.Embed.EmbedImages != nil || post.Embed.EmbedRecordWithMedia != nil || post.Embed.EmbedRecord != nil || post.Embed.EmbedExternal != nil) { 54 msg += "\n(post also contains an embed/quote/media)" 55 } 56 return sendSlackMsg(ctx, msg, mc.slackWebhookURL) 57 } 58 } 59 } 60 } 61 return nil 62} 63 64func notifyMentions(cctx *cli.Context) error { 65 ctx := context.Background() 66 logger := configLogger(cctx, os.Stdout) 67 relayHost := cctx.String("relay-host") 68 minimumWords := cctx.Int("minimum-words") 69 70 mentionDIDs := []syntax.DID{} 71 for _, raw := range strings.Split(cctx.String("mention-dids"), ",") { 72 did, err := syntax.ParseDID(raw) 73 if err != nil { 74 return err 75 } 76 mentionDIDs = append(mentionDIDs, did) 77 } 78 79 checker := MentionChecker{ 80 slackWebhookURL: cctx.String("slack-webhook-url"), 81 mentionDIDs: mentionDIDs, 82 logger: logger, 83 directory: identity.DefaultDirectory(), 84 minimumWords: minimumWords, 85 } 86 87 logger.Info("beemo mention checker starting up...", "relayHost", relayHost, "mentionDIDs", mentionDIDs) 88 89 // can flip this bool to false to prevent spamming slack channel on startup 90 if true { 91 err := sendSlackMsg(ctx, fmt.Sprintf("beemo booting, looking for account mentions: `%s`", mentionDIDs), checker.slackWebhookURL) 92 if err != nil { 93 return err 94 } 95 } 96 97 return RunFirehoseConsumer(ctx, logger, relayHost, checker.ProcessPost) 98}