• Как отправлять сообщения по расписанию с aiogram3?

    @spencer_spfl Автор вопроса
    Vindicar, Решил проблему разделив задачи на два процесса, спасибо за потраченное время.
    Написано
  • Как отправлять сообщения по расписанию с aiogram3?

    @spencer_spfl Автор вопроса
    Vindicar, + теперь сам бот не функционирует
    Написано
  • Как отправлять сообщения по расписанию с aiogram3?

    @spencer_spfl Автор вопроса
    Vindicar, Проблема исчезла, но появилась другая - не постит ничего в канал. Спасибо, что помогаете разобраться.
    Написано
  • Как отправлять сообщения по расписанию с aiogram3?

    @spencer_spfl Автор вопроса
    spencer_spfl,
    #database
    import sqlite3
    from aiogram import types
    
    
    async def connect_db():
        global db, cur
    
        db = sqlite3.connect('tabakerka.db')
        cur = db.cursor()
    
        cur.execute('CREATE TABLE IF NOT EXISTS posts(post_id INTEGER PRIMARY KEY, user_id INTEGER, text TEXT, '
                    'media_path TEXT, inline_urls TEXT, status INTEGER)')
        db.commit()
    
    
    async def post_to_db(message, text, media, inline_urls):
        with open('text/photo_num.txt', 'r') as file_pic:
            photo_num = int(file_pic.read()) - 1
        cur.execute('INSERT INTO posts VALUES(?, ?, ?, ?, ?, ?)',
                    (photo_num, message.from_user.id, text, media, inline_urls, 0))
        db.commit()
    
    
    async def get_one_post():
        data = cur.execute('SELECT text, media_path, inline_urls FROM posts WHERE status = ?', (0,)).fetchone()
        text = data[0]
        photo = data[1]
        urls_temp = data[2]
        if urls_temp is not 'NULL':
            urls = []
            for x in urls_temp:
                urls.append(x.split(' - '))
            buttons = []
            for x in urls:
                buttons.append([types.InlineKeyboardButton(text=x[0], url=x[1])])
            kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        else:
            kb = None
        return text, photo, kb


    #schedule
    from aiogram import types, Bot
    from config import channel_id
    import database
    
    
    async def auto_posting(bot: Bot):
        await database.connect_db()
        data = await database.get_one_post()
        text = str(data[0])
        photo = str(data[1])
        kb = data[2]
        print(text, photo, kb)
        if photo != 'NULL':
            await bot.send_photo(channel_id,
                                 photo=types.FSInputFile(path=photo),
                                 caption=text,
                                 reply_markup=kb,
                                 parse_mode='HTML')
        else:
            await bot.send_message(channel_id,
                                   text=text,
                                   reply_markup=kb,
                                   parse_mode='HTML')
    Написано
  • Как отправлять сообщения по расписанию с aiogram3?

    @spencer_spfl Автор вопроса
    spencer_spfl,
    Продолжение:
    @dp.message(Post.inline_url, F.text)
    async def new_post_4_1(message: types.Message, state: FSMContext):
        urls_db = message.text
        urls_temp = urls_db.split('\n')
        urls = []
        for x in urls_temp:
            urls.append(x.split(' - '))
        await state.update_data(inline_url=urls)
        buttons = []
        for x in urls:
            buttons.append([types.InlineKeyboardButton(text=x[0], url=x[1])])
        data = await state.get_data()
        text = data['text']
        buttons.append(new_post_end)
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await bot.delete_message(message.chat.id, message.message_id - 1)
        await bot.delete_message(message.chat.id, message.message_id)
        if data['media'] is None:
            await message.answer(text=text,
                                 reply_markup=kb,
                                 parse_mode='HTML',
                                 )
        else:
            photo = data['media']
            await message.answer_photo(photo=types.FSInputFile(path=photo),
                                       caption=text,
                                       reply_markup=kb,
                                       parse_mode='HTML')
        await state.clear()
    
    
    @dp.chat_join_request()
    async def join_request_accept(update: types.ChatJoinRequest):
        user_id = update.from_user.id
        buttons = [delete_button]
        kb = types.InlineKeyboardMarkup(keyboard=buttons)
        await bot.send_message(user_id,
                               text= #текст,
                               reply_markup=kb,
                               parse_mode='HTML')
        await update.approve()
    
    
    @dp.message()
    async def all_messages_func(message: types.Message):
        await bot.delete_message(message.chat.id, message.message_id)
        text =  #текст
        buttons = [delete_button]
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await message.answer(text=text, parse_mode='HTML', reply_markup=kb)
    
    
    @dp.callback_query(lambda call: call.data == 'delete_message')
    async def delete_message(call: types.CallbackQuery):
        await bot.delete_message(call.message.chat.id, call.message.message_id)
    
    
    async def scheduler():
        aioschedule.every().day.at("00:02").do(asyncio.create_task(auto_posting(bot)))
        while True:
            await aioschedule.run_pending()
            await asyncio.sleep(1)
    
    
    asyncio.create_task(scheduler())
    
    
    async def main():
        logging.basicConfig(level=logging.INFO)
        scheduler_task = asyncio.create_task(scheduler())  # создаём фоновую задачу
        try:
            await dp.start_polling(bot)
        finally:
            scheduler_task.cancel()  # сигналим о прерывании фоновой задачи
            try:
                await scheduler_task  # даём фоновой задаче шанс обработать сигнал о прерывании
            except asyncio.CancelledError:
                pass  # если всё отработало как надо, то await выкинет CancelledError
    
    
    if __name__ == '__main__':
        asyncio.run(main())


    C:\Users\user\AppData\Local\Programs\Python\Python311\python.exe "C:\Users\user\folder\main.py" 
    Traceback (most recent call last):
      File "C:\Users\user\Desktop\folder\main.py", line 377, in <module>
        asyncio.create_task(scheduler())
      File "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 371, in create_task
        loop = events.get_running_loop()
               ^^^^^^^^^^^^^^^^^^^^^^^^^
    RuntimeError: no running event loop
    sys:1: RuntimeWarning: coroutine 'scheduler' was never awaited
    Написано
  • Как отправлять сообщения по расписанию с aiogram3?

    @spencer_spfl Автор вопроса
    Vindicar,

    import asyncio
    import logging
    import aioschedule
    
    from aiogram import Bot, Dispatcher, types, F
    from aiogram.filters import CommandStart
    from aiogram.fsm.state import StatesGroup, State
    from aiogram.fsm.context import FSMContext
    from config import TOKEN
    from schedule import auto_posting
    
    bot = Bot(token=TOKEN)
    dp = Dispatcher()
    
    
    class Post(StatesGroup):
        text = State()
        media = State()
        inline_url = State()
    
    
    admin_list = []
    with open('text/admin_list.txt', 'r', encoding='utf-8') as file:
        for line in file:
            admin_list.append([int(line.split('|')[0]), str(line.split('|')[1][0:-1])])
    
    city_list = []
    with open('text/city_list.txt', 'r', encoding='utf-8') as file:
        for line in file:
            city_list.append([str(line.split('|')[0]), str(line.split('|')[1]), int(line.split('|')[2][0:-1])])
    
    shop_list = []
    with open('text/shop_list.txt', 'r', encoding='utf-8') as file:
        for line in file:
            line = line[0:-1]
            line = line.split('|')
            list_line = []
            for i in range(0, len(line) - 1, 2):
                list_line.append([line[i], line[i + 1]])
            shop_list.append(list_line)
    
    start_buttons = [
    #кнопки
    ]
    
    admin_panel_buttons = [
    #кнопки
    ]
    
    autopost_panel_buttons = [
        #кнопки
    ]
    
    #кнопки
    
    photo_paths = [
       #картинки
    ]
    
    
    @dp.message(CommandStart())
    async def start_message_func(message: types.Message):
        await bot.delete_message(message.chat.id, message.message_id)
        photo = photo_paths[0]
        buttons = start_buttons.copy()
        identification = message.from_user.full_name
        for x in admin_list:
            if message.from_user.id in x:
                identification = message.from_user.full_name
                buttons.append(admin_button)
        text = #текст
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await bot.send_photo(
            message.chat.id,
            photo=types.FSInputFile(path=photo),
            caption=text,
            reply_markup=kb,
            parse_mode='HTML'
        )
    
    
    @dp.callback_query(lambda call: call.data == 'city_list')
    async def city_list_func(call: types.CallbackQuery):
        text =  #текст
        buttons = []
        for x in city_list:
            buttons.append([types.InlineKeyboardButton(text=x[0], callback_data=x[1])])
        buttons.append([types.InlineKeyboardButton(text='Назад', callback_data='menu')])
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await bot.edit_message_caption(
            chat_id=call.message.chat.id,
            message_id=call.message.message_id,
            caption=text,
            parse_mode='HTML',
            reply_markup=kb,
        )
    
    
    @dp.callback_query(lambda call: call.data.startswith('shop_list'))
    async def shop_list_func(call: types.CallbackQuery):
        city_code = 0
        text =  #текст
        buttons = []
        for x in city_list:
            if call.data in x:
                city_code = x[2]
        for x in shop_list[city_code]:
            buttons.append([types.InlineKeyboardButton(text=x[0], url=x[1])])
        buttons.append([types.InlineKeyboardButton(text='Назад', callback_data='city_list')])
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await bot.edit_message_caption(
            chat_id=call.message.chat.id,
            message_id=call.message.message_id,
            caption=text,
            parse_mode='HTML',
            reply_markup=kb,
        )
    
    
    @dp.callback_query(lambda call: call.data.startswith('menu'))
    async def menu_func(call: types.CallbackQuery):
        identification = str(call.from_user.full_name)
        buttons = start_buttons.copy()
        for x in admin_list:
            if call.message.chat.id in x:
                identification = str(x[1])
                buttons.append([types.InlineKeyboardButton(text='Админ панель', callback_data='admin_panel')])
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        text = #текст
        await bot.edit_message_caption(
            chat_id=call.message.chat.id,
            message_id=call.message.message_id,
            caption=text,
            parse_mode='HTML',
            reply_markup=kb,
        )
    
    
    @dp.callback_query(lambda call: call.data == 'admin_panel')
    async def admin_panel_func(call: types.CallbackQuery):
        identification = 'Админ'
        for x in admin_list:
            if call.message.chat.id in x:
                identification = str(x[1])
        text =  #текст
        buttons = admin_panel_buttons.copy()
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await bot.edit_message_caption(
            chat_id=call.message.chat.id,
            message_id=call.message.message_id,
            caption=text,
            parse_mode='HTML',
            reply_markup=kb,
        )
    
    
    @dp.callback_query(lambda call: call.data == 'autopost')
    async def autopost_panel(call: types.CallbackQuery):
        identification = 'Админ'
        for x in admin_list:
            if call.message.chat.id in x:
                identification = str(x[1])
        text =  #текст
        buttons = autopost_panel_buttons.copy()
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await bot.edit_message_caption(
            chat_id=call.message.chat.id,
            message_id=call.message.message_id,
            caption=text,
            parse_mode='HTML',
            reply_markup=kb,
        )
    
    
    @dp.callback_query(lambda call: call.data == 'autopost_back')
    async def autopost_panel_back(call: types.CallbackQuery):
        identification = 'Админ'
        photo = photo_paths[0]
        for x in admin_list:
            if call.message.chat.id in x:
                identification = str(x[1])
        text =  #текст
        buttons = autopost_panel_buttons.copy()
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await bot.delete_message(call.message.chat.id, call.message.message_id)
        await bot.send_photo(
            chat_id=call.message.chat.id,
            photo=types.FSInputFile(path=photo),
            caption=text,
            parse_mode='HTML',
            reply_markup=kb,
        )
    
    
    @dp.callback_query(lambda call: call.data == 'new_post')
    async def new_post_1(call: types.CallbackQuery, state: FSMContext):
        await state.set_state(Post.text)
        await bot.delete_message(call.message.chat.id, call.message.message_id)
        text = #текст
        await bot.send_message(
            chat_id=call.message.chat.id,
            text=text,
            parse_mode='HTML',
        )
    
    
    @dp.message(Post.text, F.text)
    async def new_post_2(message: types.Message, state: FSMContext):
        await state.update_data(text=message.text)
        await state.set_state(Post.media)
        await bot.delete_message(message.chat.id, message.message_id - 1)
        await bot.delete_message(message.chat.id, message.message_id)
        text = #текст
        buttons = [nahuh_button]
        kb = types.ReplyKeyboardMarkup(keyboard=buttons)
        await bot.send_message(message.chat.id,
                               text=text,
                               parse_mode='HTML',
                               reply_markup=kb)
    
    
    @dp.message(Post.media, F.text ==  #текст)
    async def new_post_3_1(message: types.Message, state: FSMContext):
        await state.update_data(media=None)
        await state.set_state(Post.inline_url)
        await bot.delete_message(message.chat.id, message.message_id - 1)
        await bot.delete_message(message.chat.id, message.message_id)
        text = #текст
        buttons = net_button.copy()
        kb = types.ReplyKeyboardMarkup(keyboard=buttons)
        await bot.send_message(message.chat.id,
                               text=text,
                               parse_mode='HTML',
                               reply_markup=kb,
                               )
    
    
    @dp.message(Post.media, F.photo)
    async def new_post_3_2(message: types.Message, state: FSMContext):
        with open('text/photo_num.txt', 'r') as file_pic:
            photo_num = str(file_pic.read())
        file_name = 'post_photos/post_photo_' + photo_num
        with open('text/photo_num.txt', 'w') as file_pic:
            file_pic.write(str(int(photo_num) + 1))
        await bot.download(file=message.photo[-1].file_id, destination=file_name)
        await state.update_data(media=file_name)
        await state.set_state(Post.inline_url)
        await bot.delete_message(message.chat.id, message.message_id - 1)
        await bot.delete_message(message.chat.id, message.message_id)
        text = #текст
        buttons = net_button.copy()
        kb = types.ReplyKeyboardMarkup(keyboard=buttons)
        await bot.send_photo(
            message.chat.id,
            photo=types.FSInputFile(path=file_name),
            caption=text,
            parse_mode='HTML',
            reply_markup=kb,
        )
    
    
    @dp.message(Post.inline_url, F.text == #текст)
    async def new_post_4_2(message: types.Message, state: FSMContext):
        await state.update_data(inline_url=None)
        data = await state.get_data()
        text = data['text']
        buttons = [[types.InlineKeyboardButton(text='Назад', callback_data='autopost_back')]]
        kb = types.InlineKeyboardMarkup(inline_keyboard=buttons)
        await bot.delete_message(message.chat.id, message.message_id - 1)
        await bot.delete_message(message.chat.id, message.message_id)
        if data['media'] is None:
            await message.answer(text=text,
                                 reply_markup=kb,
                                 parse_mode='HTML', )
        else:
            photo = data['media']
            await message.answer_photo(photo=types.FSInputFile(path=photo),
                                       caption=text,
                                       reply_markup=kb,
                                       parse_mode='HTML')
        await state.clear()
    Написано
  • Как отправлять сообщения по расписанию с aiogram3?

    @spencer_spfl Автор вопроса
    но если прописать это в main(), от меня требуют await перед
    asyncio.create_task(scheduler())
    "Вместо этого сохрани таск в глобальную переменную", как это сделать, если не просто прописать вне функций?
    Написано
  • Как отправлять сообщения по расписанию с aiogram3?

    @spencer_spfl Автор вопроса
    Вот исправленый код
    async def scheduler():
        aioschedule.every().day.at("00:02").do(asyncio.create_task(auto_posting(bot)))
        while True:
            await aioschedule.run_pending()
            await asyncio.sleep(1)
    
    
    asyncio.create_task(scheduler())
    
    
    async def main():
        logging.basicConfig(level=logging.INFO)
        await dp.start_polling(bot)
    
    
    if __name__ == '__main__':
        asyncio.run(main())


    Теперь выдаёт ошибку:
    File "main.py", line 378, in <module>
        asyncio.create_task(scheduler())
      File "tasks.py", line 371, in create_task
        loop = events.get_running_loop()
               ^^^^^^^^^^^^^^^^^^^^^^^^^
    RuntimeError: no running event loop
    sys:1: RuntimeWarning: coroutine 'scheduler' was never awaited


    Хочет, чтобы был await и не запускается цикл.
    Написано
  • Не реагируют на нажатия кнопки в телеграм боте?

    @spencer_spfl
    Its_IVAN,
    @dp.callback_query_handler(text="support")
    Обрабатывает нажатие на кнопку, а не сообщение. Вы получаете не message, а call, его нужно по другому обрабатывать.
    
    @dp.callback_query_handler(call: call.data == 'support')
    async def support(call: types.CallbackQuery):
        markup = types.InlineKeyboardMarkup(row_width=2)
        markup.add(types.InlineKeyboardButton("Продолжить", callback_data='support2'))
        markup.add(types.InlineKeyboardButton("Отмена", callback_data='menu'))
        await bot.send_message(call.message.chat.id,
                             text="Мы отправим все данные собраные с опроса мы отправим специалисту для улучшения обслуживания и экономии времени",
                             reply_markup=markup)
    Написано