Files
tmodbot/main.py
2026-04-14 08:41:57 +02:00

168 lines
6.1 KiB
Python

import logging
import asyncio
import aiohttp
import os
from datetime import datetime
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters
# Chargement des variables d'environnement
load_dotenv()
# Configuration du logging
logging.basicConfig(
format='%(asctime)s - %(levelname)s - %(message)s',
level=logging.INFO
)
logger = logging.getLogger(__name__)
# Config NocoDB & Telegram
NOCODB_BASE_URL = os.getenv("NOCODB_BASE_URL")
TABLE_BANNIES_ID = os.getenv("TABLE_BANNIES_ID")
TABLE_HISTORY_ID = os.getenv("TABLE_HISTORY_ID")
NOCODB_TOKEN = os.getenv("NOCODB_TOKEN")
API_TOKEN = os.getenv("API_TOKEN")
if not API_TOKEN:
logger.error("❌ API_TOKEN manquant dans le fichier .env !")
exit(1)
# Liste globale des mots bannis
BANNED_KEYWORDS = []
async def fetch_banned_keywords():
"""Récupère les mots depuis NocoDB"""
global BANNED_KEYWORDS
url = f"{NOCODB_BASE_URL}{TABLE_BANNIES_ID}/records"
headers = {"xc-token": NOCODB_TOKEN}
params = {"limit": 100}
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers, params=params) as response:
if response.status == 200:
data = await response.json()
new_keywords = [
row["MotBannies"].strip().lower()
for row in data.get("list", [])
if row.get("MotBannies")
]
BANNED_KEYWORDS = new_keywords
logger.info(f"✅ Liste des mots bannis mise à jour ({len(BANNED_KEYWORDS)} mots)")
return True
else:
logger.error(f"❌ Erreur NocoDB : {response.status}")
return False
except Exception as e:
logger.error(f"❌ Erreur connexion NocoDB : {e}")
return False
async def log_to_history(update: Update, action: str):
"""Enregistre l'action dans la table History de NocoDB"""
url = f"{NOCODB_BASE_URL}{TABLE_HISTORY_ID}/records"
headers = {"xc-token": NOCODB_TOKEN}
# On récupère l'objet message ou channel_post
msg = update.message or update.channel_post
if not msg:
return
# Identification de l'auteur
user_name = "Utilisateur Inconnu"
user_id = "N/A"
logger.info(f"🎯 get info : msg '{msg}'")
if msg.from_user:
# Cas classique (Groupe/Privé)
user_full_name = msg.from_user.full_name
user_username = msg.from_user.username
user_name = f"{user_full_name} (@{user_username or 'N/A'})"
user_id = str(msg.from_user.id)
elif msg.author_signature:
# Cas Canal avec signature
user_name = f"Admin: {msg.author_signature}"
user_id = "Canal (Anonyme)"
elif msg.sender_chat:
# Cas Canal ou Groupe anonyme
user_name = f"Chat: {msg.sender_chat.title}"
user_id = str(msg.sender_chat.id)
payload = {
"Title": f"Mod-{datetime.now().strftime('%H%M%S')}",
"Message": msg.text or "[Média]",
"User": user_name,
"UserID": user_id,
"Timestamp": datetime.now().isoformat(),
"Action": action,
"Channel": f"{msg.chat.title or 'Privé'} ({msg.chat.id})"
}
try:
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=headers, json=payload) as response:
if response.status in [200, 201]:
logger.info(f"📊 Historique enregistré pour {user_name}")
else:
logger.error(f"❌ Échec archivage ({response.status})")
except Exception as e:
logger.error(f"❌ Erreur lors de l'archivage : {e}")
async def filter_logic(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Analyse les messages et applique la modération"""
msg = update.message or update.channel_post
if not msg or not msg.text:
return
text_lower = msg.text.lower()
# Log radar pour la console
source = "Inconnu"
if msg.from_user:
source = f"@{msg.from_user.username or msg.from_user.full_name}"
elif msg.chat:
source = f"ID:{msg.chat.id} ({msg.chat.title})"
logger.info(f"📩 Message de [{source}] : {msg.text}")
for word in BANNED_KEYWORDS:
if word in text_lower:
try:
# Suppression du message
await msg.delete()
# Avertissement (dans les groupes/privé uniquement)
if update.message:
await context.bot.send_message(
chat_id=msg.chat.id,
text="🚫 Mot interdit détecté et supprimé."
)
logger.info(f"🎯 Action : Suppression du mot '{word}'")
await log_to_history(update, f"Suppression (Mot: {word})")
except Exception as e:
logger.error(f"❌ Erreur lors de la modération : {e}")
return
async def refresh(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Rafraîchit la liste des mots depuis la commande /refresh"""
if await fetch_banned_keywords():
await update.message.reply_text(f"✅ Liste mise à jour ! {len(BANNED_KEYWORDS)} mots actifs.")
else:
await update.message.reply_text("❌ Échec du rafraîchissement.")
async def post_init(application):
"""Effectue les tâches d'initialisation après le démarrage du bot"""
await fetch_banned_keywords()
if __name__ == '__main__':
# Initialisation de l'application
application = ApplicationBuilder().token(API_TOKEN).post_init(post_init).build()
# Ajout des handlers
application.add_handler(CommandHandler("refresh", refresh))
# Filtre pour capturer tous les messages textes (Groupes ET Canaux)
application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), filter_logic))
logger.info("🚀 Bot démarré avec python-telegram-bot...")
application.run_polling()