Skip to content

Commit 7f6bf59

Browse files
committed
fix: handle duplicated webhooks
1 parent bfcccf7 commit 7f6bf59

File tree

1 file changed

+43
-11
lines changed

1 file changed

+43
-11
lines changed

src/integrations/webhooks/base.py

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ def _process_tv(self, payload, user, ids):
7575
episode_number,
7676
)
7777
if mal_id:
78-
logger.info("Detected anime episode with MAL ID: %s", mal_id)
78+
logger.info(
79+
"Detected anime episode via MAL ID: %s, Episode: %d",
80+
mal_id,
81+
episode_offset,
82+
)
7983
self._handle_anime(mal_id, episode_offset, payload, user)
8084
return
8185

@@ -323,17 +327,45 @@ def _handle_tv_episode(
323327
episode_item = season_instance.get_episode_item(episode_number, season_metadata)
324328

325329
if self._is_played(payload):
326-
app.models.Episode.objects.create(
327-
item=episode_item,
328-
related_season=season_instance,
329-
end_date=timezone.now().replace(second=0, microsecond=0),
330-
)
331-
logger.info(
332-
"Marked episode as played: %s S%02dE%02d",
333-
tv_metadata["title"],
334-
season_number,
335-
episode_number,
330+
now = timezone.now().replace(second=0, microsecond=0)
331+
latest_episode = (
332+
app.models.Episode.objects.filter(
333+
item=episode_item,
334+
related_season=season_instance,
335+
)
336+
.order_by("-end_date")
337+
.first()
336338
)
339+
340+
should_create = True
341+
# check for duplicate episode records,
342+
# sometimes webhooks are triggered multiple times #689
343+
if latest_episode and latest_episode.end_date:
344+
time_diff = abs((now - latest_episode.end_date).total_seconds())
345+
threshold = 5
346+
if time_diff < threshold:
347+
should_create = False
348+
logger.info(
349+
"Skipping duplicate episode record "
350+
"(time difference: %d seconds): %s S%02dE%02d",
351+
time_diff,
352+
tv_metadata["title"],
353+
season_number,
354+
episode_number,
355+
)
356+
357+
if should_create:
358+
app.models.Episode.objects.create(
359+
item=episode_item,
360+
related_season=season_instance,
361+
end_date=now,
362+
)
363+
logger.info(
364+
"Marked episode as played: %s S%02dE%02d",
365+
tv_metadata["title"],
366+
season_number,
367+
episode_number,
368+
)
337369
else:
338370
logger.info(
339371
"Episode not marked as played: %s S%02dE%02d",

0 commit comments

Comments
 (0)