diff --git a/edu_master/compose.yaml b/edu_master/compose.yaml index 5b934f7..e0f4e9b 100644 --- a/edu_master/compose.yaml +++ b/edu_master/compose.yaml @@ -13,9 +13,9 @@ services: retries: 5 playwright-service: - image: mcr.microsoft.com/playwright:v1.56.0-noble + image: mcr.microsoft.com/playwright:v1.56.0-jammy restart: unless-stopped - command: npx -y playwright run-server --port 3000 --path /ws + command: npx -y playwright@1.56.0 run-server --port 3000 --path /ws ports: - "3000:3000" diff --git a/edu_master/webinar-checker/Dockerfile b/edu_master/webinar-checker/Dockerfile new file mode 100644 index 0000000..67f5496 --- /dev/null +++ b/edu_master/webinar-checker/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Install dependencies +RUN pip install --upgrade pip && pip install playwright==1.56.0 redis requests + +COPY checker.py . + +CMD ["python", "checker.py"] diff --git a/edu_master/webinar-checker/checker.py b/edu_master/webinar-checker/checker.py new file mode 100644 index 0000000..3f9e913 --- /dev/null +++ b/edu_master/webinar-checker/checker.py @@ -0,0 +1,147 @@ +import os +import time +import logging +import redis +import requests +from playwright.sync_api import sync_playwright + +# Configure logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger(__name__) + +# Load configuration +WEBINAR_URL = os.getenv('WEBINAR_URL', 'https://edu.edu.vn.ua/webinar/useractive') +WEBINAR_CHECK_INTERVAL = int(os.getenv('WEBINAR_CHECK_INTERVAL', 60)) +REDIS_HOST = os.getenv('REDIS_HOST', 'redis') +REDIS_PORT = int(os.getenv('REDIS_PORT', 6379)) +PLAYWRIGHT_WS = os.getenv('PLAYWRIGHT_WS', 'ws://playwright-service:3000/ws') +USER_AGENT = os.getenv('USER_AGENT', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36') +WEBINAR_TELEGRAM_TOKEN = os.getenv('WEBINAR_TELEGRAM_TOKEN') +WEBINAR_TELEGRAM_CHAT_ID = os.getenv('WEBINAR_TELEGRAM_CHAT_ID') + +def send_telegram_message(message): + """Send message to Telegram.""" + if not WEBINAR_TELEGRAM_TOKEN or not WEBINAR_TELEGRAM_CHAT_ID: + logger.warning("Telegram credentials not configured. Skipping message.") + return + + try: + url = f"https://api.telegram.org/bot{WEBINAR_TELEGRAM_TOKEN}/sendMessage" + payload = { + 'chat_id': WEBINAR_TELEGRAM_CHAT_ID, + 'text': message, + 'parse_mode': 'HTML' + } + response = requests.post(url, json=payload) + if response.status_code == 200: + logger.info("Telegram message sent successfully.") + else: + logger.error(f"Failed to send Telegram message: {response.text}") + except Exception as e: + logger.error(f"Error sending Telegram message: {e}") + +def check_webinars(redis_client): + """Check for active webinars and notify via Telegram.""" + + # Get PHPSESSID from Redis + phpsessid = redis_client.get('EDU_PHPSESSID') + if not phpsessid: + logger.warning("PHPSESSID not found in Redis. Waiting for session-keeper to provide it.") + return + + logger.info(f"Using PHPSESSID from Redis: {phpsessid}") + + with sync_playwright() as p: + try: + # Connect to remote Playwright server + browser = p.chromium.connect(PLAYWRIGHT_WS) + logger.info(f"Connected to Playwright server at {PLAYWRIGHT_WS}") + + context = browser.new_context( + user_agent=USER_AGENT, + viewport={'width': 1280, 'height': 720} + ) + + # Set PHPSESSID cookie + context.add_cookies([{ + 'name': 'PHPSESSID', + 'value': phpsessid, + 'domain': 'edu.edu.vn.ua', + 'path': '/' + }]) + + page = context.new_page() + + try: + logger.info(f"Navigating to {WEBINAR_URL}...") + page.goto(WEBINAR_URL, wait_until='domcontentloaded') + + # Wait for the table to load (dynamic content) + try: + page.wait_for_selector('#meetings table', timeout=10000) + except Exception: + logger.error("Timeout waiting for #meetings table. Page might not have loaded correctly.") + return + + content = page.content() + + if "Жодного онлайн уроку зараз" in content: + logger.info("Webinars check: No active webinars.") + else: + # Webinars found! + logger.info("!!! WEBINAR FOUND !!!") + + # Extract details + rows = page.locator('#meetings table tbody tr') + count = rows.count() + + webinar_details = [] + if count > 0: + for i in range(count): + text = rows.nth(i).inner_text() + # Skip the "no webinars" row + if "Жодного онлайн уроку зараз" not in text: + webinar_details.append(text.strip()) + + # Send Telegram notification (Russian) + if webinar_details: + message = "🎓 Найден вебинар!\n\n" + for detail in webinar_details: + message += f"📌 {detail}\n\n" + send_telegram_message(message) + else: + send_telegram_message("🎓 Найден вебинар!\n\nДетали не удалось извлечь.") + + except Exception as e: + logger.error(f"An error occurred during check: {e}") + finally: + browser.close() + + except Exception as e: + logger.error(f"Failed to connect to Playwright server: {e}") + +def main(): + logger.info("Starting Webinar Checker Bot") + + # Connect to Redis + try: + redis_client = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, decode_responses=True) + redis_client.ping() + logger.info(f"Connected to Redis at {REDIS_HOST}:{REDIS_PORT}") + except Exception as e: + logger.error(f"Failed to connect to Redis: {e}") + return + + # Send startup message (Russian) + send_telegram_message("🤖 Бот запущен\n\nМониторинг вебинаров активирован...") + + while True: + check_webinars(redis_client) + logger.info(f"Sleeping for {WEBINAR_CHECK_INTERVAL} seconds...") + time.sleep(WEBINAR_CHECK_INTERVAL) + +if __name__ == "__main__": + main()