Skip to content

raymondjstone/per-plexed

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Plex Webhook Folder Toucher

Small ASP.NET Core minimal API intended to run as a Windows Service.

It exposes a single endpoint (POST /webhook) that accepts Plex Webhooks form posts and, on relevant playback events, updates the last write time of the folder that contains the media file being played.

Why: some library/file sync/indexing workflows look at folder timestamps. Touching the folder on playback can be used to trigger downstream jobs (backup, metadata refresh, external indexers, etc.).

While the behavior in this repo is intentionally specific (touching a folder timestamp, and a couple of playback events), it’s also meant as a small, practical example of how to receive Plex webhook events and trigger your own actions (run a script, call another API, enqueue a job, etc.).

What it does

  • Listens on http://0.0.0.0:5000.
  • Accepts Plex Webhooks requests (content type application/x-www-form-urlencoded) with a payload form field containing JSON.
  • Only reacts to these Plex events:
    • media.play
    • media.scrobble
  • Extracts the file path from:
    • Metadata.Media[0].Part[0].file
  • If the file exists, sets the containing directory’s last write time to DateTime.UtcNow.

Logging

The app writes a simple text log to:

  • ./logs/app-YYYYMMDD.log (relative to the deployed executable directory)

Logs are retained for 7 days.

It logs:

  • webhook receipt (webhook_received)
  • the Plex event value
  • processing_started / processing_completed for media.play and media.scrobble
  • which file/folder was touched
  • errors (including exception details)

If any field is missing/unknown, the handler returns 200 OK (so Plex doesn’t keep retrying) and does nothing.

Requirements

  • .NET 10 SDK/runtime
  • Windows (for Windows Service hosting)
  • A Plex Media Server that can reach this service over the network

Plex API lookup (to get the real filename)

Some Plex webhook payloads do not include the full filesystem path (no Metadata.Media[].Part[].file). In that case, this app will optionally call back into Plex using Metadata.ratingKey to resolve the real file path.

Set these environment variables on the machine running the service:

  • PLEX_BASEURL e.g. http://localhost:32400 or http://CHUWI02:32400
  • PLEX_TOKEN your Plex token

If these are not set, the app will log that lookup was skipped and it will not be able to touch folders.

How to get a Plex token

This token is the X-Plex-Token value.

Options:

  1. Plex Web App (Network tab)

    • Open Plex Web (https://app.plex.tv/desktop)
    • Open browser DevTools → Network
    • Click any request to your Plex server (e.g. /library/...)
    • Copy the X-Plex-Token query value
  2. Plex server Preferences file

Setting env vars on Windows

Environment variables are read from the process environment.

  • If running as a Windows Service (e.g. created with sc.exe), set them at the System level.
  • If running from Visual Studio, dotnet run, or directly from the published bin folder as your normal user, set them at the User level (or configure them in your run profile).

System-level (Windows Service)

Run PowerShell as Administrator:

setx PLEX_BASEURL "http://<plex-server>:32400" /M
setx PLEX_TOKEN "<your-x-plex-token>" /M

Restart the service after setting these.

User-level (Visual Studio / console)

Run PowerShell (non-admin is fine):

setx PLEX_BASEURL "http://<plex-server>:32400"
setx PLEX_TOKEN "<your-x-plex-token>"

Close and re-open your terminal / Visual Studio so the new environment variables are picked up.

Build

From the repository root:

dotnet build

Run (console)

dotnet run

Then test it is listening:

curl -Method Post http://localhost:5000/webhook -ContentType "application/x-www-form-urlencoded" -Body "payload={}" 

You should get a 400 for invalid payload JSON, or 200 for a valid Plex-style payload.

Install as a Windows Service

1) Publish

Publish self-contained or framework-dependent. Framework-dependent is smaller and requires the .NET runtime installed on the machine.

Framework-dependent example:

dotnet publish -c Release -o C:\Services\PlexWebhookFolderToucher

2) Create the service

Run PowerShell as Administrator.

sc.exe create PlexWebhookFolderToucher binPath= "C:\Services\PlexWebhookFolderToucher\per-plexed.exe" start= auto

Optional: set a friendly description:

sc.exe description PlexWebhookFolderToucher "Receives Plex webhooks and touches media folders on playback events."

Start it:

sc.exe start PlexWebhookFolderToucher

Check status:

sc.exe query PlexWebhookFolderToucher

Stop / delete:

sc.exe stop PlexWebhookFolderToucher
sc.exe delete PlexWebhookFolderToucher

3) Firewall

Allow inbound TCP 5000 from your Plex server to the machine running this service.

Configure Plex Webhooks

  1. In Plex, install/configure the Webhooks feature/channel (depending on your Plex version).
  2. Set the webhook URL to:
http://<service-host>:5000/webhook
  1. Ensure Plex can resolve/reach <service-host>.

Webhook payload reference

Plex webhooks post form data and include a payload JSON field.

This app specifically uses Metadata.Media[0].Part[0].file from that payload.

Notes / troubleshooting

  • Plex sends the request as application/x-www-form-urlencoded; this app will return 400 if something else is posted.
  • If you want to run this on a different port/URL, change the app.Run("http://0.0.0.0:5000") line in Program.cs.
  • If nothing happens, verify the file path provided by Plex exists on the machine where this service is running (paths are local to that machine).

About

Plex event handler (webhook and api call)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages