base demo
This commit is contained in:
168
main.py
Normal file
168
main.py
Normal file
@@ -0,0 +1,168 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user