You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用python-telegram-bot开发的Telegram机器人在群组中误响应所有消息(仅需被@时响应)的问题求助

使用python-telegram-bot开发的Telegram机器人在群组中误响应所有消息(仅需被@时响应)的问题求助

你好,我仔细看了你的代码和问题描述,咱们来一步步揪出问题所在~

首先你提到代码里加了判断,但机器人还是会响应所有群组消息,最有可能的核心问题是你漏了判断超级群组(supergroup)的类型!

Telegram的群组分为普通群组(group)和超级群组(supergroup),而你的代码里只判断了message_type == 'group',如果你的实际聊天是超级群组,那这个判断就不成立,代码会直接走到私聊的逻辑分支,对所有消息生成响应并回复——这就是为什么机器人会乱响应的原因!

快速修复方案

先把群组类型的判断改成包含两种群组:

if message_type in ['group', 'supergroup']:
    # 原有的@检测逻辑
else:
    # 私聊响应逻辑

改完之后,超级群组里的消息也会进入正确的判断分支,没@机器人的话就会执行return,不会回复。

更可靠的@检测优化(推荐)

另外,用字符串包含BOT_USERNAME in text的方式其实不太严谨——比如用户文本里刚好出现和机器人用户名类似的字符串,或者大小写不一致时,都会导致判断出错。推荐用Telegram的消息实体来精准检测是否真的@了机器人:

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    message_type = update.message.chat.type
    text = update.message.text

    if message_type in ['group', 'supergroup']:
        is_mentioned = False
        cleaned_text = text
        # 遍历消息中的实体,找@机器人的标记
        if update.message.entities:
            for entity in update.message.entities:
                if entity.type == 'mention':
                    # 提取被@的用户名(去掉前面的@)
                    mentioned_name = text[entity.offset+1 : entity.offset+entity.length]
                    # 忽略大小写比较,避免大小写不匹配问题
                    if mentioned_name.lower() == BOT_USERNAME.strip('@').lower():
                        is_mentioned = True
                        # 去掉消息里@机器人的部分,只保留有效内容
                        cleaned_text = text[:entity.offset] + text[entity.offset+entity.length:]
                        cleaned_text = cleaned_text.strip()
                        break
        # 没被@就直接返回,不处理
        if not is_mentioned:
            return
        response = handle_responses(cleaned_text)
    else:
        response = handle_responses(text)

    await update.message.reply_text(response)

进阶优化:在Handler层面过滤消息

如果想让代码更高效,可以直接在添加Handler的时候就过滤掉不需要的消息,这样不符合条件的消息根本不会进入handle_message函数:

# 自定义过滤器:私聊 或者 群组中@了机器人
def should_handle(update: Update) -> bool:
    chat_type = update.message.chat.type
    if chat_type == 'private':
        return True
    if chat_type in ['group', 'supergroup']:
        if update.message.entities:
            for entity in update.message.entities:
                if entity.type == 'mention':
                    mentioned_name = update.message.text[entity.offset+1 : entity.offset+entity.length]
                    if mentioned_name.lower() == BOT_USERNAME.strip('@').lower():
                        return True
        return False
    return False

# 添加Handler时使用这个过滤器
app.add_handler(MessageHandler(filters.TEXT & filters.create(should_handle), handle_message))

调试小技巧

你可以在handle_message函数开头加一行打印,确认当前聊天的类型:

print(f"Chat type: {message_type}, Message text: {text}")

这样就能快速确认你的群组到底是group还是supergroup,帮你定位问题。

备注:内容来源于stack exchange,提问作者Hset Yiu Paing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 12:07:59