не работает команда /report python teleBot

команда /report должна работать так: пользевотель видит сообщение нарушающее правила и отвичяет командой,в гупу администрации приходит сообщение о репорте если о нарушении сообщают 5 человек от юзера мутят на день вот код:

# Хранение данных о репортах
report_data = defaultdict(lambda: {'message_id': None, 'responses': set()})

@bot.message_handler(commands=['report'])
def handle_report(message):
    chat_id = message.chat.id
    report_data[chat_id]['message_id'] = message.message_id
    report_data[chat_id]['responses'].clear()
    bot.reply_to(message, "Пожалуйста, ответьте на сообщение, нарушающее правила, чтобы сообщить о нарушении.")

# Обработка ответа на сообщение с /report
@bot.message_handler(func=lambda msg: msg.reply_to_message and msg.reply_to_message.message_id in [data['message_id'] for data in report_data.values()])
def handle_response(message):
    chat_id = message.chat.id
    report = report_data[chat_id]

    # Добавляем ID пользователя
    report['responses'].add(message.from_user.id)
    bot.send_message(admin_grops,f"послали репорт на >> tg://user?id={message.from_user.id}, @{message.from_user.username} " + message.text)
    print(f"Пользователь @{message.from_user.username} сообщил о нарушении.")

    # Проверяем, достаточно ли ответов для бана
    if len(report['responses']) >= 5:
        user_to_ban = message.reply_to_message.from_user.id
        bot.kick_chat_member(chat_id, user_to_ban, until_date=int(time.time()) + 86400)
        bot.send_message(admin_grops, f"Пользователь {user_to_ban} получил бан на 24 часа за нарушение.")
        
# Логируем бан
        with open('ban_list.txt', 'a', encoding='utf-8') as f:
            log_entry = f"{datetime.now()} - Пользователь {user_to_ban} получил бан\n"
            f.write(log_entry)

        # Удаляем данные о репорте
        del report_data[chat_id]

но по факту код работает так: юзер кидает репорт ( как я описывал ранее) но бот сообщает что сообщение должно отвечать на другое не смотря на то что все правильно. Но репорт не проходит но если на команду /report ответит другой пользователь то репорт пройдет по этому самому пользователю. Прошу помочь


Ответы (2 шт):

Автор решения: Medvedev

По порядку, во первых:

В Python интерпретатор читает код сверху вниз, строчка за строчкой. То есть в вашем случае, когда пользователь отправляет команду /report у вас всегда будет выполняться функция handle_report(message), просто потому, что эта функция прочитается первой и сработает обработчик команды /report.

Во вторых: @bot.message_handler(func=lambda msg: msg.reply_to_message and msg.reply_to_message.message_id in [data['message_id'] for data in report_data.values()]) - это не читабельный длинный костыль, который, судя по расположению в коде предоставленном в вопросе, даже и не работает, тк обработчик не срабатывает. Да и вам не нужно придумывать дополнительные обработчики с лямбдами, всё гораздо проще: у вас обработчик команды /report, внутри него и прописывайте всю необходимую для вас логику.

Например:

def handle_response(message):
    ... ...


@bot.message_handler(commands=['report'])
def handle_report(message):
    # как то так
    if message.reply_to_message:
        handle_response(message)
    else:
        print(f'{report_data=}')
        chat_id = message.chat.id
        report_data[chat_id]['message_id'] = message.message_id
        report_data[chat_id]['responses']
        bot.reply_to(message, "Пожалуйста, ответьте ... .")

И третий момент:

Здесь вы передаете ID пользователя, который отправляет жалобу, а не на кого отправляют жалобу.

bot.send_message(admin_grops,f"послали репорт на >> tg://user?id={message.from_user.id}, @{message.from_user.username} " + message.text)
   print(f"Пользователь @{message.from_user.username} сообщил о нарушении.")

Что бы получить ID пользователя, на чье сообщение ответили, необходимо использовать message.reply_to_message.from_user.id

И к слову: возможно это как то технически и оправданно, но по ощущениям кажется, что report_data = defaultdict(lambda: {'message_id': None, 'responses': set()}) можно заменить обычным словарем

→ Ссылка
Автор решения: Hit

я решил проблему таким кодом

# Хранение данных о репортах
report_data =  {}
# Обработка ответа на сообщение с /report
@bot.message_handler(commands=['report','репорт'])
def handle_report(message):
    if message.reply_to_message:
        chat_id = message.chat.id#инециалезацыя всякой хрени
        reported_message_text = message.reply_to_message.text

        if chat_id not in report_data:#проверка на существования пометки chat_id
            report_data[chat_id] = {'responses': set()}
            
        report = report_data[chat_id]
        #добавляем id балбеса or нарушителя в тетрадь смерти Сталина report
        report['responses'].add(message.reply_to_message.from_user.id) 
        ban_ded=message.reply_to_message.from_user.id
        report_chat=message.chat.id
         
        bot.send_message(admin_grops,f"послали репорт на >> tg://user?id={message.reply_to_message.from_user.id}, @{message.reply_to_message.from_user.username} | сообщение>>" + reported_message_text)
        logger.debug(f"послали репорт на >>  @{message.reply_to_message.from_user.username} | https://t.me/c/{report_chat}/{message.reply_to_message.message_id} сообщение>> " + reported_message_text)
        logger.info(f"Пользователь @{message.from_user.username} сообщил о нарушении.")
        
        # Проверяем, достаточно ли ответов для бана
        if len(report['responses']) >= 5:
#           bot.kick_chat_member(chat_id, user_to_ban, until_date=int(time.time()) + 86400)
            bot.send_message(admin_grops,f"грубый нарушитель ! >> tg://user?id={ban_ded}")
 

            #bot.send_message(admin_grops, f"Пользователь {message.reply_to_message.from_user.username} получил бан на 24 часа за нарушение.")
            #logger.debug(f"Пользователь {message.reply_to_message.from_user.username} получил бан на 24 часа за нарушение.")        

        # Удаляем данные о репорте
        del report_data[chat_id]
    else:
       #print(f'{report_data=}')
       #chat_id = message.chat.id
       #report_data[chat_id]['message_id'] = message.message_id
       #report_data[chat_id]['responses']  =report_data[chat_id]['responses'] + 1   
        bot.reply_to(message, "Пожалуйста, ответьте командой на сообщение, нарушающее правила, чтобы сообщить о нарушении.")
→ Ссылка