配置在 Discourse 事件触发的 Webhook 以集成外部服务

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

55 个赞

在主题事件中,“revised”和“updated”之间有什么区别?

updatedrevised 似乎都不会在帖子编辑时触发——也许是我误解了它们的意图。

我真正想要的是,当(且仅当)向主题添加指定标签时,触发 webhook。这可以做到吗?

如果能提供更多关于 wiki 的详细信息,那就更好了,因为该功能自上次更新以来似乎有了很大的扩展。

1 个赞

是否有办法在其他事件上触发 webhook?例如“用户 xxx 收藏了帖子?”

是否可以编写我们自己的 webhook 触发器?我找了一下,没有找到类似的东西。