Showing app activity in Dashboard

I’m working on a Discord music bot, “Sj’s Jukebox,” that integrates with a self-hosted Plex Media Server to stream music to Discord voice channels. The bot successfully fetches metadata, streams audio, and reports playback progress, but the sessions are consistently not appearing in the Plex Dashboard’s “Now Playing” section.

I’m hoping to get some insights into what might be missing or incorrectly configured in my Plex API calls.

How the Bot Plays Media:

  • Metadata & Stream URL Fetch: The bot uses the Plex API (/hubs/search, /library/metadata/<ratingKey>/children, etc.) to find tracks and retrieve their stream_url (e.g., /library/parts/<partId>/file.ext).
  • Audio Streaming: When a track is selected, the bot makes an HTTP GET request to the stream_url provided by Plex. The raw audio bytes from this stream are then piped through FFmpeg (for format conversion) and sent to the Discord voice channel. This means the bot is essentially “Direct Playing” or “Direct Streaming” the audio from Plex, rather than relying on Plex’s internal player.
  • Timeline Reporting: The bot periodically sends HTTP GET requests to the /:/timeline endpoint to report the playback state (buffering, playing, stopped) and current progress.

Plex Headers and Query Parameters Being Sent:

To ensure Plex recognizes the bot as a legitimate player and tracks its activity, I’ve tried to mimic the headers and query parameters observed from a Plex Web client as closely as possible.

Here’s a breakdown of what’s being sent (sensitive tokens and specific client IDs are generalized):

1. Common Headers (PLEX_HEADERS) sent with most Plex API requests (metadata, search, stream fetch, timeline):

plaintext

Accept: application/json

X-Plex-Token: [REDACTED_PLEX_TOKEN]

X-Plex-Client-Identifier: sj-jukebox-bot-[GUILD_ID]

X-Plex-Product: Sjs Jukebox

X-Plex-Provides: player

X-Plex-Platform: Discord

X-Plex-Device: Discord Bot

X-Plex-Model: standalone

X-Plex-Features: external-media,indirect-media,hub-style-list

X-Plex-Version: 1.0.0

2. Query Parameters appended to the stream_url (e.g., /library/parts/…/file.ext?param1=value1&…):

plaintext

X-Plex-Session-Id: [UNIQUE_SESSION_UUID]

X-Plex-Session-Identifier: [UNIQUE_SESSION_UUID]

X-Plex-Client-Identifier: sj-jukebox-bot-[GUILD_ID]

X-Plex-Playback-Session-Id: [UNIQUE_SESSION_UUID]

X-Plex-Provides: player

X-Plex-Device-Name: Discord (Guild Name)

X-Plex-Product: Sjs Jukebox

X-Plex-Version: 1.0.0

3. Query Parameters appended to the /:/timeline endpoint (e.g., /:/timeline?param1=value1&…):

plaintext

ratingKey: [TRACK_ID]

key: /library/metadata/[TRACK_ID]

state: [buffering|playing|stopped]

time: [ELAPSED_MS]

duration: [TOTAL_DURATION_MS]

type: music

context: focus

commandID: [INCREMENTING_ID]

X-Plex-Token: [REDACTED_PLEX_TOKEN]

X-Plex-Session-Identifier: [UNIQUE_SESSION_UUID]

X-Plex-Session-Id: [UNIQUE_SESSION_UUID]

X-Plex-Playback-Session-Id: [UNIQUE_SESSION_UUID]

X-Plex-Client-Identifier: sj-jukebox-bot-[GUILD_ID]

4. Additional Headers sent specifically with /:/timeline requests:

plaintext

X-Plex-Client-Identifier: sj-jukebox-bot-[GUILD_ID]

X-Plex-Session-Identifier: [UNIQUE_SESSION_UUID]

X-Plex-Target-Client-Identifier: sj-jukebox-bot-[GUILD_ID]

X-Plex-Device: Discord

X-Plex-Device-Name: Discord (Guild Name)

X-Plex-Platform: Discord

X-Plex-Platform-Version: 1.0.0

The Problem:

Despite sending these headers and query parameters, and ensuring that X-Plex-Session-Id, X-Plex-Playback-Session-Id, and X-Plex-Client-Identifier are consistent across the stream request and all timeline reports for a given playback session, the activity never appears in the Plex Dashboard’s “Now Playing” section. The audio plays perfectly fine in Discord, and the timeline reports are being sent every 5 seconds.

I’ve tried reporting state=buffering before the stream fetch and then state=playing during playback.

Is there a specific header, query parameter, or sequence of API calls that is absolutely critical for a “headless” client like this to register its session with the Plex Dashboard? Are there any other “secret sauce” parameters that Plex Web or official clients send that I might be missing?

Any guidance or suggestions would be greatly appreciated!