A Simple Mattermost Message Proxy

October 31, 2020 | Words by Barak Stout

Sometimes things are simple, but in-the-real-world things are never simple. Remember the old days of hanging around the office watering hole, waiting for your code to compile?

compiling

Cloud resources and automation have made it such that all the “magic” happens elsewhere these days. Daily, I will commit code or trigger a build job and move on with my day. Will I remember to go back and check on that job? Sure, when I get back to that tab. Some systems have built-in notifications that will send out an email when the job is complete. That is nice, but email can be slow, lost in my inbox or in a junk folder. Personally, I read my emails very sporadically through the day. Our primary communication channel are messaging platforms such as Mattermost. Sure would be great to get the info there. Depending on the job, some CI/CD pipelines include a Slack notification, but what if you don’t use Slack? Welcome to a notification problem.

The problem statement is simple, we want a notification message sent to a platform of our choosing using a single url. We use Mattermost so I will use that for this post, but the concept would be similar for other platforms. In the case of Mattermost, we can create an incoming web hook and use it to post messages. That requires a json payload that includes a text. If you are able to have payloads, you might be all set. In my particular use case, I could only post to a url, no payload. This solution can’t be used that out of the box. In some case we could use a plugin, if available to our CI/CD or other job we are running. That would be a particular solution that wouldn’t work in all cases. So, what do we do?

Message Proxy

Our tricky solution is to utilize a post webhook, without payload, and forward the messages to an appropriate channel with the required payloads. Essentially building a proxy messaging server. We want to pick a target channel and message into the url and have the message delivered to that channel. Some of the added benefits of using a proxy is that we don’t have our Mattermost credentials anywhere but the proxy. We could also setup an authentication and/or encryption to-from the proxy for added security. Most of all, if the url becomes a visitor to a DDOS or another attack, it can just shut down without your Mattermost going down.

The first step in building our proxy is to create a bot account. Virtually all messaging platforms will have one. Then clone the message_webhook_proxy repo. You can follow the instructions in the README on how to run the code locally, it boils down to setting some environment variables and running a node server. If you are using any other messaging platform, you can modify the message_webhook_proxy.js to make the post request. Any decent messaging platform should have an API example of how to post as a bot. Once it’s up and running you can use curl to test it out:

curl localhost:3000/post/channel/<channel_id>/msg/<message>

In order to find the channel_id you will have to do some digging into the developer tools. There are instructions in the README on how to figure that out. This might involve some trial and error, but I am sure you will figure it out.

Now for the treat part. Take this proxy code, put it in a container using the provided Dockerfile and deploy to Heroku. There are a few commands to run that are also in the README. You will need to set the environment variables in Heroku, similar to the localhost version. Once that is all done, you will end up with a server you can use via post and have the messages delivered to your chat. For example, any time our site gets deployed, we get a little message posted to our media channel that looks like this:

Rafty Posting

Now, it’s 100% in the cloud. When one machine is done with the work, another machine can let me know that the work is done ;)

Happy Halloween :ghost: :jack_o_lantern:


TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES. TOGETHER, LET'S MAKE WAVES.