this repo has no description
0
fork

Configure Feed

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

basic nostr spam rule (#670)

authored by

bnewbold and committed by
GitHub
ad38fe30 5321bc31

+59 -3
+3 -3
automod/capture/fetch.go
··· 25 25 if pdsURL == "" { 26 26 return fmt.Errorf("could not resolve PDS endpoint for AT-URI account: %s", ident.DID.String()) 27 27 } 28 - pdsClient := xrpc.Client{Host: ident.PDSEndpoint()} 28 + pdsClient := xrpc.Client{Host: pdsURL} 29 29 30 30 eng.Logger.Info("fetching record", "did", ident.DID.String(), "collection", aturi.Collection().String(), "rkey", aturi.RecordKey().String()) 31 31 out, err := comatproto.RepoGetRecord(ctx, &pdsClient, "", aturi.Collection().String(), ident.DID.String(), aturi.RecordKey().String()) 32 32 if err != nil { 33 - return fmt.Errorf("fetching record from Relay (%s): %v", aturi, err) 33 + return fmt.Errorf("fetching record from PDS (%s): %v", aturi, err) 34 34 } 35 35 if out.Cid == nil { 36 36 return fmt.Errorf("expected a CID in getRecord response") ··· 61 61 if pdsURL == "" { 62 62 return nil, nil, fmt.Errorf("could not resolve PDS endpoint for account: %s", ident.DID.String()) 63 63 } 64 - pdsClient := xrpc.Client{Host: ident.PDSEndpoint()} 64 + pdsClient := xrpc.Client{Host: pdsURL} 65 65 66 66 resp, err := comatproto.RepoListRecords(ctx, &pdsClient, "app.bsky.feed.post", "", int64(limit), ident.DID.String(), false, "", "") 67 67 if err != nil {
+1
automod/rules/all.go
··· 26 26 SimpleBotPostRule, 27 27 HarassmentTargetInteractionPostRule, 28 28 HarassmentTrivialPostRule, 29 + NostrSpamPostRule, 29 30 }, 30 31 ProfileRules: []automod.ProfileRuleFunc{ 31 32 GtubeProfileRule,
+3
automod/rules/example_sets.json
··· 14 14 ], 15 15 "promo-domain": [ 16 16 "buy-crypto.example.com" 17 + ], 18 + "trivial-spam-text": [ 19 + "spam" 17 20 ] 18 21 }
+52
automod/rules/nostr.go
··· 1 + package rules 2 + 3 + import ( 4 + "fmt" 5 + "strings" 6 + "time" 7 + 8 + appbsky "github.com/bluesky-social/indigo/api/bsky" 9 + "github.com/bluesky-social/indigo/automod" 10 + ) 11 + 12 + var _ automod.PostRuleFunc = NostrSpamPostRule 13 + 14 + // looks for new accounts, which frequently post the same type of content 15 + func NostrSpamPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { 16 + if c.Account.Identity == nil { 17 + return nil 18 + } 19 + 20 + // often don't have private metadata for these accounts right after creation 21 + if c.Account.Private != nil { 22 + // TODO: helper for account age; and use public info for this (not private) 23 + age := time.Since(c.Account.Private.IndexedAt) 24 + if age > 2*24*time.Hour { 25 + return nil 26 + } 27 + } 28 + 29 + // is this a bridged nostr account? if not, bail out 30 + hdl := c.Account.Identity.Handle.String() 31 + if !(strings.HasPrefix(hdl, "npub") && len(hdl) > 63 && strings.HasSuffix(hdl, ".brid.gy")) { 32 + return nil 33 + } 34 + 35 + c.AddAccountFlag("nostr") 36 + 37 + // only posts with dumb patterns (for now) 38 + txt := strings.ToLower(post.Text) 39 + if !c.InSet("trivial-spam-text", txt) { 40 + return nil 41 + } 42 + 43 + // only accounts with empty profile (for now) 44 + if c.Account.Profile.HasAvatar || c.Account.Profile.Description != nil { 45 + return nil 46 + } 47 + 48 + c.ReportAccount(automod.ReportReasonOther, fmt.Sprintf("likely nostr spam account (also labeled; remove label if this isn't spam!)")) 49 + c.AddAccountLabel("!hide") 50 + c.Notify("slack") 51 + return nil 52 + }