# \[Paid\] Prune Spam users

**URL:** https://meta.discourse.org/t/paid-prune-spam-users/63132
**Category:** Marketplace
**Created:** [May 22, 2017, 10:28am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132 "2017-05-22T10:28:42Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![treb0r](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@treb0r](https://meta.discourse.org/u/treb0r)
#### Post date: [May 22, 2017, 10:28am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/1 "2017-05-22T10:28:42Z")

</div>

What would you like done?

Remove spam users from discourse. Specifically, remove users if not logged in for a year and never posted.

When do you need it done?

ASAP

What is your budget, in $ USD that you can offer for this task?

Please give me a quote!

---

<div class="post-metadata">

### Author: ![TrumpPlaysRBX](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/trumpplaysrbx/32/71228_2.png) [@TrumpPlaysRBX](https://meta.discourse.org/u/TrumpPlaysRBX)
#### Post date: [May 22, 2017, 10:51am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/2 "2017-05-22T10:51:08Z")

</div>

Removing spam users would be good.

---

<div class="post-metadata">

### Author: ![MakaryGo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/makarygo/32/187426_2.png) [@MakaryGo](https://meta.discourse.org/u/MakaryGo)
#### Post date: [May 22, 2017, 11:09am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/3 "2017-05-22T11:09:46Z")

</div>

`User.joins(:user_stat).where("user_stats.post_count = 0 AND previous_visit_at <= '2016-05-22'::timestamp").destroy_all`  
Should do the trick 🙂 Of course make sure to make a backup first 🙂  
Edit:  
Sorry, forgot usage tips 🙂 Of course you have to log into your server, go into the discourse directory [probably /var/discourse], enter your Docker container [probably `./launcher enter app`] and then enter rails console by typing `rails c` . These are defaults on docker based installations 🙂  
@treb0r

---

<div class="post-metadata">

### Author: ![treb0r](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@treb0r](https://meta.discourse.org/u/treb0r)
#### Post date: [May 22, 2017, 11:21am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/4 "2017-05-22T11:21:04Z")

</div>

Hey @MakaryGo, thanks dude, that’s kind of you.

I will give it a go.

Cheers 😄

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [May 22, 2017, 10:25pm UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/6 "2017-05-22T22:25:34Z")

</div>

Don’t share email addresses in public, go ahead and PM each other as needed!

One caution: destroying users can be slow, so be sure you batch this somehow in case a giant mass delete times out or anything weird.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [May 22, 2017, 10:31pm UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/7 "2017-05-22T22:31:07Z")

</div>

There are probably fewer than 1000 users with zero posts who haven’t logged in in the past year, so this should be reasonably safe.

---

<div class="post-metadata">

### Author: ![treb0r](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@treb0r](https://meta.discourse.org/u/treb0r)
#### Post date: [May 22, 2017, 10:59pm UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/8 "2017-05-22T22:59:39Z")

</div>

The users were originally imported into Discourse from BBpress, and that’s where the spam users came from.  
I think there’s probably about 5000 or so.

What is the syntax to get a count of users before I run the destroy?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [May 22, 2017, 11:01pm UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/9 "2017-05-22T23:01:52Z")

</div>

put a `.count` at the end of the line above where `.destroy_all` is.

I think you can add `limit 1000` in the `where` clause to limit the query.

---

<div class="post-metadata">

### Author: ![treb0r](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@treb0r](https://meta.discourse.org/u/treb0r)
#### Post date: [May 22, 2017, 11:03pm UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/10 "2017-05-22T23:03:14Z")

</div>

Thanks. That’s great.

I’ll give it a go..

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [May 22, 2017, 11:05pm UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/11 "2017-05-22T23:05:01Z")

</div>

Not quite. The limit thing works like this:

```plaintext
User.joins(:user_stat).where("user_stats.post_count = 0 AND previous_visit_at <= '2016-05-22'::timestamp").limit(1000)

```

You can add `.destroy_all` at the end of it.

---

<div class="post-metadata">

### Author: ![treb0r](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@treb0r](https://meta.discourse.org/u/treb0r)
#### Post date: [June 5, 2017, 9:09am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/12 "2017-06-05T09:09:49Z")

</div>

Just getting around to trying this.

Does anyone have any guidance on the best way to maintain a staged copy of a production discourse forum?

I’m worried about running these kind of queries on production, even if I do have a fresh backup.

I was thinking about setting up an LXD container on my local machine and installing docker discourse there. What’s the best way of handling this?

---

<div class="post-metadata">

### Author: ![JagWaugh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagwaugh/32/69335_2.png) [@JagWaugh](https://meta.discourse.org/u/JagWaugh)
#### Post date: [June 5, 2017, 9:33am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/13 "2017-06-05T09:33:55Z")

</div>

> [@treb0r](#):
>
> Does anyone have any guidance on the best way to maintain a staged copy of a production discourse forum?

Here’s how I do it:

> [@Build a sandbox to test changes before making them live](https://meta.discourse.org/t/howto-build-yourself-a-sandbox/58298):
>
> Regardless of if you’re a moderator or an admin, you will no doubt at some time think about making some change to your live site and wonder if this will bring shame on you, and/or cause yourself an enormous amount of work to put right again. There is an easy solution to this: build yourself a sandbox! You can restore a backup of your live site to the sandbox and this will give you a representative post and user base, then you can play Dangerous Dan all you want. (If it isn’t your site, then ta…

It’s enough to import a backup just once.

Then you can try anything out in your sandbox, including checking that the latest OS patches and Discourse updates are ok. Our live site is on AWS, but if you run your sandbox on a different provider than your live site then you’ll be open to differences in OS/Droplet changes.

I don’t run any mail on the sandbox, so regardless of what I mess up it won’t start sending stuff to the users.

---

<div class="post-metadata">

### Author: ![treb0r](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@treb0r](https://meta.discourse.org/u/treb0r)
#### Post date: [June 5, 2017, 9:40am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/14 "2017-06-05T09:40:44Z")

</div>

That’s great, thanks for the reply.

One question - what happens to the urls in this situation?

If I import a backup from [mydiscourse.com](http://mydiscourse.com) into mydiscourse.dev do I need to manually change the address in the admin?

---

<div class="post-metadata">

### Author: ![JagWaugh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagwaugh/32/69335_2.png) [@JagWaugh](https://meta.discourse.org/u/JagWaugh)
#### Post date: [June 5, 2017, 9:53am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/15 "2017-06-05T09:53:57Z")

</div>

It depends. If you leave .com in .css, for example, then the sandbox will keep taking you to the live site.

iirc I just went through the settings and changed any that seemed might cause a problem, but to be absolutely safe you might want to change all of them.

Also, if you’re using S3 for storage, do something about that so that you are sure that you’re not influencing the live site.

Links to other posts inside the sandbox resolve to the corresponding item in the sandbox, but I think this might be dependent what you do with hostname in app.yml (if you copy your app.yml over from your live site then be veewy, veewy cawefuw…)

---

<div class="post-metadata">

### Author: ![treb0r](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@treb0r](https://meta.discourse.org/u/treb0r)
#### Post date: [June 5, 2017, 10:06am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/16 "2017-06-05T10:06:59Z")

</div>

Thanks. I’ll be careful 🙏

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [June 5, 2017, 12:51pm UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/17 "2017-06-05T12:51:56Z")

</div>

You could also change your DNS where you’re browsing from, so you’d not keep getting pushed to the live site.

---

<div class="post-metadata">

### Author: ![treb0r](https://avatars.discourse-cdn.com/v4/letter/t/71e660/32.png) [@treb0r](https://meta.discourse.org/u/treb0r)
#### Post date: [June 6, 2017, 8:40am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/18 "2017-06-06T08:40:40Z")

</div>

> [@pfaffman](#):
>
> You could also change your DNS where you’re browsing from, so you’d not keep getting pushed to the live site.

Great idea. Thanks. /etc/hosts did the trick.

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [July 6, 2017, 8:40am UTC](https://meta.discourse.org/t/paid-prune-spam-users/63132/19 "2017-07-06T08:40:53Z")

</div>

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