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()