feat: add admin commands to manage whitelist, extended webinar reporting
This commit is contained in:
@@ -98,11 +98,59 @@ async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
"/help - Show this message\n"
|
"/help - Show this message\n"
|
||||||
)
|
)
|
||||||
if update.effective_user.id == ADMIN_ID:
|
if update.effective_user.id == ADMIN_ID:
|
||||||
msg += "\n<b>Admin Commands:</b>\nUse the panel below to manage settings."
|
msg += (
|
||||||
|
"\n<b>Admin Commands:</b>\n"
|
||||||
|
"/adduser [user_id] - Add user to whitelist\n"
|
||||||
|
"/removeuser [user_id] - Remove user from whitelist\n"
|
||||||
|
"Or use the panel below to manage settings."
|
||||||
|
)
|
||||||
await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard())
|
await update.message.reply_text(msg, parse_mode='HTML', reply_markup=get_admin_keyboard())
|
||||||
else:
|
else:
|
||||||
await update.message.reply_text(msg, parse_mode='HTML')
|
await update.message.reply_text(msg, parse_mode='HTML')
|
||||||
|
|
||||||
|
async def add_user(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
"""Add user to whitelist (admin only)."""
|
||||||
|
if update.effective_user.id != ADMIN_ID:
|
||||||
|
await update.message.reply_text("⛔ Admin only!")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not context.args:
|
||||||
|
await update.message.reply_text("Usage: /adduser [user_id]")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
user_id = int(context.args[0])
|
||||||
|
redis_client.sadd(KEY_WHITELIST, str(user_id))
|
||||||
|
await update.message.reply_text(f"✅ User {user_id} added to whitelist")
|
||||||
|
logger.info(f"Admin added user {user_id} to whitelist")
|
||||||
|
except ValueError:
|
||||||
|
await update.message.reply_text("❌ Invalid user ID. Must be a number.")
|
||||||
|
|
||||||
|
async def remove_user(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
"""Remove user from whitelist (admin only)."""
|
||||||
|
if update.effective_user.id != ADMIN_ID:
|
||||||
|
await update.message.reply_text("⛔ Admin only!")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not context.args:
|
||||||
|
await update.message.reply_text("Usage: /removeuser [user_id]")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
user_id = int(context.args[0])
|
||||||
|
if str(user_id) == str(ADMIN_ID):
|
||||||
|
await update.message.reply_text("❌ Cannot remove admin from whitelist")
|
||||||
|
return
|
||||||
|
|
||||||
|
removed = redis_client.srem(KEY_WHITELIST, str(user_id))
|
||||||
|
if removed:
|
||||||
|
await update.message.reply_text(f"✅ User {user_id} removed from whitelist")
|
||||||
|
logger.info(f"Admin removed user {user_id} from whitelist")
|
||||||
|
else:
|
||||||
|
await update.message.reply_text(f"⚠️ User {user_id} was not in whitelist")
|
||||||
|
except ValueError:
|
||||||
|
await update.message.reply_text("❌ Invalid user ID. Must be a number.")
|
||||||
|
|
||||||
# --- Admin Callbacks ---
|
# --- Admin Callbacks ---
|
||||||
|
|
||||||
async def admin_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def admin_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
@@ -137,18 +185,29 @@ async def admin_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
|
|
||||||
elif data == "force_check":
|
elif data == "force_check":
|
||||||
await query.message.reply_text("🔄 Running immediate check...")
|
await query.message.reply_text("🔄 Running immediate check...")
|
||||||
await check_webinars_job(context)
|
result = await check_webinars_job(context)
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
await query.message.reply_text("❌ Check failed. See logs for details.")
|
||||||
|
elif result == 0:
|
||||||
|
await query.message.reply_text("✅ Check completed. No webinars found.")
|
||||||
|
else:
|
||||||
|
await query.message.reply_text(f"✅ Check completed. Found {result} webinar(s)!")
|
||||||
|
|
||||||
# --- Webinar Checking Job ---
|
# --- Webinar Checking Job ---
|
||||||
|
|
||||||
async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
|
async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
|
||||||
"""Background job to check for webinars using Async Playwright."""
|
"""Background job to check for webinars using Async Playwright.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: Number of webinars found, or None if check failed
|
||||||
|
"""
|
||||||
logger.info("Running webinar check...")
|
logger.info("Running webinar check...")
|
||||||
|
|
||||||
phpsessid = redis_client.get(KEY_PHPSESSID)
|
phpsessid = redis_client.get(KEY_PHPSESSID)
|
||||||
if not phpsessid:
|
if not phpsessid:
|
||||||
logger.warning("PHPSESSID missing. Skipping check.")
|
logger.warning("PHPSESSID missing. Skipping check.")
|
||||||
return
|
return None
|
||||||
|
|
||||||
webinar_details = []
|
webinar_details = []
|
||||||
|
|
||||||
@@ -199,6 +258,7 @@ async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error checking page: {e}")
|
logger.error(f"Error checking page: {e}")
|
||||||
|
return None
|
||||||
finally:
|
finally:
|
||||||
await page.close()
|
await page.close()
|
||||||
await context_browser.close()
|
await context_browser.close()
|
||||||
@@ -208,7 +268,7 @@ async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Playwright error: {e}")
|
logger.error(f"Playwright error: {e}")
|
||||||
return
|
return None
|
||||||
|
|
||||||
# Notify subscribers if webinars found
|
# Notify subscribers if webinars found
|
||||||
if webinar_details:
|
if webinar_details:
|
||||||
@@ -221,6 +281,8 @@ async def check_webinars_job(context: ContextTypes.DEFAULT_TYPE):
|
|||||||
logger.info(f"Notification sent to {sub_id}")
|
logger.info(f"Notification sent to {sub_id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to send to {sub_id}: {e}")
|
logger.error(f"Failed to send to {sub_id}: {e}")
|
||||||
|
|
||||||
|
return len(webinar_details)
|
||||||
|
|
||||||
# --- Main ---
|
# --- Main ---
|
||||||
|
|
||||||
@@ -242,6 +304,8 @@ def main():
|
|||||||
# Handlers
|
# Handlers
|
||||||
app.add_handler(CommandHandler("start", start))
|
app.add_handler(CommandHandler("start", start))
|
||||||
app.add_handler(CommandHandler("help", help_command))
|
app.add_handler(CommandHandler("help", help_command))
|
||||||
|
app.add_handler(CommandHandler("adduser", add_user))
|
||||||
|
app.add_handler(CommandHandler("removeuser", remove_user))
|
||||||
app.add_handler(CallbackQueryHandler(admin_callback))
|
app.add_handler(CallbackQueryHandler(admin_callback))
|
||||||
|
|
||||||
# Job Queue
|
# Job Queue
|
||||||
|
|||||||
Reference in New Issue
Block a user