Fix YouTube notification delivery
This commit is contained in:
+10
-6
@@ -44,6 +44,7 @@ class DiscordBot(discord.Client):
|
|||||||
super().__init__(intents=intents)
|
super().__init__(intents=intents)
|
||||||
self.tree = app_commands.CommandTree(self)
|
self.tree = app_commands.CommandTree(self)
|
||||||
self.synced = False
|
self.synced = False
|
||||||
|
self.background_tasks_started = False
|
||||||
|
|
||||||
async def setup_hook(self):
|
async def setup_hook(self):
|
||||||
for cmd in (
|
for cmd in (
|
||||||
@@ -98,11 +99,15 @@ class DiscordBot(discord.Client):
|
|||||||
|
|
||||||
await cleanup_orphaned_auto_rooms(self)
|
await cleanup_orphaned_auto_rooms(self)
|
||||||
|
|
||||||
self.loop.create_task(self.updateStatus())
|
# on_ready est rappelé après une reconnexion : ne pas démarrer plusieurs
|
||||||
self.loop.create_task(self.updateHumbleBundle())
|
# boucles de surveillance, qui peuvent envoyer des notifications en double.
|
||||||
self.loop.create_task(self.updateYouTube())
|
if not self.background_tasks_started:
|
||||||
self.loop.create_task(self.updateFreeLoot())
|
self.background_tasks_started = True
|
||||||
self.loop.create_task(self.updatePatreon())
|
self.loop.create_task(self.updateStatus())
|
||||||
|
self.loop.create_task(self.updateHumbleBundle())
|
||||||
|
self.loop.create_task(self.updateYouTube())
|
||||||
|
self.loop.create_task(self.updateFreeLoot())
|
||||||
|
self.loop.create_task(self.updatePatreon())
|
||||||
|
|
||||||
async def on_disconnect(self):
|
async def on_disconnect(self):
|
||||||
webapp.config["BOT_STATUS"]["discord_connected"] = False
|
webapp.config["BOT_STATUS"]["discord_connected"] = False
|
||||||
@@ -267,4 +272,3 @@ async def on_invite_create(invite):
|
|||||||
@bot.event
|
@bot.event
|
||||||
async def on_invite_delete(invite):
|
async def on_invite_delete(invite):
|
||||||
await updateInviteCache(invite.guild)
|
await updateInviteCache(invite.guild)
|
||||||
|
|
||||||
|
|||||||
+43
-24
@@ -125,31 +125,46 @@ async def _checkChannelVideos(notification: YouTubeNotification, is_first_check:
|
|||||||
for vid, vdata in videos:
|
for vid, vdata in videos:
|
||||||
_save_video_history(notification.id, vid, vdata, notified=False)
|
_save_video_history(notification.id, vid, vdata, notified=False)
|
||||||
|
|
||||||
if videos:
|
if not videos:
|
||||||
latest_video_id, latest_video = videos[0]
|
return
|
||||||
|
|
||||||
if is_first_check:
|
latest_video_id, _ = videos[0]
|
||||||
if not notification.last_video_id or notification.last_video_id != latest_video_id:
|
if is_first_check or not notification.last_video_id:
|
||||||
logger.info(f"YouTube: synchronisation initiale pour {channel_id}, dernière vidéo: {latest_video_id}")
|
# Au démarrage, on initialise le curseur sans annoncer l'historique.
|
||||||
notification.last_video_id = latest_video_id
|
notification.last_video_id = latest_video_id
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
logger.info(f"YouTube: synchronisation initiale pour {channel_id}, dernière vidéo: {latest_video_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Le flux est trié du plus récent au plus ancien. On envoie donc toutes les
|
||||||
|
# vidéos postérieures au curseur, dans l'ordre de publication.
|
||||||
|
last_video_index = next(
|
||||||
|
(index for index, (video_id, _) in enumerate(videos) if video_id == notification.last_video_id),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
if last_video_index is None:
|
||||||
|
# Le curseur n'est plus dans le flux (ou le filtre vidéo a changé) :
|
||||||
|
# ne pas rejouer tout l'historique, mais notifier la dernière vidéo.
|
||||||
|
pending_videos = [videos[0]]
|
||||||
|
logger.warning(
|
||||||
|
f"YouTube: curseur {notification.last_video_id} absent du flux pour {channel_id}; "
|
||||||
|
f"notification de la dernière vidéo uniquement"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
pending_videos = list(reversed(videos[:last_video_index]))
|
||||||
|
|
||||||
|
embed_config = _extract_embed_config(notification)
|
||||||
|
for video_id, video_data in pending_videos:
|
||||||
|
logger.info(f"Nouvelle vidéo détectée: {video_id} pour la chaîne {channel_id}")
|
||||||
|
success = await _notifyVideo(embed_config, video_data, video_id)
|
||||||
|
if not success:
|
||||||
|
# Ne pas avancer le curseur : la vidéo sera réessayée au prochain cycle.
|
||||||
|
logger.warning(f"Notification échouée pour {video_id}; nouvel essai au prochain contrôle")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not notification.last_video_id:
|
_save_video_history(notification.id, video_id, video_data, notified=True)
|
||||||
notification.last_video_id = latest_video_id
|
notification.last_video_id = video_id
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return
|
|
||||||
|
|
||||||
if latest_video_id != notification.last_video_id:
|
|
||||||
logger.info(f"Nouvelle vidéo détectée: {latest_video_id} pour la chaîne {notification.channel_id}")
|
|
||||||
embed_config = _extract_embed_config(notification)
|
|
||||||
success = await _notifyVideo(embed_config, latest_video, latest_video_id)
|
|
||||||
if success:
|
|
||||||
_save_video_history(notification.id, latest_video_id, latest_video, notified=True)
|
|
||||||
else:
|
|
||||||
logger.warning(f"Notification échouée pour {latest_video_id}, vidéo enregistrée comme non notifiée")
|
|
||||||
notification.last_video_id = latest_video_id
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Erreur lors de la vérification des vidéos: {e}")
|
logger.error(f"Erreur lors de la vérification des vidéos: {e}")
|
||||||
@@ -242,9 +257,13 @@ async def _sendMessage(embed_config: dict, message: str, video_url: str, thumbna
|
|||||||
"""Envoie le message Discord. Retourne True si l'envoi a réussi."""
|
"""Envoie le message Discord. Retourne True si l'envoi a réussi."""
|
||||||
from discordbot import bot
|
from discordbot import bot
|
||||||
try:
|
try:
|
||||||
discord_channel = bot.get_channel(embed_config['notify_channel'])
|
channel_id = int(embed_config['notify_channel'])
|
||||||
|
discord_channel = bot.get_channel(channel_id)
|
||||||
if not discord_channel:
|
if not discord_channel:
|
||||||
logger.error(f"Canal Discord {embed_config['notify_channel']} introuvable")
|
# Le salon peut ne pas être présent dans le cache local après une reconnexion.
|
||||||
|
discord_channel = await bot.fetch_channel(channel_id)
|
||||||
|
if not discord_channel:
|
||||||
|
logger.error(f"Canal Discord {channel_id} introuvable")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
embed_title_text = _format_embed_text(embed_config['embed_title'], channel_name, video_title, video_url, video_id, thumbnail, published_at, is_short) if embed_config['embed_title'] else video_title
|
embed_title_text = _format_embed_text(embed_config['embed_title'], channel_name, video_title, video_url, video_id, thumbnail, published_at, is_short) if embed_config['embed_title'] else video_title
|
||||||
|
|||||||
Reference in New Issue
Block a user