Make members of a group watch a category by default

I revised the “Watch Category” plugin for my own site, incorporating code from both Jared Needell and Thomas Purchas.

You can find it here:

This version allows you to automatically watch a category or sub-category for all the users in the system or all the users in a particular group.

Features that are still missing:

  • Support for tags
  • Admin UI. This looks tricky as I don’t see any UI that supports nested arrays, which you’d probably need.
  • Users don’t automatically stop watching categories if they’re removed from a group. Should this be an (optional) feature? What happens if a user is removed from a group that prevents them from having access to a category that they’re still watching?

I don’t know Ruby and just cobbled together this for my purposes. I hope that more skilful people than myself can work on the above.


Wow, this is very exciting… hope to try it out soon!

In the official user defaults, I have every user watch all relevant categories by default. If they aren’t in a group which gives them permission to view - they simply don’t get the messages. No problem.

This way, if they are added, they automatically start getting the right messages.

I don’t think it’s important that you have users auto-stop watching categories if they are removed from a group. If they auto-start again when re-added to a group then it’s kinda 6-one-way, 1/2 dozen-the-other, however, the logic as to which groups to remove them from based on what membership could get really ichy if two groups each grant access to a given category, and a user is removed from just one group.

1 Like

Thank you for clarifying this! I’ve wanted to try it, but mailcatcher doesn’t work on my development server. And thus had no way of testing email notifications, except on production :scream_cat:

Ah, true. I hadn’t thought of this case. It could get really hairy. Like Sasquatch hairy. :monkey:

I should note that I haven’t tried my plugin in production, as I wanted to figure out the the permission stuff first. I’ll try it over the weekend. People are less likely to be looking at the forum then – in case it explodes.

I think you’re 100% fine not attempting to auto-unwatch Groups. As for Production… I’ll be in line to deploy this right after you :troll: (One of my 4 Discourse is good for testing… only 15 users in “production”)

1 Like

It’s worth noting that Watching a category doesn’t watch the category by default

it only watches the topic which are created after a member joins.


it only watches topics that are created after the member starts watching the category. Join date has nothing to do with it.

Yes but that is a bit of a technicality as the user did not exist at all prior to that point. The account creation and watch happen “at the same time”.

1 Like

Join date is relevant when I thought my user-pref to default watch key categories when they sign up.

As it is, there is no Watch a category - that entire phrase is a misconception*

There is only Automatically watch new topics in this category. And this is not what I need or expect.

EDIT - This was addressed in

*It states this clear enough in user preferences.

You will automatically watch all new topics in these categories. You will be notified of all new posts and topics, and a count of new posts will also appear next to the topic.


I’m psyched to see this improved code for this plugin and will try it out next time I have to make adjustments to the groups that are to automatically watch categories. For now the old code is working fine and I don’t want to break it. :wink: But adding a new group and category was error prone so this is a vast improvement.

Pretty much agree with all of @watchmanmonitor’s input.

1 Like

AFAICT, it works fine. It’s mostly just a cleaner way to do the same ol’ stuff.

But, as @watchmanmonitor pointed out on GitHub, you should fork the repository in order to customize it. This will prevent conflicts since the customization happens right in the code.

BTW, @Jared_Needell had an interesting bit about user.staged that I discarded, as I wasn’t sure what it was doing. My guess is that it ignored staged users?

I also agree with all of @watchmanmonitor’s input, but I’ll reply in @fefrei’s thread.


I’m wondering if any of the mailing list crowd have played around with the updated group PMs.

I’m thinking of using a category for inter-group communication and using the group PM to allow non-group users to contact them. (I thought of doing it the other way around, but it wouldn’t make sense in my case. Non-group users might not want their messages publicly viewable.)

I don’t know if group PMs are covered by Sam’s recent changes to the watching feature: Watching and tracking implementation for tags and categories

In any case, if they’re not now, I assume they would be eventually.

Can someone suggest how to programatically change the watch state for group PMs?

I’m looking for the group PM equivalent for this:

1 Like

@techAPJ: Can you point me to some example of how to script users watching group PMs and tags?

@alehandrof, for the record:

# based on
groups = {
  "Group_1" => {},
  "Group_2" => {category: "News"},
  "Group_3" => {tag: "content"},
  "Group_4" => {tag: "content", category: "News"}

# levels: :watching :watching_first_post etc.
level = :watching

groups.each do |group_name, subscriptions|
  group = Group.find_by_name(group_name)
  next if group.nil? # skip if group not found
  puts "group: #{}"
  # watch group inbox
  # found in discourse/spec/services/post_alerter_spec.rb
  # GroupUser.where(user_id:, group_id: level) # change for one user
  GroupUser.where(group_id: GroupUser.notification_levels[level]) # change for whole group
  # watch tag
  tag_name = subscriptions[:tag]
  if tag_name
    tag = Tag.find_by_name(tag_name)
    unless tag.nil?
      puts "tag: #{}"
      # TagUser.where(tag_id: GroupUser.notification_levels[:level])
      group.users.each do |user|
        watched_tags = TagUser.lookup(user, level).pluck(:tag_id)
        TagUser.change(,, TagUser.notification_levels[level]) unless watched_tags.include?(
  # watch category
  category_slug = subscriptions[:category]
  if category_slug
    category = Category.find_by_slug(category_slug)
    unless category.nil?
      puts "category: #{}"
      group.users.each do |user|
        watched_categories = CategoryUser.lookup(user, level).pluck(:category_id)
        CategoryUser.set_notification_level_for_category(user, CategoryUser.notification_levels[level], unless watched_categories.include?(

What will happen if I uninstall/deactivate this plugin? Will all watch settings stay as they are or will all group-members be “unsubscribed” from their category?

1 Like

The settings will stay the same if you disable/uninstall the plugin.

This post explains how to change settings for multiple users if, for example, you want to have them stop watching a category (i.e., “unsubscribe”):


@rriemann Your code looks interesting, but I haven’t had a chance to play around with it. Sorry for taking so long to respond. Your code, if it does what it seems to, is much better than mine. I will happily fold it into my plugin, if you (or someone else) doesn’t want to take over this rickety plugin :slight_smile:

I cannot work on this at the moment. Plugin? I think there should be some setting in vanilla Discourse.

1 Like

Agreed :slight_smile: But in the meantime, I’d like to have a UI to configure this behavior, and I’m tight on time (and with limited skills). I won’t be able to dig in to see how plugin config UIs work until end of May probably, but I might have time then.

1 Like

Is your plugin still working as intended? I forked it yesterday and adopted it but after 12 hours the people it the respective groups are still not watching the respective categories…

I changed :watching to :watching_first_post, maybe there is a problem with that?

No errors logged.

Update: Stupid me: I used the category names instead if the slugs. It should work now, I guess (any way of knowing at what times the script is executed?) Edit: yes there is: check the WatchCategory job at http://<your-site>/sidekiq/scheduler

1 Like

You can always go to siteurl/sidekiq/scheduler and run it yourself.

1 Like