feat(tracking): add webhook media trackers, with Yamtrack - #304
feat(tracking): add webhook media trackers, with Yamtrack#304sean-wils wants to merge 5 commits into
Conversation
6f75add to
c5f53c2
Compare
Several trackers are fed through Jellyfin's webhook plugin and differ
only in the body they want and how they read a response.
`webhook_media_tracker` is the half they share: building the
notification, posting it, and classifying the reply into retryable,
reauth or permanent. A provider supplies a `WebhookFormat` and nothing
else.
Yamtrack is the first one on it. It keys an episode on the episode's
own ids, which is why `WebhookItem` carries both those and the series'.
A tracker may hold its credential in the url, as a path segment or a
query parameter, and a transport error prints the url it failed on.
That string becomes `last_error` and `GET /users/{id}/mediatrackers`
hands it back, so the url is dropped before the message is built.
TMDB's season listing carries no `external_ids`, so an episode reaches a tracker with nothing of its own. Yamtrack matches an episode on its own tvdb or imdb id, never the series', so it depends on `complete_episode_ids` for every episode it can place. Nothing in this file reaches that code, and a break there costs no test and no error: the webhook still takes the delivery and Yamtrack drops the episode on the floor.
c5f53c2 to
debed03
Compare
Yamtrack looks an episode up by its own tvdb or imdb id and reads nothing else. `is_matchable` passes an episode whose only ids are the series', which this provider never consults, so one that resolved to nothing was posted anyway, answered 200, and recorded as delivered. Found on a season-0 special, where TMDB carries no external ids for the episode and completion leaves it with none: the webhook went out with an empty `ProviderIds` and the watch was lost with nothing to show for it. 30% of the episodes in the library it was found on carry no tmdb id of their own, so they all rest on that lookup succeeding.
|
Tested against a real Yamtrack instance:
I'll look into fixing the unresolved episodes in a separate PR. |
|
i don't think webhooks and trackers are the same thing tho. wanted to tackle webhooks acfer this do these trackers dont have an api? |
|
They do, but they don't follow a standard and would rely on us maintaining every self hosted tracking service under the sun in isolation if they change anything. They all share the same jellyfin webhook plugin functionality so in my mind it makes way more sense to me to just follow the standard defined where at all possible. |
|
If you''d rather tackle webhooks properly maybe let's close this for now and revisit once it's ready. |
The guard refused an episode whose ids were empty, but Yamtrack reads an episode's own tvdb or imdb id and never looks at tmdb on its TV path. An episode carrying only a tmdb id has something for `provider_ids` to send and still identifies nothing, so it passed the check, took a 200, and was recorded as delivered. That is the shape most of a real library is in: TMDB gives an episode its own tmdb id and no `external_ids` at all, so the case the guard was written for was the case it let through.
|
i didnt gave it much thought but seeing your pr you provide the webhooks/body which makes sense tho yeah i need to have a proper look again because webhooks in its core are generic and used outside of trackers |
The shared half sat at `addons/webhook_media_tracker.rs`, next to the addons rather than inside the capability it serves, which read as a claim on webhooks generally. It is neither: no operator-configured URL, no body a user can edit, just the payload dialect these trackers' receivers parse. Moving it to `media_tracker/jellyfin_webhook_body.rs` puts it where its only caller lives and names it after what it builds. Yamtrack's API doc line goes with it: their write API is merged to a feature branch, not to a release, so "no released write API" is the accurate claim.
|
Yeah, agreed they should be generic. I think the split is:
Yamtrack wants the second one, so I'd keep it on the tracker trait even once generic webhooks exist. Renamed it to I'll keep this in draft until you'd have a think about it. 👍 |
|
posted an idea on discord |
Towards #207.
Several trackers are fed through Jellyfin's webhook plugin and differ only in the body they send.
webhook_media_trackeris the shared half: build the notification, post it, classify the reply. A provider supplies aWebhookFormatand nothing else.Yamtrack is the first on it. Scrob follows in its own PR once this lands.
FYI connecting a tracker has no API yet, that'll be a separate PR, so this does nothing for users until that lands.