From 82d75c1d4de1ca990fe6aa507540fc783567d63d Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Wed, 4 Sep 2024 20:19:06 -0700 Subject: [PATCH 1/5] make identity reply rule more aggressive --- automod/rules/replies.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/automod/rules/replies.go b/automod/rules/replies.go index a5a9a4a37..92b04d728 100644 --- a/automod/rules/replies.go +++ b/automod/rules/replies.go @@ -39,6 +39,7 @@ func ReplyCountPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error // var identicalReplyLimit = 6 // TODO: bumping temporarily var identicalReplyLimit = 20 +var identicalReplyActionLimit = 75 var _ automod.PostRuleFunc = IdenticalReplyPostRule @@ -71,7 +72,12 @@ func IdenticalReplyPostRule(c *automod.RecordContext, post *appbsky.FeedPost) er count := c.GetCount("reply-text", bucket, period) if count >= identicalReplyLimit { c.AddAccountFlag("multi-identical-reply") - c.ReportAccount(automod.ReportReasonRude, fmt.Sprintf("possible spam (new account, %d identical reply-posts today)", count)) + c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("possible spam (new account, %d identical reply-posts today)", count)) + c.Notify("slack") + } + if count >= identicalReplyActionLimit && utf8.RuneCountInString(post.Text) > 100 { + c.ReportAccount(automod.ReportReasonRude, fmt.Sprintf("likely spam/harassment (new account, %d identical reply-posts today), actioned (remove label urgently if account is ok)", count)) + c.AddAccountLabel("!warn") c.Notify("slack") } From a50845f6f899159d1dd9e02ff54ec2f6b78747c4 Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Wed, 4 Sep 2024 20:24:05 -0700 Subject: [PATCH 2/5] bump distinct replies a lot --- automod/rules/replies.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automod/rules/replies.go b/automod/rules/replies.go index 92b04d728..3a4bb17b1 100644 --- a/automod/rules/replies.go +++ b/automod/rules/replies.go @@ -86,7 +86,7 @@ func IdenticalReplyPostRule(c *automod.RecordContext, post *appbsky.FeedPost) er // TODO: bumping temporarily // var youngReplyAccountLimit = 12 -var youngReplyAccountLimit = 30 +var youngReplyAccountLimit = 200 var _ automod.PostRuleFunc = YoungAccountDistinctRepliesRule func YoungAccountDistinctRepliesRule(c *automod.RecordContext, post *appbsky.FeedPost) error { From f9079ade250b78a033be7b68d1c3ee7b254d8568 Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Wed, 4 Sep 2024 20:52:52 -0700 Subject: [PATCH 3/5] simplify build following rule --- automod/rules/interaction.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/automod/rules/interaction.go b/automod/rules/interaction.go index e14a5777d..fc056be06 100644 --- a/automod/rules/interaction.go +++ b/automod/rules/interaction.go @@ -8,6 +8,7 @@ import ( ) var interactionDailyThreshold = 800 +var followsDailyThreshold = 3000 var _ automod.RecordRuleFunc = InteractionChurnRule @@ -26,6 +27,7 @@ func InteractionChurnRule(c *automod.RecordContext) error { c.AddAccountFlag("high-like-churn") c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("interaction churn: %d likes, %d unlikes today (so far)", created, deleted)) c.Notify("slack") + return nil } case "app.bsky.graph.follow": c.Increment("follow", did) @@ -37,14 +39,16 @@ func InteractionChurnRule(c *automod.RecordContext) error { c.AddAccountFlag("high-follow-churn") c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("interaction churn: %d follows, %d unfollows today (so far)", created, deleted)) c.Notify("slack") + return nil } // just generic bulk following followRatio := float64(c.Account.FollowersCount) / float64(c.Account.FollowsCount) - if created > interactionDailyThreshold && c.Account.FollowsCount > 2000 && followRatio < 0.2 { + if created > followsDailyThreshold { c.Logger.Info("bulk-follower", "created-today", created) c.AddAccountFlag("bulk-follower") c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("bulk following: %d follows today (so far)", created)) - //c.Notify("slack") + c.Notify("slack") + return nil } } return nil From 0f54a07564c43e736331504d111964b03e179505 Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Wed, 4 Sep 2024 20:55:12 -0700 Subject: [PATCH 4/5] fix --- automod/rules/interaction.go | 1 - 1 file changed, 1 deletion(-) diff --git a/automod/rules/interaction.go b/automod/rules/interaction.go index fc056be06..61b960528 100644 --- a/automod/rules/interaction.go +++ b/automod/rules/interaction.go @@ -42,7 +42,6 @@ func InteractionChurnRule(c *automod.RecordContext) error { return nil } // just generic bulk following - followRatio := float64(c.Account.FollowersCount) / float64(c.Account.FollowsCount) if created > followsDailyThreshold { c.Logger.Info("bulk-follower", "created-today", created) c.AddAccountFlag("bulk-follower") From 768fa44bb1bd3018819db97c45260506e0dbaada Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Wed, 4 Sep 2024 21:02:38 -0700 Subject: [PATCH 5/5] add trivial spam text rule --- automod/rules/all.go | 1 + automod/rules/quick.go | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/automod/rules/all.go b/automod/rules/all.go index 33f9c16a6..e73234071 100644 --- a/automod/rules/all.go +++ b/automod/rules/all.go @@ -27,6 +27,7 @@ func DefaultRules() automod.RuleSet { HarassmentTargetInteractionPostRule, HarassmentTrivialPostRule, NostrSpamPostRule, + TrivialSpamPostRule, }, ProfileRules: []automod.ProfileRuleFunc{ GtubeProfileRule, diff --git a/automod/rules/quick.go b/automod/rules/quick.go index f63b900fc..77075d94a 100644 --- a/automod/rules/quick.go +++ b/automod/rules/quick.go @@ -68,3 +68,28 @@ func NewAccountBotEmailRule(c *automod.AccountContext) error { } return nil } + +var _ automod.PostRuleFunc = TrivialSpamPostRule + +// looks for new accounts, which frequently post the same type of content +func TrivialSpamPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { + if c.Account.Identity == nil || !AccountIsYoungerThan(&c.AccountContext, 8*24*time.Hour) { + return nil + } + + // only posts with dumb patterns (for now) + txt := strings.ToLower(post.Text) + if !c.InSet("trivial-spam-text", txt) { + return nil + } + + // only accounts with empty profile (for now) + if c.Account.Profile.HasAvatar { + return nil + } + + c.ReportAccount(automod.ReportReasonOther, fmt.Sprintf("trivial spam account (also labeled; remove label if this isn't spam!)")) + c.AddAccountLabel("!hide") + c.Notify("slack") + return nil +}