feat: support reply-based admin actions
This commit is contained in:
+47
-22
@@ -38,6 +38,25 @@ async def mark_reply_message_deleted(reply_msg, reason: str = "command_ban_reply
|
||||
await rec.save()
|
||||
|
||||
|
||||
async def delete_replied_message(update: Update, reason: str) -> None:
|
||||
"""删除管理命令引用的目标消息,并同步标记本地消息记录。"""
|
||||
reply_msg = update.message.reply_to_message if update.message else None
|
||||
if not reply_msg:
|
||||
return
|
||||
try:
|
||||
await reply_msg.delete()
|
||||
await mark_reply_message_deleted(reply_msg, reason=reason)
|
||||
except Exception as e:
|
||||
logger.debug(f"删除引用消息失败: {type(e).__name__}: {e}")
|
||||
|
||||
|
||||
async def delete_command_message(update: Update) -> None:
|
||||
"""尽量删除管理员命令消息,失败不影响主流程。"""
|
||||
try:
|
||||
await update.message.delete()
|
||||
except Exception as e:
|
||||
logger.debug(f"删除命令消息失败: {type(e).__name__}: {e}")
|
||||
|
||||
|
||||
async def cmd_stats(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""今日统计"""
|
||||
@@ -80,19 +99,12 @@ async def cmd_ban(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
method="reply_command" if update.message.reply_to_message else "command",
|
||||
)
|
||||
if update.message.reply_to_message:
|
||||
try:
|
||||
await update.message.reply_to_message.delete()
|
||||
await mark_reply_message_deleted(update.message.reply_to_message)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
await update.message.delete()
|
||||
except Exception:
|
||||
pass
|
||||
await delete_replied_message(update, reason="command_ban_reply")
|
||||
await delete_command_message(update)
|
||||
reply = await update.effective_chat.send_message(f"🔨 已封禁 {target} ({user_id}) {config.BAN_DURATION_MINUTES} 分钟")
|
||||
except Exception as e:
|
||||
logger.error(f"手动封禁失败: {type(e).__name__}: {e}")
|
||||
reply = await update.message.reply_text(f"❌ 封禁失败: {e}")
|
||||
reply = await update.message.reply_text("❌ 封禁失败,请检查 Bot 权限或目标用户状态")
|
||||
|
||||
asyncio.create_task(auto_delete(reply))
|
||||
|
||||
@@ -115,7 +127,7 @@ async def cmd_unban(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
reply = await update.message.reply_text(f"🔓 已解封用户 {target} ({user_id})")
|
||||
except Exception as e:
|
||||
logger.error(f"手动解封失败: {type(e).__name__}: {e}")
|
||||
reply = await update.message.reply_text(f"❌ 解封失败: {e}")
|
||||
reply = await update.message.reply_text("❌ 解封失败,请检查 Bot 权限或目标用户状态")
|
||||
|
||||
asyncio.create_task(auto_delete(reply))
|
||||
|
||||
@@ -137,14 +149,22 @@ async def cmd_warn(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
else:
|
||||
reason = " ".join(context.args[1:]) if len(context.args) > 1 else "未说明原因"
|
||||
|
||||
warn_count = await Warning.filter(user_id=user_id).count() + 1
|
||||
await Warning.create(user_id=user_id, username=target, reason=reason, operator_id=update.effective_user.id)
|
||||
await Action.create(action="WARN", user_id=user_id, username=target, operator_id=update.effective_user.id, details={"reason": reason})
|
||||
try:
|
||||
warn_count = await Warning.filter(user_id=user_id).count() + 1
|
||||
await Warning.create(user_id=user_id, username=target, reason=reason, operator_id=update.effective_user.id)
|
||||
await Action.create(action="WARN", user_id=user_id, username=target, operator_id=update.effective_user.id, details={"reason": reason})
|
||||
if update.message.reply_to_message:
|
||||
await delete_replied_message(update, reason="command_warn_reply")
|
||||
await delete_command_message(update)
|
||||
reply = await update.effective_chat.send_message(f"⚠️ 已警告 {target} ({user_id})\n原因: {reason}\n累计警告: {warn_count}")
|
||||
else:
|
||||
reply = await update.message.reply_text(f"⚠️ 已警告 {target} ({user_id})\n原因: {reason}\n累计警告: {warn_count}")
|
||||
except Exception as e:
|
||||
logger.error(f"警告失败: {type(e).__name__}: {e}")
|
||||
reply = await update.message.reply_text("❌ 警告失败,请检查 Bot 权限或数据库状态")
|
||||
|
||||
reply = await update.message.reply_text(f"⚠️ 已警告 {target} ({user_id})\n原因: {reason}\n累计警告: {warn_count}")
|
||||
asyncio.create_task(auto_delete(reply))
|
||||
|
||||
|
||||
async def cmd_mute(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""禁言用户"""
|
||||
if not await require_admin(update, context):
|
||||
@@ -171,10 +191,15 @@ async def cmd_mute(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
until_date=until_date,
|
||||
)
|
||||
await Action.create(action="MUTE", user_id=user_id, username=target, operator_id=update.effective_user.id, details={"minutes": minutes})
|
||||
reply = await update.message.reply_text(f"🔇 已禁言 {target} ({user_id}) {minutes} 分钟")
|
||||
if update.message.reply_to_message:
|
||||
await delete_replied_message(update, reason="command_mute_reply")
|
||||
await delete_command_message(update)
|
||||
reply = await update.effective_chat.send_message(f"🔇 已禁言 {target} ({user_id}) {minutes} 分钟")
|
||||
else:
|
||||
reply = await update.message.reply_text(f"🔇 已禁言 {target} ({user_id}) {minutes} 分钟")
|
||||
except Exception as e:
|
||||
logger.error(f"禁言失败: {type(e).__name__}: {e}")
|
||||
reply = await update.message.reply_text(f"❌ 禁言失败: {e}")
|
||||
reply = await update.message.reply_text("❌ 禁言失败,请检查 Bot 权限或目标用户状态")
|
||||
|
||||
asyncio.create_task(auto_delete(reply))
|
||||
|
||||
@@ -228,10 +253,10 @@ async def cmd_help(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"🔗 /bind - 绑定账号\n"
|
||||
"🌙 /night on/off - 夜间模式(管理员)\n\n"
|
||||
"管理命令(管理员):\n"
|
||||
"🔨 回复消息 /ban 或 /ban 用户ID\n"
|
||||
"🔓 /unban 用户ID\n"
|
||||
"⚠️ 回复消息 /warn [原因]\n"
|
||||
"🔇 回复消息 /mute [分钟]\n"
|
||||
"🔨 /ban 用户ID/@历史用户名,或回复消息 /ban(删除原消息并封禁)\n"
|
||||
"🔇 /mute 用户ID/@历史用户名 [分钟],或回复消息 /mute [分钟](禁言并删除原消息)\n"
|
||||
"⚠️ /warn 用户ID/@历史用户名 [原因],或回复消息 /warn [原因](警告并删除原消息)\n"
|
||||
"🔓 /unban 用户ID/@历史用户名\n"
|
||||
"🧹 回复消息 /purge 数量\n"
|
||||
)
|
||||
reply = await update.message.reply_text(text)
|
||||
|
||||
Reference in New Issue
Block a user