OBS client in Go, and JXA apps with Dock extras
Tags: obs, go, jxa, devlog
Published: 2018-09-20 14:27:41

---
title: OBS client in Go, and JXA apps with Dock extras
published: true
description: Today I built a client to work with a plugin to OBS that lets you remotely control it over Websocket. We can eventually generate types for all the messages, but what we got done today using maps for messages is already useful. I also spent maybe too much time playing with MacOS bundles for JXA applications and plugins, specifically for extending the Dock. But I mostly figured it out.
tags: obs, go, golang, jxa, devlog
---
Here's a quick update on what I did today on [Workbench](https://www.twitch.tv/progrium) where I stream my open source innovation work. 

I wanted to build a Go client to interact with [OBS](https://obsproject.com/), the tool of choice for most streaming. There's a plugin that gives OBS a websocket server to make requests and get events with simple JSON messages. The plugin project also provides a JSON schema for all the request and event messages, so I figured that would come in handy to generate types in Go. However, before generating anything I wanted to make a basic client that works with maps.

It took 45 minutes to get an OBS instance running with the plugin. I didn't realize until my stream began that I'd probably have to restart OBS, which would kill the stream. I was able to get a second instance running but it didn't load the plugin, so Josh, a regular viewer, suggested running it on another machine. And I did have a windows machine right here, so I installed it there and accessed it over Remote Desktop. I almost went down the path of running it in Docker and accessing it over X11. This was much easier. 

I spent some time with an existing [Python client](link) to make sure the websocket plugin was working. It also took a bit of time to get that working because the library was a bit rough. But it worked, so I moved on.

I then started with a demo Go script that made a connection and did their just-complicated-enough-to-be-annoying auth challenge all manually. Then I did the same request I tried in Python. It worked, so then I refactored the code into an actual client. The client tracks message IDs and routes messages to waiting response channels or the events channel. It also handles the authentication if the server requires it. 

This let me clean up the original demo script and even though we don't have
message types yet, this is already a pretty useful library. 

Obviously the next step is to generate types, but I might hold off on that until later because I'd rather get started using the client. We'll see what I'm using it for in the next week or so.

Another totally unrelated thing I spent a lot of time on earlier in the day was understanding MacOS app bundles, plugins, and ways to package plugins with JXA script bundles. Plugins are used for all kinds of stuff to integrate with MacOS.  If you make an app bundle using [osacompile](https://ss64.com/osx/osacompile.html), it won't load plugins. I tried playing with an extension to set the badge and menu for an application in the Dock before it's running. Apparently, the Dock dynamically loads extensions into a process that provides extra Dock features for an app even when it's not running. This is why I won't be able to implement the extension in JXA, but I did at least get it working in an app that is JXA. 

I also got an example app to build all the pieces and tricks without using XCode. I'll be using this for a future project as well. 

{% youtube C0wAbBEJDiw %}