···11+package rules
22+33+import (
44+ "fmt"
55+ "strings"
66+ "time"
77+88+ appbsky "github.com/bluesky-social/indigo/api/bsky"
99+ "github.com/bluesky-social/indigo/automod"
1010+)
1111+1212+var _ automod.PostRuleFunc = NostrSpamPostRule
1313+1414+// looks for new accounts, which frequently post the same type of content
1515+func NostrSpamPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error {
1616+ if c.Account.Identity == nil {
1717+ return nil
1818+ }
1919+2020+ // often don't have private metadata for these accounts right after creation
2121+ if c.Account.Private != nil {
2222+ // TODO: helper for account age; and use public info for this (not private)
2323+ age := time.Since(c.Account.Private.IndexedAt)
2424+ if age > 2*24*time.Hour {
2525+ return nil
2626+ }
2727+ }
2828+2929+ // is this a bridged nostr account? if not, bail out
3030+ hdl := c.Account.Identity.Handle.String()
3131+ if !(strings.HasPrefix(hdl, "npub") && len(hdl) > 63 && strings.HasSuffix(hdl, ".brid.gy")) {
3232+ return nil
3333+ }
3434+3535+ c.AddAccountFlag("nostr")
3636+3737+ // only posts with dumb patterns (for now)
3838+ txt := strings.ToLower(post.Text)
3939+ if !c.InSet("trivial-spam-text", txt) {
4040+ return nil
4141+ }
4242+4343+ // only accounts with empty profile (for now)
4444+ if c.Account.Profile.HasAvatar || c.Account.Profile.Description != nil {
4545+ return nil
4646+ }
4747+4848+ c.ReportAccount(automod.ReportReasonOther, fmt.Sprintf("likely nostr spam account (also labeled; remove label if this isn't spam!)"))
4949+ c.AddAccountLabel("!hide")
5050+ c.Notify("slack")
5151+ return nil
5252+}