Building an integration for Plex with Azure API Management
At home, I run a Plex media server. I’ve added a TV receiver to the setup to have a real DVR that I can control remotely. It’s great!
Here’s how it looks in Plex when I want to record all the episodes for The Blacklist:
(for some reason, Plex reverts to using Swedish for content description within the DVR — I suspect this is an issue with my TV/cable operator. I speak very brokenly Swedish, so I don’t mind.)
It even offers to record new airings only:
Plex has an API that I’ve never really needed. I record movies and TV episodes and watch them when I have time. Occasionally, I also load breakout sessions from conferences to watch when on the go. I’ve set up Tautulli in a Docker container to track what’s going on with my Plex setup.
Recently, I needed to build a system to notify my family members when interesting new content is added to my Plex setup. Ideally, I could send an email or a text message when a new episode was added to a favorite series, for example.
Tautulli, which is a Python-based monitoring system for Plex, has a rich engine for doing just this:
Yet somehow, this seemed too easy. So, I set out to build something more custom – perhaps not because I needed it, but to learn more about Azure.
Tautulli has all the whistles I would ever need – even a built-in newsletter feature – but this time, I need to notify a family member that a new episode is available.
Designing the solution
As I mentioned, Plex has a REST API built-in. I could poll this API, but Plex also includes a Webhook capability. When an event is triggered, I can call a custom endpoint to manage it and take it from there. To add a new Webhook, the interface is comically sparse:
I couldn’t find a way to define if it’s a POST or a GET or to inject any additional data within the headers. In essence, Plex will call this URL via an HTTP GET. I think I’m fine with that for now. Again, Tautulli has much more to offer on this front:
It’s good to know I can always revert to Tautulli’s capabilities, should it come to that. But onwards with a vanilla Plex!
Now that I know Plex can trigger an HTTP request, I need a place to land that in Azure. The options obviously would include any of the following:
- Azure Functions
- Azure API App
- Logic App
- A custom API in a VM
I chose to start with a Logic App, as this allows me to rapidly build the custom integrations I might need later on. Also, I am not suspecting I will be getting a lot of requests – perhaps a few per week.
To secure my Logic App and hide it a bit further, I chose to utilize Azure API Management. It has a consumption-based tier, essentially making it a lucrative and affordable option to publish my APIs.
End-to-end, my architecture looks as follows:
Building it
I provisioned a vanilla API Management, and selected the Consumption tier. Pricing is 2.9 €/million calls, the first 1 million calls are free.
Before publishing anything, I created a new Logic App. It’s rather simple – it’s HTTP triggered, and I parse all the elements within the payload. This is how it looks:
How did I know what the payload is? Easy! I made a test call from Plex, and captured all the data, and then trained the Logic App with that same data.
Based on the data, I get a lot. As Plex will call this API for all events, it simply pushed out everything it knows about the event. Here’s a snippet of the JSON payload, when someone stopped a movie from playing – the event thus is media.stop:
You can view a list of all the supported events here. I’m interested in only library.new, so I’ll discard everything else.
In my second block, I’ll verify what the event is – and if it’s library.new, I’ll send an email:
Admittedly, it’s very bare-bones, but again – it’s so easy to amend this, and I still have to add API Management in front of my Logic App first.
So, let’s move on to API Management then. I’ll need to introduce my Logic App-based API first – and as a nice gesture, Microsoft has added a direct link for this under APIs:
And configuring the API is easy:
Once added, I’ll have to remove the subscription verification from my API endpoint. This is due to Plex being unable to send out header data, and I’d rather not store sensitive keys such as the subscription key of API Management to my Plex server in clear text.
Is this better, then? Perhaps not, but it really is the only meaningful way. I could add a custom client-side certificate check-in my Logic App, but again – Plex cannot manage that either. Without resorting to more advanced trickery such as a dedicated VPN tunnel, I’ll have to publish my API in a bare-bones manner like this. Ideally, I could leverage VNET-bound access, but that isn’t available in this cheap consumption-based API Management instance.
I’m now leaning towards moving back to Tautulli, as I could easily push my API Management subscription details in the header. But for now, I’ll continue with this simple approach and perhaps revisits this in a later post.
All that is now needed is a Webhook added to Plex – it will simply contain the URL to my API Management-exposed API:
Testing it
When Plex now initiates an action that warrants a call via the Webhook, my API Management will receive it and route the request to the Logic App.
Logic App parses the JSON payload, and when it finds new content that was added, will email me.
It all works very well, and usually the Logic App takes about 500-600 ms to complete.
Further development ideas
It’s very static now. So my family members would need to have a way of subscribing to the content they’d like to be notified on. Perhaps a simple SharePoint list would do, as I’d like to avoid having them install any additional apps for a simple feature like this.
I’m now sending an email notification. I did aim to use Azure Communication Services, but all telephony services (such as SMS) are restricted to US-based tenants only.
I’m also acutely aware of the fact that Plex has a notification system in their mobile app. But many of my family members do not use the Plex app at all. So this solution would perhaps work best if I could trigger a notification based on individual preferences (perhaps based on a user’s viewing patterns).
In summary
This was a nice and quick build, where I got to lay the base for using Azure API Management in my future hobby projects. The setup is very loosely built, and I can easily now change any component – Plex notifications to Tautulli and notifications from email to something more decent. The Logic App could be evolved into figuring out what the user wants and only send a notification when it makes sense.