Enhance Twitch and Discord bot functionality by updating BOT_STATUS management. Added tracking for Twitch message timestamps and messages per minute, improved connection handling, and refined live status updates. Updated webapp to reflect new status attributes and modified Twitch moderation template for better chat message handling.
This commit is contained in:
+37
-1
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import time
|
||||
|
||||
from twitchAPI.twitch import Twitch
|
||||
from twitchAPI.type import AuthScope, ChatEvent
|
||||
@@ -71,6 +72,13 @@ async def _onMessage(msg: ChatMessage):
|
||||
# Stocker le message dans BOT_STATUS pour l'affichage web
|
||||
with webapp.app_context():
|
||||
from datetime import datetime
|
||||
now_ts = time.time()
|
||||
msg_timestamps = webapp.config["BOT_STATUS"].setdefault("twitch_msg_timestamps", [])
|
||||
msg_timestamps.append(now_ts)
|
||||
cutoff = now_ts - 60
|
||||
webapp.config["BOT_STATUS"]["twitch_msg_timestamps"] = [ts for ts in msg_timestamps if ts >= cutoff]
|
||||
webapp.config["BOT_STATUS"]["twitch_msg_per_minute"] = len(webapp.config["BOT_STATUS"]["twitch_msg_timestamps"])
|
||||
|
||||
message_data = {
|
||||
'username': msg.user.name,
|
||||
'text': msg.text,
|
||||
@@ -176,6 +184,19 @@ class TwitchBot():
|
||||
self.chat.start()
|
||||
except Exception as e:
|
||||
logging.error(f'Échec de l\'authentification Twitch : {e}')
|
||||
finally:
|
||||
webapp.config["BOT_STATUS"]["twitch_connected"] = False
|
||||
self._loop = None
|
||||
try:
|
||||
if hasattr(self, 'chat') and self.chat:
|
||||
self.chat.stop()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
if hasattr(self, 'twitch') and self.twitch:
|
||||
await self.twitch.close()
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
logging.info("Twitch n'est pas configuré")
|
||||
|
||||
@@ -287,7 +308,22 @@ class TwitchBot():
|
||||
await asyncio.sleep(120)
|
||||
|
||||
def begin(self):
|
||||
asyncio.run(self._connect())
|
||||
retry_delay = 15
|
||||
while True:
|
||||
try:
|
||||
if not _isConfigured():
|
||||
logging.info("Twitch non configuré, nouvelle tentative dans 60s")
|
||||
with webapp.app_context():
|
||||
webapp.config["BOT_STATUS"]["twitch_connected"] = False
|
||||
time.sleep(60)
|
||||
continue
|
||||
asyncio.run(self._connect())
|
||||
logging.warning("Session Twitch terminée, reconnexion dans %ss", retry_delay)
|
||||
except Exception as e:
|
||||
logging.error("Déconnexion/erreur Twitch: %s", e)
|
||||
with webapp.app_context():
|
||||
webapp.config["BOT_STATUS"]["twitch_connected"] = False
|
||||
time.sleep(retry_delay)
|
||||
|
||||
async def _close(self):
|
||||
self.chat.stop()
|
||||
|
||||
+57
-13
@@ -1,4 +1,6 @@
|
||||
import logging
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
import discord
|
||||
|
||||
from twitchAPI.twitch import Twitch
|
||||
@@ -47,6 +49,8 @@ async def checkOnlineStreamer(twitch: Twitch) :
|
||||
global _live_alert_first_check
|
||||
with webapp.app_context() :
|
||||
alerts : list[LiveAlert] = LiveAlert.query.all()
|
||||
bot_status = webapp.config["BOT_STATUS"]
|
||||
was_live = bot_status.get("twitch_is_live", False)
|
||||
|
||||
try:
|
||||
streams = await _retreiveStreams(twitch, alerts)
|
||||
@@ -65,17 +69,37 @@ async def checkOnlineStreamer(twitch: Twitch) :
|
||||
|
||||
# Mise à jour du BOT_STATUS pour la webapp
|
||||
if main_stream:
|
||||
webapp.config["BOT_STATUS"]["twitch_is_live"] = True
|
||||
webapp.config["BOT_STATUS"]["twitch_viewer_count"] = getattr(main_stream, 'viewer_count', 0)
|
||||
webapp.config["BOT_STATUS"]["twitch_stream_title"] = getattr(main_stream, 'title', '') or ''
|
||||
webapp.config["BOT_STATUS"]["twitch_game_name"] = getattr(main_stream, 'game_name', '') or ''
|
||||
webapp.config["BOT_STATUS"]["twitch_started_at"] = main_stream.started_at.isoformat() if getattr(main_stream, 'started_at', None) else None
|
||||
bot_status["twitch_is_live"] = True
|
||||
bot_status["twitch_viewer_count"] = getattr(main_stream, 'viewer_count', 0)
|
||||
bot_status["twitch_stream_title"] = getattr(main_stream, 'title', '') or ''
|
||||
bot_status["twitch_game_name"] = getattr(main_stream, 'game_name', '') or ''
|
||||
bot_status["twitch_started_at"] = main_stream.started_at.isoformat() if getattr(main_stream, 'started_at', None) else None
|
||||
bot_status["twitch_ended_at"] = None
|
||||
bot_status["twitch_chat_clear_notice_sent"] = False
|
||||
else:
|
||||
webapp.config["BOT_STATUS"]["twitch_is_live"] = False
|
||||
webapp.config["BOT_STATUS"]["twitch_viewer_count"] = 0
|
||||
webapp.config["BOT_STATUS"]["twitch_stream_title"] = ""
|
||||
webapp.config["BOT_STATUS"]["twitch_game_name"] = ""
|
||||
webapp.config["BOT_STATUS"]["twitch_started_at"] = None
|
||||
bot_status["twitch_is_live"] = False
|
||||
bot_status["twitch_viewer_count"] = 0
|
||||
bot_status["twitch_stream_title"] = ""
|
||||
bot_status["twitch_game_name"] = ""
|
||||
bot_status["twitch_started_at"] = None
|
||||
if was_live and not bot_status.get("twitch_ended_at"):
|
||||
bot_status["twitch_ended_at"] = datetime.now().isoformat()
|
||||
if was_live and not bot_status.get("twitch_chat_clear_notice_sent"):
|
||||
messages = bot_status.setdefault("twitch_chat_messages", [])
|
||||
now_iso = datetime.now().isoformat()
|
||||
messages.append({
|
||||
'username': 'System',
|
||||
'text': 'Live terminé, ce chat sera vidé dans 1h.',
|
||||
'timestamp': now_iso,
|
||||
'is_mod': False,
|
||||
'is_subscriber': False,
|
||||
'is_vip': False,
|
||||
'color': '#22c55e',
|
||||
'panel_only': True,
|
||||
})
|
||||
if len(messages) > 100:
|
||||
messages.pop(0)
|
||||
bot_status["twitch_chat_clear_notice_sent"] = True
|
||||
|
||||
# Premier check : synchronisation sans notification
|
||||
if _live_alert_first_check:
|
||||
@@ -113,15 +137,27 @@ async def checkOnlineStreamer(twitch: Twitch) :
|
||||
|
||||
|
||||
async def _updateBotActivity(stream: Stream | None):
|
||||
if not bot.loop or bot.loop.is_closed():
|
||||
logger.warning("Loop Discord non disponible pour mise à jour de présence")
|
||||
return
|
||||
|
||||
if stream:
|
||||
logger.info(f'Mise à jour de l\'activité : Regarde le live de {stream.user_name}')
|
||||
activity = discord.Streaming(
|
||||
name=f'Regarde le live de {stream.user_name}',
|
||||
url=f'https://www.twitch.tv/{stream.user_login}'
|
||||
)
|
||||
await bot.change_presence(status=discord.Status.online, activity=activity)
|
||||
with webapp.app_context():
|
||||
webapp.config["BOT_STATUS"]["discord_streaming_activity"] = True
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
bot.change_presence(status=discord.Status.online, activity=activity),
|
||||
bot.loop
|
||||
)
|
||||
future.result(timeout=10)
|
||||
else:
|
||||
logger.info('Aucun stream à regarder, retour à l\'activité normale')
|
||||
with webapp.app_context():
|
||||
webapp.config["BOT_STATUS"]["discord_streaming_activity"] = False
|
||||
# Remettre une humeur aléatoire
|
||||
from database.models import Humeur
|
||||
import random
|
||||
@@ -129,10 +165,18 @@ async def _updateBotActivity(stream: Stream | None):
|
||||
if humeurs:
|
||||
humeur = random.choice(humeurs)
|
||||
logger.info(f'Réinitialisation du statut : {humeur.text}')
|
||||
await bot.change_presence(status=discord.Status.online, activity=discord.CustomActivity(humeur.text))
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
bot.change_presence(status=discord.Status.online, activity=discord.CustomActivity(humeur.text)),
|
||||
bot.loop
|
||||
)
|
||||
future.result(timeout=10)
|
||||
else:
|
||||
# Si pas de humeur, remettre un statut par défaut
|
||||
await bot.change_presence(status=discord.Status.online, activity=None)
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
bot.change_presence(status=discord.Status.online, activity=None),
|
||||
bot.loop
|
||||
)
|
||||
future.result(timeout=10)
|
||||
|
||||
async def _notifyAlert(alert: LiveAlert, stream: Stream):
|
||||
stream_url = f'https://www.twitch.tv/{stream.user_login}'
|
||||
|
||||
Reference in New Issue
Block a user