Search code examples
telegram-botaiogram

the post sent by the bot telegram is not deleted for all users


I have a function which allows to send a message to all users who clicked the start button.

@dp.message_handler(commands=['Yes'], state=Post.send_post)
async def process_name(message: Message, state: FSMContext):
    for admin in admins:
        if message.from_user.id == admin:
            async with state.proxy() as data:
                data['send_post'] = message.text
            conn = sqlite3.connect('data.db')
            cur = conn.cursor()
            cur.execute(f'SELECT * FROM users')
            result = cur.fetchall()
            await state.finish()
            print(result)
            try:
                for z in range(len(result)):
                    print(result[z][0])
                    await dp.bot.send_photo(chat_id=result[z][0], photo=data['photo'], caption=data['CAPTHION'], reply_markup=kb)
                    print(z)
                    test = message.message_id + 1
                    await dp.bot.send_message(chat_id=result[z][0], text=f'id поста {test}')
            except BotBlocked:
                print('Пользователь заблокировал бота')
            except ChatNotFound:
                print('Пользователь не запускал бота')

Also, there is a function that allows you to delete messages by id. The administrator enters the deleted command, after which the bot asks to enter its id. When the Administrator enters an id, the bot deletes messages through a loop, iterating over the id. But for some reason, it only deletes a post from one user, then it throws an error aiogram.utils.exceptions.MessageToDeleteNotFound: Message to delete not found Please help me I can't figure out why

@dp.message_handler(commands=['deleted'], state=None)
async def send_id(message: Message):
    for admin in admins:
         if message.from_user.id == admin:
                await Post.Sen_id.set()
                await dp.bot.send_message(chat_id=admin, text='Введите ID поста, который нужно удалить.')
    await Post.next()


@dp.message_handler(state=Post.del_mess)
async def deleted_post(message: Message, state: FSMContext):
    for admin in admins:
        if message.from_user.id == admin:
            async with state.proxy() as data:
                data['sen_id'] = message.text
        try:
            conn = sqlite3.connect('data.db')
            cur = conn.cursor()
            cur.execute(f'SELECT * FROM users')
            result = cur.fetchall()
            #message_ids = int(data['sen_id'])
            for z in range(len(result)):
                print('/////////////deleted/////////////')
                print(result)
                print(z)
                await dp.bot.delete_message(chat_id=result[z][0], message_id=data['sen_id'])
                print('Сообщение удалено')
            #chat_id = message.chat.id

            #await dp.bot.delete_message(message.chat.id, message_ids)
            await dp.bot.send_message(chat_id=admin, text='пост удален')
        except BotBlocked:
            print('Пользователь заблокировал бота')
        except ChatNotFound:
            print('Пользователь не запускал бота')

Solution

  • This is a code that does what you wish for - deleting message with given message_id in every chat where that message exist. Later I'll explain why this is actually not a good solution.

    The problem is with the placing of the try-except block. In your code, if deleting the message fails for a single user, for all users that are past him in the database the deletion will not be even attempted. Solution would be to place the try-except block in the for loop.

    ...
    if message.from_user.id == admin:
        async with state.proxy() as data:
            data['sen_id'] = message.text
    
    conn = sqlite3.connect('data.db')
    cur = conn.cursor()
    cur.execute(f'SELECT * FROM users')
    result = cur.fetchall()
    #message_ids = int(data['sen_id'])
    for z in range(len(result)):
        try:
            print('/////////////deleted/////////////')
            print(result)
            print(z)
            await dp.bot.delete_message(chat_id=result[z][0], message_id=data['sen_id'])
            print('Сообщение удалено')
            #chat_id = message.chat.id
            #await dp.bot.delete_message(message.chat.id, message_ids)
            await dp.bot.send_message(chat_id=admin, text='пост удален')
        except BotBlocked:
            print('Пользователь заблокировал бота')
        except ChatNotFound:
            print('Пользователь не запускал бота')
        except Exception as e:
            print(e)
    ...
    

    However, after testing this approach, I believe you will realise that there is a problem: if you send a "post" to multiple users, it may have a different message_id for different users! So you would have to use a different approach.