A Discourse Toolkit for the Rails Console #discoursehacking

I’ve been working for Digital Health Networks (e-Health Media) for the past few months, migrating them from a Google Group which lacked some of the nicer social features we have become used to, to a new shiny Discourse forum.

Discourse is a modern flat forum with some lovely features, a responsive and speedy UI (using the Ember.js client-side app framework) and a back-end based on Ruby on Rails, a mature web framework and the so-called ‘killer app’ of the Ruby language.

Even with Discourse’s awesome functionality and almost daily updates of the software containing new tweaks and features, I did find a few things I needed to do in Discourse for which there is no admin UI. I worked out some ways to do these using the Rails console, so I thought I’d put them up here for others to see and use (and add to!)

I also put most of them on Discourse Meta because that’s the main place to go for Discourse info.

They are all tested on a standard Discourse Docker installation running latest updates and cloudin’ it on a Digital Ocean Ubuntu 14.04 LTS box.

1. make a group of users get email notifications for every post on a Category

When starting a new forum (or in my case, migrating to a new platform), users do need to be encouraged to participate and visit the site using email notifications. We found that in the early few weeks following migration, traffic on the site dropped to almost nothing. We realised that this is because the default setting in Discourse is for users to get notifications only if they are @mentioned or have participated in a topic – fine for a large established site especially if lots of unrelated groups are on there, but it was killing our site.

Here is the menu where an individual user can set their Notification status. Unfortunately at the time of writing, there is no way to change the default, and no admin over-ride.

Update February 2016: There is now a comprehensive Admin UI covering all these ‘global defaults for users’. I’d advise to do it in the Admin UI.

You can get to the Rails console in Discourse by using the following commands:

ssh root@your-discourse-server
cd /var/discourse
./launcher ssh app
rails c

You need to find out the category_id of your Category that you want users to Watch:

pry(main)> Category.where(name: "Health CIO Network").first.id
=> 6

Then find the group id of the Group that you want to set the watching status of

pry(main)> Group.where(name: "Health_CIO_members").first.id
=> 43

Then set the user watching status like this:

# initialise an empty array for the users in the group
pry(main)> userlist = []

# get array of user ids who are in that group

pry(main)> GroupUser.where(group_id: **43** ).each { |u| userlist << u.user_id }

#check the array of user ids looks sensible

pry(main)> userlist
=> [1, 3, 6, 78, 112]

# set the group's users to Watching (represented in Discourse by 3) the category_id 6

pry(main)> userlist.each { |u| usr = User.find(u); CategoryUser.set_notification_level_for_category( usr, 3, 6); usr.save! }

# check the bulk Watching assignment worked

pry(main)> CategoryUser.where (category_id: 6, notification_level: 3)

It’s worth noting that the only reason I was able to work out how to do this is because I was able to look at Discourse’s data model in their source code on github – just another reason why Open Source Is The Only Way!

2. prevent Discourse from suppressing Daily Digests for users that have been seen recently

Discourse’s default behaviour is to suppress the Daily Email Digest if the user has been seen on the actual Discourse forum recently. This can be turned off per-user but unfortunately there’s no Admin UI for doing it globally. We felt that even though our users had been to the Discourse forum recently didn’t mean they’d seen everything that’s of interest.

You can switch off this suppression behaviour by getting a Rails console on your server (see #1 for instructions), and then this line:

pry(main)> User.all.each { |u| u.email_always = true; u.save }

This will of course affect all users, but they will still have the option to reinstate the Daily Digest suppression in their preferences if they want.

3. reassign posts to a different user

UPDATE: Do this in the Discourse UI – it’s easier. I didn’t realise there was an Admin only UI feature for this.

image goes here

If you want to reassign posts from User A to User B this is not currently possible via the Discourse Admin UI (or if it is, I haven’t found it yet! ). So we do it in Rails – follow the instructions in #1 to start the rails console if you haven’t already – then:

# find out a User’s ID number from their name pry(main)> User.where(username: “pacharanero”).first.id => 23

# this would transfer all of User 23’s posts to User 75 Post.where(user: 23).each { |post| post.user_id = 75; post.save }