Не удалось запустить мультибота по кнопке

Рейтинг: 2Ответов: 0Опубликовано: 18.06.2023

У меня есть файл main.py:

import asyncio
import logging

from aiogram import Bot, Dispatcher, F
from aiogram.filters.command import Command
from aiogram.filters.text import Text

from aiogram.fsm.storage.memory import SimpleEventIsolation

from aiogram.exceptions import TelegramUnauthorizedError

from config import dp, bot
from utils.polling_manager import PollingManager
from handlers import client
from mb_handlers import client as mb_client
from database.database import *

logger = logging.getLogger(__name__)


def get_bot_tokens_from_database():
    users = Users.select()
    bot_tokens = [user.USERS_TOKENS for user in users]
    return bot_tokens


async def main():
    logging.getLogger("schedule").setLevel(logging.ERROR)
        
    # TODO: Handlers by main bot
    dp.message.register(client.start_message_handler, F.chat.type == 'private', Command(commands="start"))
    dp.message.register(client.settings, F.chat.type == 'private', Text(text="⚙️ Настройки"))
    dp.message.register(client.my_bots, F.chat.type == 'private', Text(text="🤖 Мои боты"))

    # dp.message.register(client.add_bot_father, F.chat.type == 'private', Text(text="back_in_my_bot"))
    # dp.message.register(client.adding_token, F.chat.type == 'private', Text(text=['text'],state=client.AddTokenStates.add_token))



    # ----

    bots_setting = get_bot_tokens_from_database()
    multi_dp = Dispatcher(events_isolation=SimpleEventIsolation())

    # TODO: Handlers by multibots
    multi_dp.message.register(mb_client.send_welcome_multi, F.chat.type == 'private', Command(commands="start"))
    # ----
    polling_manager = PollingManager()
    if bots_setting != list():
        for mbot_ in bots_setting:
            try:            
                mbot = Bot(mbot_)
                polling_manager.start_bot_polling(
                    dp=multi_dp, bot=mbot, polling_manager=polling_manager, dp_for_new_bot=multi_dp
                )
                # Проверка обновлений в ботах при включение, пока они были выключены
                await mbot.get_updates(offset=-1)
            except TelegramUnauthorizedError:
                await bot.send_message(chat_id=mbot_['owner_user_id'], text=f'Бот с пользовательским названием "@{mbot_["username_bot"]}" не был авторизирован\nРешением этой проблемы может быть изменение токена бота в настройках проекта')

    await dp.start_polling(bot, dp_for_new_bot=multi_dp, polling_manager=polling_manager)


if __name__ == "__main__":
    try:
        print('Starting main bot')
        asyncio.run(main())
    except (KeyboardInterrupt, SystemExit):
        logger.error("Exit")

poolling_manager.py:

import asyncio
import functools
import logging
from asyncio import AbstractEventLoop, CancelledError, Task, get_running_loop
from contextvars import Context
from typing import Any, Awaitable, Dict, List, Optional

from aiogram import Bot
from aiogram.dispatcher.dispatcher import DEFAULT_BACKOFF_CONFIG, Dispatcher
from aiogram.types import User
from aiogram.utils.backoff import BackoffConfig

logger = logging.getLogger(__name__)


class PollingManager:
    def __init__(self):
        self.polling_tasks: Dict[int, Task] = {}

    def _create_pooling_task(
        self,
        dp: Dispatcher,
        bot: Bot,
        polling_timeout: int,
        handle_as_tasks: bool,
        backoff_config: BackoffConfig,
        allowed_updates: Optional[List[str]],
        **kwargs: Any,
    ):
        asyncio.create_task(
            self._start_bot_polling(
                dp=dp,
                bot=bot,
                polling_timeout=polling_timeout,
                handle_as_tasks=handle_as_tasks,
                backoff_config=backoff_config,
                allowed_updates=allowed_updates,
                **kwargs,
            )
        )

    def start_bot_polling(
        self,
        dp: Dispatcher,
        bot: Bot,
        polling_timeout: int = 10,
        handle_as_tasks: bool = True,
        backoff_config: BackoffConfig = DEFAULT_BACKOFF_CONFIG,
        allowed_updates: Optional[List[str]] = None,
        **kwargs: Any,
    ):
        loop: AbstractEventLoop = get_running_loop()
        # noinspection PyArgumentList
        loop.call_soon(
            functools.partial(
                self._create_pooling_task,
                dp=dp,
                bot=bot,
                polling_timeout=polling_timeout,
                handle_as_tasks=handle_as_tasks,
                backoff_config=backoff_config,
                allowed_updates=allowed_updates,
                **kwargs,
            ),
            context=Context(),
        )

    async def _start_bot_polling(
        self,
        dp: Dispatcher,
        bot: Bot,
        polling_timeout: int = 10,
        handle_as_tasks: bool = True,
        backoff_config: BackoffConfig = DEFAULT_BACKOFF_CONFIG,
        allowed_updates: Optional[List[str]] = None,
        on_bot_startup: Optional[Awaitable] = None,
        on_bot_shutdown: Optional[Awaitable] = None,
        **kwargs: Any,
    ):
        logger.info("Start poling")
        user: User = await bot.me()
        if on_bot_startup:
            await on_bot_startup

        try:
            logger.info(
                "Run polling for bot @%s id=%d - %r",
                user.username,
                bot.id,
                user.full_name,
            )
            polling_task = asyncio.create_task(
                dp._polling(
                    bot=bot,
                    handle_as_tasks=handle_as_tasks,
                    polling_timeout=polling_timeout,
                    backoff_config=backoff_config,
                    allowed_updates=allowed_updates,
                    **kwargs,
                )
            )
            self.polling_tasks[bot.id] = polling_task
            await polling_task
        except CancelledError:
            logger.info("Polling task Canceled")
        finally:
            logger.info(
                "Polling stopped for bot @%s id=%d - %r",
                user.username,
                bot.id,
                user.full_name,
            )
            if on_bot_shutdown:
                await on_bot_shutdown

            await bot.session.close()

    def stop_bot_polling(self, bot_id: int):
        polling_task = self.polling_tasks.pop(bot_id)
        polling_task.cancel()

Вопрос в том, что я пытаюсь запустить бота вот таким вот кодом по кнопке:

@dp.callback_query(Text("options_bot_"))
async def handle_bot_settings(callback_query: types.CallbackQuery):
    user_id = callback_query.from_user.id
    user = Users.get_or_none(Users.USER_ID == user_id)
    if user:
        bot_username = user.BOT_USERNAME 
        user_token = user.USERS_TOKENS
        bot_id = user.ID_BOT
        settings_menu_keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
            [types.InlineKeyboardButton(text="Принятие заявок", callback_data=f"accept_requests_{bot_username}")],
            [types.InlineKeyboardButton(text="Запустить бота", callback_data=f"toggle_bot_{user_token}")],
        ])

    await callback_query.message.edit_text(options_text(user), reply_markup=settings_menu_keyboard)


@dp.callback_query()
async def handle_callback_query(callback_query: types.CallbackQuery):
    if re.search(r'toggle_bot_', callback_query.data):
        user_id = callback_query.from_user.id
        user = Users.get_or_none(Users.USER_ID == user_id)
        user_token = user.USERS_TOKENS
        multi_dp = Dispatcher(events_isolation=SimpleEventIsolation())
        polling_manager = PollingManager()
        if user_token:
            mbot = Bot(user_token)
            polling_manager.start_bot_polling(
                dp=multi_dp, bot=mbot, polling_manager=polling_manager, dp_for_new_bot=multi_dp
            )
            await mbot.get_updates(offset=-1)
            await dp.start_polling(multi_dp, mbot, polling_manager)
        await dp.start_polling(bot, dp_for_new_bot=multi_dp, polling_manager=polling_manager)

Но у меня ошибка вот такая:

RuntimeError: Task <Task pending name='Task-30' coro=<Dispatcher._process_update() running
 at C:\Users\admin\AppData\Local\Programs\Python\Python39\lib\site-packages\aiogram\dispatcher\dispatcher.py:293>> 
got Future <Future pending> attached to a different loop

Ответы

Ответов пока нет.