Telegram群聊Bot异常:本该仅回复@提及消息却全量响应求助
Telegram Bot 群聊消息响应逻辑修复
问题描述
开发的Telegram Bot预期实现:私聊场景下回复所有消息,群聊/超级群场景下仅回复@提及Bot用户名的消息。但目前Bot在群聊中会回复所有消息,无法实现预期逻辑。
问题根源
- 第一个消息处理器
@dp.message_handler()未设置任何过滤条件,会匹配所有类型的消息(包括群聊消息),导致群聊中的所有消息都被该处理器优先响应,后续的群聊专用处理器无法触发。 - 群聊处理器中错误使用
openai.Completion.create调用gpt-3.5-turbo模型,该模型属于ChatCompletion接口,且结果提取方式错误。 - 两个处理器逻辑高度重复,冗余代码增加维护成本。
修复方案
- 给私聊专用处理器添加
chat_type=["private"]过滤条件,确保仅处理私聊消息。 - 调整OpenAI调用方式,群聊处理器中改用
openai.ChatCompletion.create,并修正结果提取逻辑。 - 提取公共逻辑为独立函数,复用代码。
修正后的完整代码
import openai from aiogram.dispatcher import Dispatcher from aiogram.types import Message, types from database import dbase openai.api_key = '' max_telegram_post_length = 4095 def get_gpt_response(user_id: int, user_query: str) -> str: """复用的GPT请求逻辑""" system_role = dbase.get_system_role(user_id) all_user_gpt_answers = dbase.get_gpt_answers(user_id) query = [ {"role": "system", "content": system_role}, {"role": "user", "content": user_query} ] if all_user_gpt_answers: for answer in all_user_gpt_answers: query.append({"role": "assistant", "content": answer}) response = openai.ChatCompletion.create( model='gpt-3.5-turbo-0301', messages=query, temperature=0.9 ) return response['choices'][0]['message'].content async def send_split_message(message: Message, text: str): """超长消息拆分发送逻辑""" if len(text) > max_telegram_post_length: for i in range(0, len(text), max_telegram_post_length): await message.answer(text[i:i + max_telegram_post_length]) else: await message.answer(text) def register_ooo_handler(dp: Dispatcher): # 仅处理私聊消息 @dp.message_handler(chat_type=["private"]) async def handle_private_message(message: Message): ans = get_gpt_response(message.from_user.id, message.text) await send_split_message(message, ans) dbase.add_gpt_answer(message.from_user.id, ans) # 处理群聊/超级群消息,仅响应@提及Bot的消息 @dp.message_handler(content_types=["text"], chat_type=["group", "supergroup"]) async def handle_group_message(message: types.Message): bot_info = await message.bot.get_me() # 检查消息是否@提及Bot,且消息来自真实用户 if f'@{bot_info.username}' in message.text and message.from_user is not None: # 提取去掉@提及的纯问题文本(可选优化) clean_query = message.text.replace(f'@{bot_info.username}', '').strip() ans = get_gpt_response(message.from_user.id, clean_query if clean_query else message.text) await send_split_message(message, ans) dbase.add_gpt_answer(message.from_user.id, ans)
额外优化说明
- 新增了
get_gpt_response和send_split_message两个公共函数,将重复逻辑抽离,提升代码可维护性。 - 可选优化:在群聊处理中去掉消息中的@Bot用户名,让GPT处理更纯粹的用户问题(已在代码中实现)。
内容的提问来源于stack exchange,提问作者FoorA
相关产品推荐
相关产品推荐

