-
Notifications
You must be signed in to change notification settings - Fork 25
Description
import os
import json
import asyncio
import re
import requests
from bs4 import BeautifulSoup
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes
TOKEN = os.environ['TOKEN']
URLS = [
("gov", "🏛 Гос. сотрудники", "https://forum.matrp.ru/index.php?forums/zaloby-na-gos-sotrudnikov.2991/"),
("players", "👤 Игроки (не в орг)", "https://forum.matrp.ru/index.php?forums/zaloby-na-igrokov-ne-sostoasih-v-org.2989/"),
("opg", "🔫 Члены ОПГ", "https://forum.matrp.ru/index.php?forums/zaloby-na-clenov-opg.2990/"),
]
ALL_CATS = {key: label for key, label, _ in URLS}
STATE_FILE = "bot_state.json"
def load_state():
if os.path.exists(STATE_FILE):
with open(STATE_FILE, "r", encoding="utf-8") as f:
return json.load(f)
return {"chats": {}, "seen_threads": {}}
def save_state(state):
with open(STATE_FILE, "w", encoding="utf-8") as f:
json.dump(state, f, ensure_ascii=False, indent=2)
state = load_state()
def get_chat(chat_id):
cid = str(chat_id)
if cid not in state["chats"]:
state["chats"][cid] = {"active": False, "focus": False, "watchlist": {}, "muted": [], "categories": list(ALL_CATS.keys())}
chat = state["chats"][cid]
if "categories" not in chat:
chat["categories"] = list(ALL_CATS.keys())
return chat
def parse_status(prefix_text):
if not prefix_text:
return "pending"
t = prefix_text.lower()
if any(w in t for w in ["одобр", "выдан", "принят", "удовлетвор"]):
return "approved"
elif any(w in t for w in ["отказ", "закрыт", "отклон"]):
return "rejected"
return "pending"
def status_label(status):
if status == "approved":
return "✅ Одобрена"
elif status == "rejected":
return "❌ Отказано"
return "🔄 На рассмотрении"
def parse_players(title):
m = re.search(r'^(.+?)\s+на\s+(.+?)$', title, re.IGNORECASE)
if m:
return m.group(1).strip(), m.group(2).strip()
m = re.search(r'^(.+?)\s*[|/]\s*(.+?)$', title)
if m:
return m.group(1).strip(), m.group(2).strip()
return None, None
def should_notify(chat, author, target, cat_key):
if cat_key not in chat.get("categories", list(ALL_CATS.keys())):
return False
watchlist = chat.get("watchlist", {})
muted = [m.lower() for m in chat.get("muted", [])]
focus = chat.get("focus", False)
author_l = author.lower() if author else None
target_l = target.lower() if target else None
if focus:
if not watchlist:
return False
for nick, direction in watchlist.items():
nick_l = nick.lower()
if nick_l in muted:
continue
if direction in ("both", "author") and author_l and nick_l == author_l:
return True
if direction in ("both", "target") and target_l and nick_l == target_l:
return True
return False
else:
for nick in muted:
if author_l and nick == author_l:
return False
if target_l and nick == target_l:
return False
return True
async def notify_chats(app, event_type, title, href, status, cat_key="", cat_label="", old_status=None):
author, target = parse_players(title)
cat_line = f"📂 {cat_label}\n" if cat_label else ""
author_line = f"✍️ Написал: {author}\n" if author else ""
target_line = f"🎯 На кого: {target}\n" if target else ""
if event_type == "new":
msg = f"🚨 Новая жалоба\n\n{cat_line}📌 {title}\n{author_line}{target_line}{status_label(status)}\n🔗 {href}"
else:
msg = f"🔔 Статус жалобы изменён\n\n{cat_line}📌 {title}\n{author_line}{target_line}{status_label(status)}\n🔗 {href}"
for cid, chat in state["chats"].items():
if not chat.get("active"):
continue
if not should_notify(chat, author, target, cat_key):
continue
try:
await app.bot.send_message(cid, msg)
except Exception as e:
print(f"Ошибка отправки в