From 67329b1ed86af5ff78df13c2ab1c51a454149fa2 Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Tue, 26 Dec 2023 17:42:27 +0100 Subject: [PATCH] automod: annotate rules with function types --- automod/rules/gtube.go | 4 ++++ automod/rules/hashtags.go | 4 ++++ automod/rules/identity.go | 2 ++ automod/rules/interaction.go | 4 ++++ automod/rules/keyword.go | 6 ++++++ automod/rules/misleading.go | 4 ++++ automod/rules/private.go | 2 ++ automod/rules/profile.go | 2 ++ automod/rules/promo.go | 2 ++ automod/rules/replies.go | 4 ++++ 10 files changed, 34 insertions(+) diff --git a/automod/rules/gtube.go b/automod/rules/gtube.go index 895e0ee47..69da65ff3 100644 --- a/automod/rules/gtube.go +++ b/automod/rules/gtube.go @@ -10,6 +10,8 @@ import ( // https://en.wikipedia.org/wiki/GTUBE var gtubeString = "XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X" +var _ automod.PostRuleFunc = GtubePostRule + func GtubePostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { if strings.Contains(post.Text, gtubeString) { c.AddRecordLabel("spam") @@ -17,6 +19,8 @@ func GtubePostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { return nil } +var _ automod.ProfileRuleFunc = GtubeProfileRule + func GtubeProfileRule(c *automod.RecordContext, profile *appbsky.ActorProfile) error { if profile.Description != nil && strings.Contains(*profile.Description, gtubeString) { c.AddRecordLabel("spam") diff --git a/automod/rules/hashtags.go b/automod/rules/hashtags.go index b1e2ec03f..ff10d456e 100644 --- a/automod/rules/hashtags.go +++ b/automod/rules/hashtags.go @@ -5,6 +5,8 @@ import ( "github.com/bluesky-social/indigo/automod" ) +var _ automod.PostRuleFunc = BadHashtagsPostRule + // looks for specific hashtags from known lists func BadHashtagsPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { for _, tag := range ExtractHashtags(post) { @@ -17,6 +19,8 @@ func BadHashtagsPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error return nil } +var _ automod.PostRuleFunc = TooManyHashtagsPostRule + // if a post is "almost all" hashtags, it might be a form of search spam func TooManyHashtagsPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { tags := ExtractHashtags(post) diff --git a/automod/rules/identity.go b/automod/rules/identity.go index 15e149bcc..41deb5410 100644 --- a/automod/rules/identity.go +++ b/automod/rules/identity.go @@ -9,6 +9,8 @@ import ( "github.com/bluesky-social/indigo/automod/countstore" ) +var _ automod.IdentityRuleFunc = NewAccountRule + // triggers on first identity event for an account (DID) func NewAccountRule(c *automod.AccountContext) error { // need access to IndexedAt for this rule diff --git a/automod/rules/interaction.go b/automod/rules/interaction.go index 7662c16b8..627e4fcc5 100644 --- a/automod/rules/interaction.go +++ b/automod/rules/interaction.go @@ -9,6 +9,8 @@ import ( var interactionDailyThreshold = 800 +var _ automod.RecordRuleFunc = InteractionChurnRule + // looks for accounts which do frequent interaction churn, such as follow-unfollow. func InteractionChurnRule(c *automod.RecordContext) error { did := c.Account.Identity.DID.String() @@ -37,6 +39,8 @@ func InteractionChurnRule(c *automod.RecordContext) error { return nil } +var _ automod.RecordRuleFunc = DeleteInteractionRule + func DeleteInteractionRule(c *automod.RecordContext) error { did := c.Account.Identity.DID.String() switch c.RecordOp.Collection { diff --git a/automod/rules/keyword.go b/automod/rules/keyword.go index 0362d240c..d83103fa4 100644 --- a/automod/rules/keyword.go +++ b/automod/rules/keyword.go @@ -7,6 +7,8 @@ import ( "github.com/bluesky-social/indigo/automod" ) +var _ automod.PostRuleFunc = KeywordPostRule + func KeywordPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { for _, tok := range ExtractTextTokensPost(post) { if c.InSet("bad-words", tok) { @@ -18,6 +20,8 @@ func KeywordPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { return nil } +var _ automod.ProfileRuleFunc = KeywordProfileRule + func KeywordProfileRule(c *automod.RecordContext, profile *appbsky.ActorProfile) error { for _, tok := range ExtractTextTokensProfile(profile) { if c.InSet("bad-words", tok) { @@ -29,6 +33,8 @@ func KeywordProfileRule(c *automod.RecordContext, profile *appbsky.ActorProfile) return nil } +var _ automod.PostRuleFunc = ReplySingleKeywordPostRule + func ReplySingleKeywordPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { if post.Reply != nil && !IsSelfThread(c, post) { tokens := ExtractTextTokensPost(post) diff --git a/automod/rules/misleading.go b/automod/rules/misleading.go index 86a19a0a5..12dd85fe2 100644 --- a/automod/rules/misleading.go +++ b/automod/rules/misleading.go @@ -78,6 +78,8 @@ func isMisleadingURLFacet(facet PostFacet, logger *slog.Logger) bool { return false } +var _ automod.PostRuleFunc = MisleadingURLPostRule + func MisleadingURLPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { // TODO: make this an InSet() config? if c.Account.Identity.Handle == "nowbreezing.ntw.app" { @@ -100,6 +102,8 @@ func MisleadingURLPostRule(c *automod.RecordContext, post *appbsky.FeedPost) err return nil } +var _ automod.PostRuleFunc = MisleadingMentionPostRule + func MisleadingMentionPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { // TODO: do we really need to route context around? probably ctx := context.TODO() diff --git a/automod/rules/private.go b/automod/rules/private.go index 7c8d9d08a..a897dbe0d 100644 --- a/automod/rules/private.go +++ b/automod/rules/private.go @@ -7,6 +7,8 @@ import ( "github.com/bluesky-social/indigo/automod" ) +var _ automod.PostRuleFunc = AccountPrivateDemoPostRule + // dummy rule. this leaks PII (account email) in logs and should never be used in real life func AccountPrivateDemoPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { if c.Account.Private != nil { diff --git a/automod/rules/profile.go b/automod/rules/profile.go index 2dee4ad89..18b2d60ae 100644 --- a/automod/rules/profile.go +++ b/automod/rules/profile.go @@ -5,6 +5,8 @@ import ( "github.com/bluesky-social/indigo/automod" ) +var _ automod.PostRuleFunc = AccountDemoPostRule + // this is a dummy rule to demonstrate accessing account metadata (eg, profile) from within post handler func AccountDemoPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { if c.Account.Profile.Description != nil && len(post.Text) > 5 && *c.Account.Profile.Description == post.Text { diff --git a/automod/rules/promo.go b/automod/rules/promo.go index d8d00f399..95c04406a 100644 --- a/automod/rules/promo.go +++ b/automod/rules/promo.go @@ -10,6 +10,8 @@ import ( "github.com/bluesky-social/indigo/automod/countstore" ) +var _ automod.PostRuleFunc = AggressivePromotionRule + // looks for new accounts, with a commercial or donation link in profile, which directly reply to several accounts // // this rule depends on ReplyCountPostRule() to set counts diff --git a/automod/rules/replies.go b/automod/rules/replies.go index 6905b787d..822d4a313 100644 --- a/automod/rules/replies.go +++ b/automod/rules/replies.go @@ -10,6 +10,8 @@ import ( "github.com/bluesky-social/indigo/automod/countstore" ) +var _ automod.PostRuleFunc = ReplyCountPostRule + // does not count "self-replies" (direct to self, or in own post thread) func ReplyCountPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error { if post.Reply == nil || IsSelfThread(c, post) { @@ -35,6 +37,8 @@ func ReplyCountPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error // triggers on the N+1 post, so 6th identical reply var identicalReplyLimit = 5 +var _ automod.PostRuleFunc = IdenticalReplyPostRule + // Looks for accounts posting the exact same text multiple times. Does not currently count the number of distinct accounts replied to, just counts replies at all. // // There can be legitimate situations that trigger this rule, so in most situations should be a "report" not "label" action.