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

Firstly, we need a webhook to feed our Github bot. Go to API - Webhooks panel and create 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 system user. You must fully trust this URL. Here we take a heroku app as an example. (No dash allowed in the url, will fix soon.)

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 generate a signature for given webhook event. It’s shared among you and 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 up one and verify as the instruction (see below).

For this example, we only make use of post event. You can definitely choose event type you need. Check Send me everything to receive every event, even the event type we will add in the future.

Triggered categories/groups are advanced features which allows you to filter some event. For example, if only you cares about Staff category, you can add Staff category so that topic event will happen accordingly.

Then, we checked TLS certificate so that we can avoid some network attacks and keep your information secure.

At last, checked active and click create!


Monitor how is the webhook

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

Go to list and Edit webhook allows you to jump around. Ping is a special button to send a 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.

You can also read every event to see how it works. We shows the response status code, event id, event happened time and completion time of each event. If you want, the request/response headers and body are available. If you are debugging webhook or your service, Redeliver button can help you to send the exact request again.

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 process 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 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 kinds of extensions to Discourse based on changes (events) on the forum, consider webhooks. It will be sure to help you with a loosely coupled system. And it shall be much more stable to maintain.


Last Reviewed by @SaraDev on 2022-06-06T18:00:00Z

52 Likes