[scrobblers] Use MediaSourceId to avoid multiple Jellyfin scrobbles
This commit is contained in:
@ -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 = (
|
||||
|
||||
Reference in New Issue
Block a user