Skip to content

Instantly share code, notes, and snippets.

@jhass
Last active February 14, 2022 09:43
Deletes spam comments, posts and local spam accounts. Place into Diasporas root, edit and run. Don't forget to set necessary environment variables.
#!/usr/bin/env ruby
# List of spam accounts
spam_accounts = %w(spamacc@podA spamacc@podB spamacc@mypod)
# Delete comments even if spammer isn't a local user or spam isn't on a
# local users account.
# And delete posts of users in spam_accounts that aren't local.
always_delete = true
# Keep empty (%w() or []) to retract spam comments from remote accounts
# for all local users
retract_for = %w(userA userB)
###########################################################################
# Load diaspora environment
ENV['RAILS_ENV'] ||= "production"
require_relative 'config/environment'
local_spammers, remote_spammers = Person.where(diaspora_handle: spam_accounts).partition(&:local?)
# Retract all comments of local spammers and close their accounts
local_spammers.each do |spammer|
Comment.where(author_id: spammer.id).each do |comment|
spammer.owner.retract(comment)
end
spammer.owner.close_account!
end
# Retract all spam comments on posts of local users and delete the rest
Comment.where(author_id: remote_spammers.map(&:id)).each do |comment|
post_author = comment.parent.author
if post_author.local? && (retract_for.include?(post_author.owner.username) || retract_for.empty?)
post_author.owner.retract(comment)
elsif always_delete
comment.destroy
end
end
# Destroy posts of remote users if wanted
if always_delete
Post.where(author_id: remote_spammers.map(&:id)).each(&:destroy)
end
@dmorley
Copy link

dmorley commented Feb 23, 2014

Getting a

"/home/david/.rvm/gems/ruby-2.0.0-p353@diaspora/gems/activerecord-3.2.17/lib/active_record/relation/delegation.rb:40:in `partition': wrong number of arguments (1 for 0) (ArgumentError)
    from /home/david/.rvm/gems/ruby-2.0.0-p353@diaspora/gems/activerecord-3.2.17/lib/active_record/relation/delegation.rb:40:in `method_missing'
    from spam.rb:19:in `<main>'" 

error, looking for answers and not finding much on that error

@jhass
Copy link
Author

jhass commented Feb 23, 2014

Whoops, missed a &, Try the updated version.

@jaywink
Copy link

jaywink commented Feb 23, 2014

I got it working by changing line 19 to this:

local_spammers, remote_spammers = Person.where(diaspora_handle: spam_accounts).partition { |account| account.local? }

But & would be better?

@jhass
Copy link
Author

jhass commented Feb 23, 2014

It's really the same thing, just a shortcut to write what you wrote ;)

@ajya
Copy link

ajya commented May 5, 2018

if anyone else needs, I have a forked version that also deletes spam "likes" and local profiles of spammers, https://gist.github.com/ajya/bdeb1c69330c85bcb400297c319d5be4/revisions#diff-79fdb7c3dc82d2ad8e5713fe5f2dfaf7

@Vertux
Copy link

Vertux commented Mar 27, 2019

@ajya
@jhass
These scripts are very helpfull, thank you very much.
I have a little suggestion for further improvement. If the script encounters an account entry which was already deleted/blocked, it throws an error and stops the execution. It would be nice it would handle this stituation by skipping those entries and continue execution.

@tclaus
Copy link

tclaus commented Mar 30, 2021

Whats about wrapping this into an UI and put this inside a worker?

@grinapo
Copy link

grinapo commented May 2, 2021

The first step towards stopping my pod forever had to be disabling registrations. In the last few years I have got no observable help from anyone, this script is barely qualifying as useful and the spambots are pretty lively. There seem to be no admin-approval option, no antispam measures, hooks, whatever, and everything is slow as hell. Not providing real antispam support just doesn't cut it.

Nevertheless, here's my after-the-fact script, which calls this code above with the modification of

spam_accounts = ARGV[0]

#!/bin/bash
# dewankerer.sh by grin, 2020
# gplv3+ or cc-by-sa-4.0 

# database user, host, dbname
DBU="pora"
DBH="1.7.1.2"
DBDB="pora"

SQL_GET_SPAMMER="SELECT username, getting_started, language, email,
        sign_in_count, last_sign_in_at, last_sign_in_ip, last_seen
  FROM users
  WHERE last_sign_in_ip IN ('51.91.67.153','151.80.230.21','85.113.129.7','178.159.37.139')                                                                          
  ORDER BY username;"

# .pgpass  
psql -h $DBH -U $DBU $DBDB -c "${SQL_GET_SPAMMER}"

psql -h $DBH -U $DBU $DBDB -tA -c "${SQL_GET_SPAMMER}" | awk -F'|' '{ print $1} ' | \
        while read user; do
                echo ">>${user}>>"
                ./z_delete_user.rb "${user}@spora.grin.hu"
        done

or I often replace the SQL above with

SELECT username, getting_started, language, email, 
        sign_in_count, last_sign_in_at, last_sign_in_ip, last_seen
  FROM users
  WHERE sign_in_count=1 AND last_seen+'1 day'::INTERVAL < NOW()
  ORDER BY last_seen ;

to kill accounts older than a week and logged in only once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment