I created benzaiten to try and make it easier for people to see updates for the Keep Dreaming Project. It’s pretty basic but does the job well enough. The goal was to get notifications in Discord and on for various Phabricator events and for whenever a container was successfully built on Docker Hub. Phabricator, Docker Hub, and Discord all support webhooks to various degrees so all I needed to do was tie these things together.

benzaiten is a docker container that listens for incoming webhooks, packages that information into a message, and then saves the message as a json file and sends out the message as a Discord webhook.


The Docker container uses multi-stage builds to make the final container as lightweight as possible. The first stage builds adnanh/webhook which is used to receive the incoming webhooks. The second stage builds all the python dependencies. The final stage copies everything that was built in the previous stages and copies in the various python and shell scripts.

Incoming Webhooks

Phabricator can be set up to send out a webhook for all kinds of events (commits, new tasks, etc) however the webhook itself consists of very little information.


  "objectIdentifier": "PHID-XXXX-abcdef",
  "constraints": {
    "phids": [

To get useful data from this I used a python wrapper for Phabricator’s Conduit API to query the relevant search endpoints using the PHID’s included in the webhook.

Docker Hub can be set up to fire off a webhook every time a docker container is built successfully, this just needs to be parsed for relevant information to include in the message.

Processing Webhooks

When adnanh/webhook receives a webhook it does some basic verification and parses the webhook for information which it saves into environment variables, it then calls the relevant shell script which in turn calls the relevant python script (there was some issue with running the python script directly so this is a workaround). The python scripts grab the information from the environment variables, query whatever other info they may need, and then package it all into a message.

Sending The Message

Since I don’t need all the features of an actual Discord bot I’m using a Discord webhook API wrapper to send the messages to the Keep Dreaming Project Discord server. As far as updating with the latest updates benzaiten saves all the messages as json files. I use githugo with and have it rebuild the site every few hours, when it rebuilds it grabs these json files and parses them for the ‘Recent Activity’ section of the website.


Since I plan to move away from using Discord at some point benzaiten will need to be modified to work with Matrix, at which point I might also rewrite it in Rust.