Search code examples
pythontelegramtelegram-botopenai-apiaiogram

For some reason, my bot replies to all messages in the group, although it should only respond to messages mentioning it


He must reply to all messages in private, but in the group he must reply to messages in which he is mentioned and ignore all others. But for some reason it doesn't work and he still replies to all messages. Here is my code:

import openai
import json
from datetime import datetime, timedelta
from aiogram.dispatcher import Dispatcher
from aiogram.types import Message
from database import dbase
from aiogram import types


openai.api_key = ''
max_telegram_post_length = 4095



def register_ooo_handler(dp: Dispatcher):
    @dp.message_handler()
    async def ooo_ooo(message: Message):

        system_role = dbase.get_system_role(message.from_user.id)
        all_user_gpt_answers = dbase.get_gpt_answers(message.from_user.id)

        query = [
            {
                "role": "system",
                "content": f"{system_role}"
            },

            {
                "role": "user",
                "content": f"{message.text}"
            },

        ]

        if all_user_gpt_answers:
            for answer in all_user_gpt_answers:
                query.append({"role": "assistant", "content": f"{answer}"})

        responce = openai.ChatCompletion.create(
            model='gpt-3.5-turbo-0301',
            messages=query,
            temperature=0.9
        )

        ans = responce['choices'][0]['message'].content

        if len(ans) > max_telegram_post_length:
            for i in range(0, len(ans), max_telegram_post_length):
                text = ans[i:i + max_telegram_post_length]
                await message.answer(text)

        else:
            await message.answer(ans)

        dbase.add_gpt_answer(message.from_user.id, ans)


    @dp.message_handler(content_types=["text"], chat_type=["group", "supergroup"])
    async def send_group_message(message: types.Message):
        bot_info = await message.bot.get_me()
        if f'@{bot_info.username}' in message.text:
            # This handler only responds to messages in the group that mention the bot's name
            if message.from_user is not None:  # Checking that the message is from the user and not from another bot or system message
                system_role = dbase.get_system_role(message.from_user.id)
                all_user_gpt_answers = dbase.get_gpt_answers(message.from_user.id)

                query = [
                    {
                        "role": "system",
                        "content": f"{system_role}"
                    },
                    {
                        "role": "user",
                        "content": f"{message.text}"
                    }
                ]

                if all_user_gpt_answers:
                    for answer in all_user_gpt_answers:
                        query.append({"role": "assistant", "content": f"{answer}"})

                    responce = openai.Completion.create(
                        model='gpt-3.5-turbo-0301',
                        messages=query,
                        temperature=0.9
                    )
                    ans = responce['choices'][0]['text']

                    if len(ans) > max_telegram_post_length:
                        for i in range(0, len(ans), max_telegram_post_length):
                            text = ans[i:i + max_telegram_post_length]
                            await message.answer(text)

                    else:
                        await message.answer(ans)

                    dbase.add_gpt_answer(message.from_user.id, ans)

I tried to change the code in every possible way, but nothing worked out for me and the bot by default replies to all messages in the group.


Solution

  • If you enable privacy mode, the bot will only receive messages are ment for him. Check the docs for more info about privacy mode.


    Regarding the Aiogram way:

    Your message handler does not limit the handling of only messages that are send to your bot:

    @dp.message_handler(content_types=["text"], chat_type=["group", "supergroup"])
    

    You could add a filter to only reply on the message's you'd like.

    Doesn't seem to be an out-of-the-box filter for your needs, so you could create a custom one.


    Most straight forward way is to check if entities key is set on the message. If there is a type mention you know it's send to the bot directly:

    > print(message)
    < {"message_id": 715, ... "entities": [{"type": "mention", "offset": 0, "length": 15}]}
    
    @dp.message_handler(
        lambda message: 
               message.entities and any(entitie.type == 'mention' for entitie in message.entities
    )