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
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.
- 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.
- Get payload by reading
Content-Length
and Content-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 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