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.).
- Listens on
http://0.0.0.0:5000. - Accepts Plex Webhooks requests (content type
application/x-www-form-urlencoded) with apayloadform field containing JSON. - Only reacts to these Plex events:
media.playmedia.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.
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
eventvalue processing_started/processing_completedformedia.playandmedia.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.
- .NET 10 SDK/runtime
- Windows (for Windows Service hosting)
- A Plex Media Server that can reach this service over the network
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_BASEURLe.g.http://localhost:32400orhttp://CHUWI02:32400PLEX_TOKENyour Plex token
If these are not set, the app will log that lookup was skipped and it will not be able to touch folders.
This token is the X-Plex-Token value.
Options:
-
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-Tokenquery value
- Open Plex Web (
-
Plex server Preferences file
- Find
PlexOnlineToken="..."inPreferences.xml - Plex support article (includes paths):
- Find
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 publishedbinfolder as your normal user, set them at the User level (or configure them in your run profile).
Run PowerShell as Administrator:
setx PLEX_BASEURL "http://<plex-server>:32400" /M
setx PLEX_TOKEN "<your-x-plex-token>" /MRestart the service after setting these.
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.
From the repository root:
dotnet builddotnet runThen 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.
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\PlexWebhookFolderToucherRun PowerShell as Administrator.
sc.exe create PlexWebhookFolderToucher binPath= "C:\Services\PlexWebhookFolderToucher\per-plexed.exe" start= autoOptional: set a friendly description:
sc.exe description PlexWebhookFolderToucher "Receives Plex webhooks and touches media folders on playback events."Start it:
sc.exe start PlexWebhookFolderToucherCheck status:
sc.exe query PlexWebhookFolderToucherStop / delete:
sc.exe stop PlexWebhookFolderToucher
sc.exe delete PlexWebhookFolderToucherAllow inbound TCP 5000 from your Plex server to the machine running this service.
- In Plex, install/configure the Webhooks feature/channel (depending on your Plex version).
- Set the webhook URL to:
http://<service-host>:5000/webhook
- Ensure Plex can resolve/reach
<service-host>.
Plex webhooks post form data and include a payload JSON field.
- Official-ish docs/reference (Plex Support):
This app specifically uses Metadata.Media[0].Part[0].file from that payload.
- Plex sends the request as
application/x-www-form-urlencoded; this app will return400if 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 inProgram.cs. - If nothing happens, verify the
filepath provided by Plex exists on the machine where this service is running (paths are local to that machine).