开发Telegram防广告Bot:区分提及的是用户还是群组
解决方案
核心问题是正则表达式无法区分用户账号与群组账号,必须通过Telegram API查询被提及账号的实际类型来实现需求。以下是修改后的完整代码:
from telegram import Update from telegram.ext import Updater, CallbackContext, MessageHandler, Filters import re # 匹配消息中所有@开头的合法账号(提取账号名称部分,去掉@) username_pattern = re.compile(r'@([A-Za-z][A-Za-z0-9_]{4,30})', re.IGNORECASE) def message_handler(update: Update, context: CallbackContext): # 豁免管理员、创建者和机器人的消息,避免误操作 chat_member = context.bot.get_chat_member(update.effective_chat.id, update.message.from_user.id) if chat_member.status in ['creator', 'administrator'] or chat_member.user.is_bot: return message_text = update.message.text if not message_text: return # 提取消息中所有被@提及的账号名称 mentioned_accounts = username_pattern.findall(message_text) for account in mentioned_accounts: try: # 查询该账号对应的Chat信息 chat = context.bot.get_chat(account) # 若为群组/超级群组/频道类型,则处理违规消息 if chat.type in ['group', 'supergroup', 'channel']: update.message.delete() # 发送提示消息(可选,可根据需求调整) context.bot.send_message( chat_id=update.effective_chat.id, text=f"@{account} 是群组/频道账号,此类提及已被删除。" ) break # 检测到一个违规提及即处理,避免重复操作 except Exception: # 处理账号不存在、权限不足等异常,跳过不影响流程 continue def main(): updater = Updater(token="你的机器人Token", use_context=True) dispatcher = updater.dispatcher # 注册消息处理器,排除命令消息(如/start) dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, message_handler)) updater.start_polling() updater.idle() if __name__ == "__main__": main()
关键细节说明
- 账号提取逻辑:使用
findall提取消息中所有符合格式的@账号,而非匹配整个消息,覆盖多提及场景 - 类型判断核心:通过
get_chat接口获取账号对应的Chat对象,通过chat.type字段区分:- 用户账号对应
private类型 - 群组/频道对应
group/supergroup/channel类型
- 用户账号对应
- 权限控制:恢复你注释的管理员豁免逻辑,避免误删管理员或机器人发送的消息
- 异常处理:捕获查询账号时的异常(如账号不存在、机器人无权限),保证程序稳定运行
必要前提
确保你的机器人已被授予删除消息和读取聊天信息的权限,否则无法正常执行操作。
内容的提问来源于stack exchange,提问作者Daisha
相关产品推荐
相关产品推荐

