Plex activity monitor using WEBHOOKS, the easy way

The post is updated using node.js instead of Tautelli, check first point.

Hi, a year ago ! created a script before that checked the status of a plex client and updated a sensor. Problem was it didn’t use webhooks for instant triggers. If you want reasonable fast update of a sensor you hade to run the script almost every second 24/7…so webhooks is a much better solution since it gives you the update.

This script is written to be used with a plex client (more than one soon) that you want to use for automations, not to monitor all your users/devices etc.

1. Using node.js

  • Install node.js using the terminal:
    curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
    sudo apt-get install -y nodejs
    sudo apt-get install -y build-essential
  • You can verify the installation by running:
    node -v
    It should output the version of node you installed.

In your home-directory (or other directory with r/w permissions), create a file called Index.js and paste this text into it:

var express = require('express')
  , request = require('request')
  , multer  = require('multer');

var app = express();
var upload = multer({ dest: '/tmp/' });

app.post('/', upload.single('thumb'), function (req, res, next) {
  var payload = JSON.parse(req.body.payload);
  console.log('Got webhook for', payload.event);

 // USER INPUT: You only need the comment below once to get the UUID. Play a movie on the client you want to automate and run the script. You can comment out it when you got the UUID.
   console.log(payload.Player.uuid)


  // USER INPUT: Insert the UUID you got from the console instead of 'PLAYER-UUID'
  if (payload.Player.uuid == 'PLAYER-UUID' && payload.Metadata.type != 'track') {
    var options = {
      method: 'POST',
      json: true,
  //  USER INPUT: Replace 123.456.7.8 with your HASS IP, you may need to change the port number too.
      url: 'http://123.456.7.8:8123/api/states/sensor.plex_sensor',
  //  USER INPUT: Replace 'ABC123' with your hass-password, if you don't have a password you can remove 'x-ha-access' and the password 'ABC123'.
      headers: {'Content-Type': 'application/json',  'x-ha-access': 'ABC123'}
    };

    if (payload.event == 'media.play' || payload.event == 'media.resume') {
      console.log('Plex client playing');
      if (payload.Metadata.type == 'episode'){
      options.body = {'state':'Playing','attributes':{'series':payload.Metadata.grandparentTitle,'title':payload.Metadata.title,'season':payload.Metadata.parentIndex,'episode':payload.Metadata.index,'client':payload.Player.title, 'mediatype':payload.Metadata.type,'user':payload.Account.title}};
      }
      else{
      options.body = {'state':'Playing','attributes':{'title':payload.Metadata.title, 'client':payload.Player.title, 'mediatype':payload.Metadata.type, 'user':payload.Account.title }};
      }
      request(options);
    } else if (payload.event == 'media.pause') {
      console.log('Plex client paused');
      options.body = {'state':'Paused'};
      request(options);
    } else if  (payload.event == 'media.stop'){
      console.log('Plex client stopped');
      options.body = {'state':'Stopped'};
      request(options);
    }
  }

  res.sendStatus(200);
});
// USER INPUT: Choose the port of your liking.
app.listen(12000);

In the code, where it says // USER INPUT: you should modify the code with your settings.

  • Go into your plex account, add a webhook and add the IP where the node.js is running and the port chosen above, default is 12000.

In the terminal run:

node /PATH/WHERE/THE-FILE-IS-SAVED/Index.js

This method is more reliable and faster.

2. Using Tautelli
This project requires that you have:

  • Plex Pass
  • Tautulli (Plexpy)

Tautulli uses webhooks to get information from your PMS, and we will take advantage of that. In the Tautulli go to Settings -> Web Interface and enable API.

Paste this python-code into a a file, remember path and filename, you need to specify that in the configuration tab below:

import json
import requests

###### User settings
Plex_url = 'IP_to_TAUTULLI/PLEX' #Change this (example "12.34.56.78")
Tautelli_port = 'PORT_TO_TAUTULLI' #Change this (example "8181")
apikey = 'API_FROM_TAUTULLI' #Change this (example "abcdefghi")
hassSecret = 'HASS_PASSWORD' # Change this (example "test123")
hassUrl = 'HASS_URL' #Change this (example "14.12.12.14")
hassPort = 'HASS_PORT' #Change this (example "8123") 
player = 'MY_IPHONE' #The client name you want to run automations with, should match the name in Plex.
#############

url = 'http://' + Plex_url + ':' + Tautelli_port + '/api/v2?apikey=' + apikey + '&cmd=get_activity'
r=requests.get(url)

myJson = json.loads(r.text)
sessions = myJson['response']['data']['sessions']

if len(sessions) > 0:
 for thissession in sessions:
   if thissession['player'] == player:
     playerstate = thissession['state'].title()
     thistitle = thissession['full_title'].title()
     thisuser = thissession['user'].title()
else:
  playerstate = 'stopped'.title()

if playerstate == 'Buffering':
  playerstate == 'Playing'

url = 'http://' + hassUrl + ':' + hassPort + '/api/states/sensor.plex_sensor'

if playerstate != 'Stopped':
  data = '{"state":"' + playerstate + '", "attributes": {"Title":"' + thistitle + '","User":"' + thisuser + '","Player":"' + player.title() + '"}}'
else:
  data = '{"state":"' + playerstate + '", "attributes":{}}'

headers = {'Content-Type': 'application/json', 'x-ha-access': hassSecret}
r = requests.post(url, headers = headers, data = data)

Then go to notifications agents and add “script”. Add the folder path and later choose your script in the configuration tap. In the Triggers tab choose:

  • Notify on play
  • Notify on pause
  • Notify on stop
  • Notify on resume

Click save. You’re done! The status of sensor.plexstatus should update instantly. In the next revision of this script, I’ll add support for watching the status of more than one client to use for automation trigger.

Change http:// to https:// in the code if you use https://
Let me know if doesn’t work for you. :slight_smile:

3 Likes

I’ve been using Tautulli to monitor the status of my Plex using mqtt for awhile and it’s been solid. Pretty easy to setup. I don’t think you need Plex Pass to use Tautulli.

You need plex pass to use webhooks.

So just to clarify… the above script runs from tautulii and nothing needs to be done in homeassistant?

Correct, the script creates an entity in hass: sensor.plexsensor.

I haven’t done much with the events from Plex yet but would this be better than using Tautulli and the MQTT notification feature?

what kind of response time are you experiencing with this?

Around 1s for the sensor.plexsensor to get updated. And remeber that my PMS/Tautulli is at a remote place and I run a VPN tunnel between HASS and the remote server which increases the response time.

hmm does not seems to be working… image

I guess this is not really going to work with https and ssl cert just yet…

Aha, I removed my ip-address and the ‘http’ got deleted. I updated my post, try now.

Do you have your own ssl cert, it’s prett easy to modify to use ssl. I use nginx/cloudfare so it’s don’t have that problem. Let me known and I can inbox you the change.

yes im using letsencrypt for ssl on my tautulii server and my homeassistant server… they both are using the same cert.

It should work then, try it out and let me know if it doesn’t.
Don’t forget to change the http to https in the code :slight_smile:

its not…


I blacked out the host and port… but they are the same url listed in the cert.

import requests

url = 'https://home.***.se'

r=requests.get(url)

print(r.text)

I use this sample that connects to my HASS externally without any problem, and it’s https. But my ssl cert is issued by cloudflare and is not stored locally. If your is stored localy you could try his:

requests.get('https://***.com', verify='/path/to/certfile')

So just add verify='/path/to/certfile' in the requests.

yea im not doing something right… guess the /path/to/certfile needs to be a local path… tautullii is running on my windows based plex server and homeassistant is running on a raspberry pi so not sure what that needs to be… seems to be failing on the homeassistant url.

What if you copied it over to your raspberry pi? Is it giving you a ssl error for hass?

yea its a ssl error for hass seems to be fine for tautulli…

So just to clarify… the pi is running ssl using the same certs that the tautulli server is using. Both are stored on each device respectively. The error im getting is listing the homeassistant ip and port number with the error above. Ive tried it different ways as well using the domain name and external port and even internal ip and internal port 8123 still get the same error.