DEV Community

Jon Neverland
Jon Neverland

Posted on • Originally published at on

Adding webhooks to Matrix

Adding webhooks to Matrix

Now that you got your homeserver you want some integrations right? Webhooks seems like a great place to start - it's fairly easy to set up and the use cases are virtually unlimited.

I have a couple of scenarios in Huginn for posting tomorrows weather, top voted posts from various subreddits and alerts from Grafana, to mention a few.

In this guide we will use an application service (👈 read this if you haven't) called matrix-appservice-webhooks to be able to add webhooks to a room by just issuing a command. It has a Docker image so it fits right into my standard Traefik setup. If your Synapse isn't set up like mine you'll have to make some adjustments.


First let's get the files we need for the appservice.

cd /opt/matrix # or wherever your stuff is 
mkdir matrix-appservice-webhooks
cd matrix-appservice-webhooks
curl -o database.json
curl -o config.yaml

Enter fullscreen mode Exit fullscreen mode

Then we replace paths in database.json...

sed -i 's/db\//\/data\//' database.json

Enter fullscreen mode Exit fullscreen mode

... so that it looks like this.

  "defaultEnv": {
    "ENV": "NODE_ENV"
  "development": {
    "driver": "sqlite3",
    "filename": "/data/development.db"
  "production": {
    "driver": "sqlite3",
    "filename": "/data/production.db"

Enter fullscreen mode Exit fullscreen mode

We edit config.yaml...

nano config.yaml

Enter fullscreen mode Exit fullscreen mode

... and put in the (internal) URL to Synapse - accessible via our Docker network - the public URL for our webhooks and our Matrix domain name.

  # The name here is from docker-compose.yaml
  url: "http://synapse:8008"

  # Domain for you matrix server, with subdomain if needed
  domain: ""

  # This domain will be proxied via Traefik
  hookUrlBase: ''
  # Because we're in a container
  bind: ''

Enter fullscreen mode Exit fullscreen mode

☝️ I only included the settings that needs to be changed for this guide. Edit the others according to comments in the file and remember to replace

Registration file

Then we need to generate a registration file to add to Synapse via homeserver.yaml.

docker run --rm \
  -v /opt/matrix/matrix-appservice-webhooks:/data \
  turt2live/matrix-appservice-webhooks \
  node index.js -r \
  -f /data/appservice-registration-webhooks.yaml \
  -u "http://webhooks:9000" \
  -c /data/config.yaml

Enter fullscreen mode Exit fullscreen mode

Now you should have a file called appservice-registration-webhooks.yaml in your appservice directory. Copy that file to your Synapse dir (/opt/matrix/synapse in my case).

sudo cp appservice-registration-webhooks.yaml ../synapse

Enter fullscreen mode Exit fullscreen mode

Add/edit the line below in your homeserver.yaml, so that Synapse is aware of the appservice.

app_service_config_files: ['/data/appservice-registration-webhooks.yaml']

Enter fullscreen mode Exit fullscreen mode


Time to add the container to our docker-compose.yaml.

    image: turt2live/matrix-appservice-webhooks
    restart: unless-stopped
      - synapse
      - web
      - default
      - "/opt/matrix/matrix-appservice-webhooks:/data"
      - "traefik.enable=true"
      - ""
      - "traefik.port=9000"
      - ""

Enter fullscreen mode Exit fullscreen mode

☝️ If you've followed my previous guide, this should be enough. Remember to replace

Now we're all set and ready to start the service.

docker-compose up -d webhooks
docker-compose restart synapse

Enter fullscreen mode Exit fullscreen mode

Adding hook to a room

Go to a room where you want to have a webhook, invite the bot user (adjust handle if you changed it in config.yaml), send the message !webhook in the room and you should see something like this 👇

Adding webhooks to Matrix

Posting them hooks

Test your webhook with an app like Insomnia / Postman or just use curl.

curl --header "Content-Type: application/json" \
     --data '{
       "text": "Hello world!",
       "format": "plain",
       "displayName": "My Cool Webhook",
       "avatarUrl": ""
     }' \

Enter fullscreen mode Exit fullscreen mode

Adding webhooks to Matrix

Updating hooks

The first time you post the appservice will invite a virtual user with the name and avatar you set. If you change displayName on succeeding posts another user will join and if you change avatarUrl but not displayName the avatar will update.

That's it! Have fun 🎉

Top comments (1)

erickhavel profile image
Erick Havel

Hi Jon,

I'm trying to add webhooks using your guide (although I'm using nginx-proxy instead of Traefik) and it fails when trying to fire up the webhooks container.

[ERROR] { [M_UNKNOWN_TOKEN: Invalid macaroon passed.]


I've changed the provisioning secret in config.yaml to match the macaroon_secret_key in homeserver.yaml but it doesn't help. Maybe I should use something else here?

Any idea what I could do from here? I tried googling but couldn't find anything helpful.