diff --git a/.env.example b/.env.example index 2b70d29..6ac9226 100644 --- a/.env.example +++ b/.env.example @@ -22,11 +22,12 @@ SMTP_PASSWORD=your-app-password EMAIL_FROM=your-email@gmail.com EMAIL_TO=mmarius28@gmail.com -# Telegram +# Telegram Trigger Bot (pentru declanșare remote prin Telegram) TELEGRAM_ENABLED=false TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz TELEGRAM_CHAT_ID=your-chat-id -# Telegram Trigger Bot (pentru declanșare remote prin Telegram) -TELEGRAM_ALLOWED_USER_IDS=123456789,987654321 # User IDs autorizați (goală = toți) +TELEGRAM_ALLOWED_USER_IDS=123456789,987654321 # User IDs autorizați individual (opțional) +# TELEGRAM_CHAT_ID = grup autorizat (orice membru poate folosi bot-ul în DM/grup) +# Dacă ambele sunt goale = permite oricui TELEGRAM_POLL_TIMEOUT=60 # Long polling timeout în secunde (30-90 recomandat) diff --git a/TELEGRAM_BOT_SETUP.md b/TELEGRAM_BOT_SETUP.md index baa951b..b01c3ef 100644 --- a/TELEGRAM_BOT_SETUP.md +++ b/TELEGRAM_BOT_SETUP.md @@ -27,9 +27,13 @@ Tu (Telegram) → Bot → Rulează scraper → Trimite CSV-uri înapoi 3. Alege nume pentru bot (ex: "BTGO Scraper Bot") 4. Copiază **token-ul** primit (ex: `123456789:ABCdefGHIjklMNOpqrs`) -### 2. Obține User ID-ul Tău +### 2. Obține User ID-ul Tău (OPȚIONAL) -Ai nevoie de User ID pentru securitate (doar tu poți rula scraper-ul). +User ID e necesar doar dacă vrei să autorizezi utilizatori care **NU sunt în grup**. + +**Dacă folosești grup:** Toți membrii grupului pot folosi bot-ul automat (în grup sau DM)! + +**Pentru whitelist suplimentar:** **Opțiunea A - Folosește bot existent:** ```bash @@ -98,19 +102,20 @@ Editează `.env` și adaugă: # Bot token (același ca pentru notificări sau nou) TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrs -# User IDs autorizați (separați prin virgulă) -# DOAR acești useri pot rula /scrape din grup -TELEGRAM_ALLOWED_USER_IDS=123456789,987654321 - -# Chat ID GRUP pentru notificări automate + răspunsuri comenzi +# Chat ID GRUP pentru notificări automate + autorizare membri # IMPORTANT: Negativ pentru grupuri! (ex: -1001234567890) +# TOȚI membrii acestui grup pot folosi bot-ul (în grup sau DM) TELEGRAM_CHAT_ID=-1001234567890 + +# User IDs autorizați individual (OPȚIONAL - separați prin virgulă) +# Pentru useri care NU sunt în grup dar vrei să le dai acces +TELEGRAM_ALLOWED_USER_IDS=123456789,987654321 ``` -**Securitate:** -- `TELEGRAM_ALLOWED_USER_IDS` = doar acești useri pot rula `/scrape` din grup -- Lasă gol dacă vrei ca oricine din grup să poată rula (nesigur!) -- Bot-ul verifică User ID-ul celui care trimite comanda, NU group ID-ul +**Autorizare:** +- **Orice membru al grupului `TELEGRAM_CHAT_ID`** poate folosi bot-ul (în grup SAU în DM) +- **SAU** useri din `TELEGRAM_ALLOWED_USER_IDS` (chiar dacă nu sunt în grup) +- Dacă ambele sunt goale = bot deschis pentru oricine (NESIGUR!) ### 4. Pornire Bot @@ -153,7 +158,7 @@ Bot pornit. Așteaptă comenzi... /help - Ajutor utilizare ``` -**Securitate:** Doar userii din `TELEGRAM_ALLOWED_USER_IDS` pot rula comenzi! +**Autorizare:** Membri ai grupului TELEGRAM_CHAT_ID SAU useri din TELEGRAM_ALLOWED_USER_IDS pot rula comenzi! ### Flow Tipic în Grup @@ -308,16 +313,18 @@ TELEGRAM_ALLOWED_USER_IDS=123456789 **⚠️ ATENȚIE:** - Bot-ul are acces la credentials din `.env` -- `TELEGRAM_ALLOWED_USER_IDS` TREBUIE configurat! +- `TELEGRAM_CHAT_ID` sau `TELEGRAM_ALLOWED_USER_IDS` TREBUIE configurat pentru securitate! - Nu partaja token-ul botului - VM-ul trebuie securizat (firewall, VPN) **Best Practices:** ```bash -# ✅ Bun - doar tu și admin +# ✅ Bun - grup autorizat + whitelist individual +TELEGRAM_CHAT_ID=-1001234567890 TELEGRAM_ALLOWED_USER_IDS=123456789,987654321 -# ❌ Rău - oricine cu acces la bot +# ❌ Rău - ambele goale (oricine are acces) +TELEGRAM_CHAT_ID= TELEGRAM_ALLOWED_USER_IDS= # ✅ Bun - notificări separate de trigger diff --git a/telegram_trigger_bot.py b/telegram_trigger_bot.py index 9121913..f2d1329 100644 --- a/telegram_trigger_bot.py +++ b/telegram_trigger_bot.py @@ -46,6 +46,7 @@ class TelegramTriggerBot: self.bot_token = BOT_TOKEN self.allowed_users = [int(uid.strip()) for uid in ALLOWED_USER_IDS if uid.strip() and not uid.strip().startswith('#')] + self.allowed_group_id = CHAT_ID.strip() if CHAT_ID else None self.base_url = f"https://api.telegram.org/bot{self.bot_token}" self.last_update_id = 0 self.poll_timeout = POLL_TIMEOUT @@ -54,6 +55,7 @@ class TelegramTriggerBot: raise ValueError("TELEGRAM_BOT_TOKEN nu este setat în .env!") logging.info(f"Bot inițializat. Useri autorizați: {self.allowed_users}") + logging.info(f"Grup autorizat: {self.allowed_group_id}") logging.info(f"Long polling timeout: {self.poll_timeout}s") # Înregistrare comenzi în meniul Telegram @@ -105,11 +107,55 @@ class TelegramTriggerBot: response = requests.post(url, data=data, files=files) return response.json() + def is_member_of_group(self, user_id, group_id): + """Verifică dacă user_id este membru al group_id prin Telegram API""" + try: + url = f"{self.base_url}/getChatMember" + params = { + 'chat_id': group_id, + 'user_id': user_id + } + response = requests.get(url, params=params, timeout=5) + + if response.status_code == 200 and response.json().get('ok'): + result = response.json().get('result', {}) + status = result.get('status', '') + + # Statusuri valide: creator, administrator, member + if status in ['creator', 'administrator', 'member']: + logging.info(f"User {user_id} este membru al grupului {group_id} (status: {status})") + return True + else: + logging.info(f"User {user_id} NU este membru al grupului {group_id} (status: {status})") + return False + else: + logging.warning(f"Eroare verificare membership: {response.text}") + return False + except Exception as e: + logging.error(f"Excepție verificare membership pentru user {user_id}: {e}") + return False + def is_user_allowed(self, user_id): - """Verifică dacă user-ul are permisiune""" - if not self.allowed_users: # Dacă lista e goală, permite oricui + """Verifică dacă user-ul are permisiune (whitelist sau membru al grupului autorizat)""" + # 1. Verifică dacă e în whitelist explicit + if user_id in self.allowed_users: + logging.info(f"User {user_id} autorizat prin TELEGRAM_ALLOWED_USER_IDS") return True - return user_id in self.allowed_users + + # 2. Verifică dacă e membru al grupului autorizat + if self.allowed_group_id: + if self.is_member_of_group(user_id, self.allowed_group_id): + logging.info(f"User {user_id} autorizat prin membership în grup {self.allowed_group_id}") + return True + + # 3. Dacă ambele liste sunt goale, permite oricui (backwards compatible) + if not self.allowed_users and not self.allowed_group_id: + logging.warning("Nicio restricție configurată - bot DESCHIS pentru toți userii!") + return True + + # 4. Altfel, respinge + logging.warning(f"User {user_id} RESPINS - nu e în whitelist și nu e membru al grupului") + return False def run_scraper(self, chat_id, reply_to_message_id=None, send_as_zip=False, balances_only=False): """Execută scraper-ul"""