Bulk delete users that match an email pattern

I would like to bulk delete users that match an email pattern such as :

  • *.xyz
  • *.fun
  • etc…

I tried this as of now : User.find(UserEmail.where("email like '%.fun'").pluck(:user_id)).count. But I can’t use the destroy_all function after a .where()

Could you please help ?
Thanks a lot.

2 Likes

I would like to do the same, in addition to deleting all those users’ posts/topics too.

User.joins(:user_emails)
  .where('lower(user_emails.email) LIKE ?', '%domain.com')

In particular, the percentage sign (%) is a wildard that represents zero or more of any character. So %domain.com means emails ending with domain.com.

Rather than User#destroy, it’s best to use the UserDestroyer:

UserDestroyer.new(Discourse.system_user)
  .destroy(user, delete_posts: true)

This will have the system user delete the user and all of their posts.

To sum it up:

User.joins(:user_emails)
  .where('lower(user_emails.email) LIKE ?', '%domain.com')
  .find_each do |user|
    UserDestroyer.new(Discourse.system_user).destroy(user, delete_posts: true)
  end

Be ware that this is irreversable. You may want to verify the users selected by the query before actually deleting them. Also I am unsure of the performance implications if you’re deleting a great number of users and/or if they have a large number of posts.

On another note, not sure if Anonymizing Users in Discourse is an alternative for you?

7 Likes

Hi @xrav3nz ! This reply is awesome ! :open_mouth:
This is exactly what I need, I will try it right now, before I will confirm the amount with a basic count() of course as you suggested.

One remark, shouldn’t it be delete_post: true instead of false ?

My use case is very simple, I imported an old phpBB (thanks to @gerhard) and it has work perfectly, but this old forum what totally poluted by fake accounts… They did not post any message. All email addresses looks like .fun or .xyz.

2 Likes

Yes you’re right! Typo on my end!

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.