Skip to content

Instantly share code, notes, and snippets.

@jhass
Last active February 14, 2022 09:43
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jhass/9104029 to your computer and use it in GitHub Desktop.
Save jhass/9104029 to your computer and use it in GitHub Desktop.
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