Configure webhooks that trigger on Discourse events to integrate with external services

A webhook is a way to notify external services about changes on the internet. It’s easier to setup, manage and develop than a Discourse plugin. Though, it does require you to program a little bit or understand its technical details.

In this howto, I’ll set up webhook to power a Github bot for referencing pull request brought in a forum. We’ll want to see a new comment on Github pull request when a new post has a link to it.

It’s a very simple process:

  1. Publish a new post.
  2. A webhook event happens, the payload about the new post is sent to the bot on Heroku.
  3. The bot on heroku parses the payload and check Github for existing comments. Then it creates comment when it feels appropriate.

Setting up the webhook

First, we need a webhook to feed our Github bot. Navigate to your site’s Admin section, then search for webhooks in the sidebar search. Select the + Add Webhook button to start creating a new webhook:

A webhook will simply POST the payload to the given url. https is strongly recommended. A webhook event may contain sensitive information, for example a reply to message. It may reveal information only available to staff since the payload is generated by the system user. You must fully trust this URL. Here we take a Heroku app as an example.

There are two content types available, application/json and application/x-www-form-urlencoded. We prefer json encoding.

The secret is an optional secret key for generating a signature for a given webhook event. It’s shared among you and the URL you’ve set. Once added, there will be a X-Discourse-Event-Signature in the HTTP header. It’s computed by sha256. It’s strongly recommended to set one up and verify as described below.

For this example, we only make use of a Post Event. With the Select individual events option, you can choose any events types you need. Alternatively, you can choose the Send me everything option to receive every event, even the event types that are added in the future (located at the end of the individual event list).


Triggered categories, tags, and groups are optional advanced features which allow you to filter certain events. For example, if you only care about the Staff category, you can set it so that only topic events from that category will be emitted.

Checking TLS certificate is reccomended to avoid network attacks and to keep your information secure. Be sure to mark the webhook as active and then select the Create button!

Monitoring the webhook

Click Go to events or click status information on the left side of webhook list.

With your webhook created, you will find it listed on the main webhook page. Here you can see latest delivery status (Inactive, Disabled, Successful or Failed). There are also options to edit or delete the webhook. Selecting the status or choosing the vertical dot menu’s “Events” option will take you to the list of emitted events:

On the events page, you can see various of statistics, review request and response logs (includes headers / payload / body), or attempt to redeliver individual or all failed events.

Ping is a special button to send an empty event (with no actual payload). It can help you to test your configuration. You should check out your service’s log to see if you receive a ping event.

Setting up a Github bot

We want to have a service to notify every mentions to the pull request. We’ll achieve that by hosting a bot on Heroku. It receives webhook event from a Discourse instance and processes accordingly.

The code is available here. Simply publish this to a Heroku dyno. Then you’ll need to set up some config envs in the setting page. Check out the readme of that repo.

Try it by a reply!

We’ll just need an url to the pull request.

Nailed it!

Verify and parse webhook event

Let’s dive in how it works so you can build yourself one. The flow is simple.

  1. Check out X-Discourse-Event-Id and X-Discourse-Event-Type to see whether you are interested. X-Discourse-Event also shows the internal event hook.
  2. Get payload by reading Content-Length and Content-Type.
  3. Compute sha256 HMAC of raw payload.

To be noted, X-Discourse-Event-Signature consists of sha256= and hmac of raw payload.

Webhook event type explanation

The event type is a big category of several DiscourseEvent under the hood.

Topic event

Can be restricted by categories.
Event: topic_created, topic_destroyed, topic_recovered.

Post event

Event: post_created, post_destroyed, post_recovered, validate_post.

User event

Event: user_created, user_approved.

Webhook usages

As you can see, webhook is simply a standard and configured way to notify external services. If you are looking for some kind of extension to Discourse based on changes (events) on the forum, consider webhooks. It will surely help you with a loosely coupled system. And it will be much more stable to maintain.


Last Reviewed by @tshenry on 2025-04-26T03:00:00Z

53 Likes

What is the difference between revised and updated with the Topic Events?

image

Neither updated nor revised seem to fire on a post edit - perhaps I misunderstand the intent.

What I really want is for the webhook to fire when (and only when) a specified tag is added to the topic. Is this doable?

It would also be great to have more detail on this in the wiki above, as the functionality seems to have expanded quite a bit since it was last updated.

1 Like

Is there any way to trigger a webhook on other events? Like ‘user xxx bookmarked a post?’