Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tweak reply mod rule to be less expensive #749

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion automod/rules/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ func DefaultRules() automod.RuleSet {
ReplySingleBadWordPostRule,
AggressivePromotionRule,
IdenticalReplyPostRule,
//IdenticalReplyPostSameParentRule,
DistinctMentionsRule,
YoungAccountDistinctMentionsRule,
MisleadingLinkUnicodeReversalPostRule,
Expand Down
89 changes: 48 additions & 41 deletions automod/rules/replies.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ func ReplyCountPostRule(c *automod.RecordContext, post *appbsky.FeedPost) error
// TODO: bumping temporarily
var identicalReplyLimit = 20
var identicalReplyActionLimit = 75
var identicalReplySameParentLimit = 3
var identicalReplySameParentMaxPosts int64 = 50
var multiIdenticalReplyFlag = "multi-identical-reply"
var multiIdenticalReplyLabeledFlag = "multi-identical-reply-labeled"
var multiIdenticalReplySamePostFlag = "multi-identical-reply-same-post"

var _ automod.PostRuleFunc = IdenticalReplyPostRule

Expand All @@ -52,9 +57,6 @@ func IdenticalReplyPostRule(c *automod.RecordContext, post *appbsky.FeedPost) er
}

// don't action short replies, or accounts more than two weeks old
if utf8.RuneCountInString(post.Text) <= 10 {
return nil
}
if AccountIsOlderThan(&c.AccountContext, 14*24*time.Hour) {
return nil
}
Expand All @@ -64,55 +66,60 @@ func IdenticalReplyPostRule(c *automod.RecordContext, post *appbsky.FeedPost) er
return nil
}

// increment before read. use a specific period (IncrementPeriod()) to reduce the number of counters (one per unique post text)
period := countstore.PeriodDay
bucket := c.Account.Identity.DID.String() + "/" + HashOfString(post.Text)
c.IncrementPeriod("reply-text", bucket, period)
isLessThanDayOld := AccountIsYoungerThan(&c.AccountContext, 24*time.Hour)
runeCount := utf8.RuneCountInString(post.Text)
hasImage := post.Embed.EmbedImages != nil || post.Embed.EmbedRecordWithMedia.Media.EmbedImages != nil

count := c.GetCount("reply-text", bucket, period)
if count >= identicalReplyLimit {
c.AddAccountFlag("multi-identical-reply")
c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("possible spam (new account, %d identical reply-posts today)", count))
c.Notify("slack")
// skip accounts that are over a day old, are not long posts, and do not have images
if !isLessThanDayOld && !hasImage && runeCount <= 10 {
return nil
}
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")

// skip accounts that have already been flagged by one of the "labeled" rules
accountFlags := c.Account.AccountFlags
for _, flag := range accountFlags {
if flag == multiIdenticalReplyLabeledFlag || flag == multiIdenticalReplySamePostFlag {
return nil
}
}

return nil
}
postTextHash := HashOfString(post.Text)

// Similar to above rule but only counts replies to the same post. More aggressively applies a spam label to new accounts that are less than a day old.
var identicalReplySameParentLimit = 3
var identicalReplySameParentMaxAge = 24 * time.Hour
var identicalReplySameParentMaxPosts int64 = 50
var _ automod.PostRuleFunc = IdenticalReplyPostSameParentRule
// special check for accounts less than a day old who are replying to the same post
if isLessThanDayOld || c.Account.PostsCount < identicalReplySameParentMaxPosts {
sameReplyPeriod := countstore.PeriodHour
bucket := c.Account.Identity.DID.String() + "/" + post.Reply.Parent.Uri + "/" + postTextHash
c.IncrementPeriod("reply-text-same-post", bucket, sameReplyPeriod)

func IdenticalReplyPostSameParentRule(c *automod.RecordContext, post *appbsky.FeedPost) error {
if post.Reply == nil || IsSelfThread(c, post) {
return nil
count := c.GetCount("reply-text-same-post", bucket, sameReplyPeriod)
if count >= identicalReplySameParentLimit {
c.AddAccountFlag(multiIdenticalReplySamePostFlag)
c.ReportAccount(automod.ReportReasonRude, fmt.Sprintf("likely spam/harassment (new account, %d identical reply-posts to same post today), actioned (remove label urgently if account is ok)", count))
c.AddAccountLabel("!warn")
c.Notify("slack")
return nil
}
}

if ParentOrRootIsFollower(c, post) {
return nil
}
// increment before read. use a specific period (IncrementPeriod()) to reduce the number of counters (one per unique post text)
period := countstore.PeriodDay
bucket := c.Account.Identity.DID.String() + "/" + postTextHash
c.IncrementPeriod("reply-text", bucket, period)

postCount := c.Account.PostsCount
if AccountIsOlderThan(&c.AccountContext, identicalReplySameParentMaxAge) || postCount >= identicalReplySameParentMaxPosts {
return nil
}
count := c.GetCount("reply-text", bucket, period)

period := countstore.PeriodHour
bucket := c.Account.Identity.DID.String() + "/" + post.Reply.Parent.Uri + "/" + HashOfString(post.Text)
c.IncrementPeriod("reply-text-same-post", bucket, period)
// regardless of rune count, report account for possible spam
if count >= identicalReplyLimit {
c.AddAccountFlag(multiIdenticalReplyFlag)
c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("possible spam (new account, %d identical reply-posts today)", count))
c.Notify("slack")
}

count := c.GetCount("reply-text-same-post", bucket, period)
if count >= identicalReplySameParentLimit {
c.AddAccountFlag("multi-identical-reply-same-post")
c.ReportAccount(automod.ReportReasonSpam, fmt.Sprintf("possible spam (%d identical reply-posts to same post today)", count))
c.AddAccountLabel("spam")
// action accounts that have exceeded the limit and are either longer posts or have at least one image
if count >= identicalReplyActionLimit && (hasImage || runeCount > 25) {
c.AddAccountFlag(multiIdenticalReplyLabeledFlag)
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")
}

Expand Down
Loading