Discourse Automation

:discourse2: Summary Discourse Automation lets you automate actions through scripts and triggers. Customisation is made through an automatically generated UI.
:hammer_and_wrench: Repository Link https://github.com/discourse/discourse-automation
:open_book: Install Guide How to install plugins in Discourse


  • Easy automation of complex workflows
  • Triggers automations at specific dates, periodically, or on specific events
  • Provides automatically generated UIs to specify options for your automation


  • trigger: represents the name of the trigger, eg: user_added_to_group
  • triggerable: represents the code logic associated to a trigger, eg: triggers/user_added_to_group_.rb
  • script: represents the name of the script, eg: send_pms
  • scriptable: represents the code logic associated to a script, eg: scripts/send_pms.rb


Automations can be created and updated from Admin → Plugins → Automations, or directly from /admin/plugins/discourse-automation.

Available scripts

Script name Plugin Description
Banner Topic automation convert a topic into a banner notice
Flag post on Words automation flag a topic on creation/edition if it contains specific words
Gift Exchange automation simple implementation of the secret santa game
Pin Topic automation pin and unpin a topic in the future
Send PMs automation send PMs with support for placeholders
Suspend User By Email automation suspend a user for a specified duration
Topic required words automation enforce the presence of at least one of the specified words in the posts of a topic
Auto Responder automation given a series of keywords and associated replies, automatically respond with the corresponding reply
User Global Notice automation presents a global notice on the site for a specific user
Random Assign assign assign a random user from a given group to the given topic
Close topic automation close a topic, optionally with a closing message

Available triggers

Note that due to their nature, each script only supports certain triggers. For example it wouldn’t make sense for a script enforcing the content of a post to trigger when a user is added to a group.

Trigger name Plugin Description
API Call automation triggers when a certain API endpoint is called
Recurring automation triggers at intervals ranging from every minute to every year
Point in Time automation triggers at a specific date and time
Post created/edited automation triggers when a post of a specified topic is created or edited
User added to group automation triggers when a user is added to a group
User promoted automation triggers when a user is promoted from one specified trust level to another, or for all of them
Stalled wiki automation triggers when a wiki hasn’t been edited for a while
First accepted solution solved triggers when a user achieves their first accepted solution

More scripts and triggers to come!

Plugin API

add_automation_scriptable(name, &block)
add_automation_triggerable(name, &block)

Scriptable API


field :name, component: lets you add a customisable value in your automation’s UI.

List of valid components:

# foo must be unique and represents the name of your field.

field :foo, component: :text # generates a text input
field :foo, component: :list # generates a multi select text input where users can fill values
field :foo, component: :choices, extra: { content: [ {id: 1, name: 'your.own.i18n.key.path' } ] } # generates a combo-box with a custom content
field :foo, component: :boolean # generate a checkbox input
field :foo, component: :category # generates a category-chooser
field :foo, component: :group # generates a group-chooser
field :foo, component: :date_time # generates a date time picker
field :foo, component: :tags # generates a tag-chooser
field :foo, component: :user  # generates a user-chooser
field :foo, component: :pms  # allows to create one or more PM templates
field :foo, component: :categories  # allows to select zero or more categories
field :foo, component: :key-value  # allows to create key-value pairs
field :foo, component: :message  # allows to compose a PM with replaceable variables
field :foo, component: :trustlevel  # allows to select one or more trust levels
triggerables and triggerable!
# Lets you define the list of triggerables allowed for a script
triggerables %i[recurring]

# Lets you force a triggerable for you script and also lets you force some state on fields
field :recurring, component: :boolean
triggerable! :recurring, state: { foo: false }
# Lets you mark a key as replaceable in texts using the placeholder syntax `%%sender%%`
placeholder :sender

Note that it’s the responsibility of the script to provide values for placeholders and to apply the replacement using input = utils.apply_placeholders(input, { sender: 'bob' })


This is the heart of an automation and where all the logic happens.

# context is sent when the automation is triggered, and can differ a lot between triggers
script do |context, fields, automation|


Each field you will use will depend on i18n keys and will be namespaced to their trigger/script.

For example a scriptable with this content:

field :post_created_edited, component: :category

Will require the following keys in client.en.yml:

              label: Category
               description: Optional, allows to limit trigger execution to this category

Note that description is optional here.


This plugin doesn’t seem to have SQL queries, does it? I would like to automate tagging people in the introduction thread on my forum. But only if a user’s account is one month old, haven’t reached TL1 yet and of course hasn’t left a comment in the intro thread yet. I can’t install the plugin at the moment. But from what I gather from the description of this plugin, something like that isn’t possible? Maybe with another plugin?

I second this question/request in a way: configure Automate plugin to execute any query you can a make with DataExplorer plugin

1 Like

How does the Add user to group through User Custom Field (by @leonardo) script work?

I can’t get it to work despite trying a few things and trying to decipher the code. But it would be really helpful!

Hi Nathan!

It’s meant for a rather specific use case where you want to ensure that users belong to a certain group based on a custom field that they filled in on signup.

Let’s say the custom field is “favorite soccer team” and it contains a list of choices. The script runs on a recurring trigger, so users will eventually end up belonging to a group with the same full name (not just name) as the value they chose, if the group exists.

You can look at the tests for some synthetic examples: discourse-automation/add_user_to_group_through_custom_field_spec.rb at main · discourse/discourse-automation · GitHub

Brilliant! Would that also work for Multiselect user fields? It could be just what I’m looking for.

It will only make sense with Dropdown type user fields, because Multiselects allow choosing more than one value and the script does not support multiple groups as target. It’s doable, but it would complicate the logic a bit. PRs welcome :slight_smile:

Caveat: never use this with a text user field, because users would then be able to choose any group to be added to. So far Dropdown is the only sane choice.

1 Like