diff --git a/apps/telegram-bot/bot.py b/apps/telegram-bot/bot.py index c72df9c..c4ea389 100644 --- a/apps/telegram-bot/bot.py +++ b/apps/telegram-bot/bot.py @@ -8,6 +8,7 @@ from telegram.ext import Application, CommandHandler, MessageHandler, filters from commands import ( cmd_add, + cmd_admin, cmd_bounty, cmd_delete, cmd_edit, @@ -41,6 +42,7 @@ def build_app() -> Application: app.add_handler(CommandHandler("delete", cmd_delete)) app.add_handler(CommandHandler("track", cmd_track)) app.add_handler(CommandHandler("untrack", cmd_untrack)) + app.add_handler(CommandHandler("admin", cmd_admin)) app.add_handler(MessageHandler(filters.COMMAND, cmd_help)) @@ -56,6 +58,7 @@ async def post_init(app: Application) -> None: ("edit", "Edit a bounty"), ("track", "Track a bounty"), ("untrack", "Stop tracking"), + ("admin", "Admin management"), ("help", "Show help"), ] ) diff --git a/apps/telegram-bot/commands.py b/apps/telegram-bot/commands.py index b0ae05e..b245c11 100644 --- a/apps/telegram-bot/commands.py +++ b/apps/telegram-bot/commands.py @@ -291,6 +291,101 @@ async def cmd_untrack(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: await update.message.reply_text("Not tracking bounty #{bounty_id}.") +async def cmd_admin(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: + args = extract_args(update.message.text) + if not args: + await update.message.reply_text( + "Usage: /admin [@username]\n" + "/admin list — list admins\n" + "/admin add @username — add admin\n" + "/admin remove @username — remove admin" + ) + return + + subcommand = args[0].lower() + username = args[1] if len(args) > 1 else None + + requesting_user_id = get_user_id(update) + room_id = get_room_id(update) + + if subcommand == "list": + admins = BOUNTY_SERVICE.list_admins(room_id) + if not admins: + await update.message.reply_text("No admins in this room.") + return + admin_mentions = " ".join(f"admin_id:{uid}" for uid in admins) + await update.message.reply_text(f"Admins: {admin_mentions}") + return + + if subcommand == "remove": + if not username: + await update.message.reply_text("Usage: /admin remove @username") + return + + if not username.startswith("@"): + await update.message.reply_text( + f"⛔ {username} is not a valid username (must start with @)." + ) + return + + target_username = username[1:] + try: + chat = await ctx.bot.get_chat(target_username) + target_user_id = chat.id + except Exception: + await update.message.reply_text( + f"⛔ Could not find user @{target_username}." + ) + return + + try: + BOUNTY_SERVICE.remove_admin(room_id, target_user_id, requesting_user_id) + await update.message.reply_text( + f"✅ @{target_username} is no longer an admin." + ) + except PermissionError as e: + await update.message.reply_text(f"⛔ {e}") + except ValueError: + await update.message.reply_text(f"⛔ @{target_username} is not an admin.") + return + + if subcommand == "add": + if not username: + await update.message.reply_text("Usage: /admin add @username") + return + + if not username.startswith("@"): + await update.message.reply_text( + f"⛔ {username} is not a valid username (must start with @)." + ) + return + + target_username = username[1:] + try: + chat = await ctx.bot.get_chat(target_username) + target_user_id = chat.id + except Exception: + await update.message.reply_text( + f"⛔ Could not find user @{target_username}." + ) + return + + try: + BOUNTY_SERVICE.add_admin(room_id, target_user_id, requesting_user_id) + await update.message.reply_text(f"✅ @{target_username} is now an admin.") + except PermissionError as e: + await update.message.reply_text(f"⛔ {e}") + except ValueError: + await update.message.reply_text( + f"⛔ @{target_username} is already an admin." + ) + return + + await update.message.reply_text( + "Unknown subcommand. Use: /admin [@username]" + ) + + async def cmd_start(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: if is_group(update): await update.message.reply_text(