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:
- Publish a new post.
- A webhook event happens, the payload about the new post is sent to the bot on Heroku.
- 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.
- Check out
X-Discourse-Event-Id
andX-Discourse-Event-Type
to see whether you are interested.X-Discourse-Event
also shows the internal event hook. - Get payload by reading
Content-Length
andContent-Type
. - 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