[scrobblers] Use MediaSourceId to avoid multiple Jellyfin scrobbles

This commit is contained in:
2026-03-02 08:41:11 -05:00
parent 82a7fd8673
commit a027e877f7
5 changed files with 40 additions and 0 deletions

View File

@ -582,6 +582,7 @@ class Scrobble(TimeStampedModel):
# Metadata
source = models.CharField(max_length=255, **BNULL)
source_id = models.CharField(max_length=255, **BNULL)
log = models.JSONField(
**BNULL,
default=dict,
@ -1136,6 +1137,23 @@ class Scrobble(TimeStampedModel):
skip_in_progress_check = kwargs.get("skip_in_progress_check", False)
read_log_page = kwargs.get("read_log_page", None)
source_id = scrobble_data.get("source_id")
# If source_id is provided (e.g., MediaSourceId from Jellyfin), check for existing scrobble first
# This prevents duplicates when webhooks arrive faster than scrobble creation
if source_id:
existing_by_source_id = cls.objects.filter(
media_query,
user_id=user_id,
source_id=source_id,
).first()
if existing_by_source_id:
logger.info(
"[create_or_update] found existing scrobble by source_id, updating",
extra={"scrobble_id": existing_by_source_id.id, "source_id": source_id},
)
scrobble_data["playback_status"] = scrobble_data.pop("status", None)
return existing_by_source_id.update(scrobble_data)
# Find our last scrobble of this media item (track, video, etc)
scrobble = (