feat: basic webinar checker bot
This commit is contained in:
@@ -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"]
|
||||
@@ -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 = "🎓 <b>Найден вебинар!</b>\n\n"
|
||||
for detail in webinar_details:
|
||||
message += f"📌 {detail}\n\n"
|
||||
send_telegram_message(message)
|
||||
else:
|
||||
send_telegram_message("🎓 <b>Найден вебинар!</b>\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("🤖 <b>Бот запущен</b>\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()
|
||||
Reference in New Issue
Block a user