Добавлены типы событий: bot_stopped, dialog_cleared, dialog_muted, dialog_unmuted. Изменена система запуска вебхуков
This commit is contained in:
parent
5e98e540ea
commit
29b319768b
@ -5,9 +5,6 @@ import asyncio
|
||||
from typing import Any, Callable, Dict, List, TYPE_CHECKING, Optional
|
||||
from asyncio.exceptions import TimeoutError as AsyncioTimeoutError
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
from uvicorn import Config, Server
|
||||
from aiohttp import ClientConnectorError
|
||||
|
||||
from .filters.middleware import BaseMiddleware
|
||||
@ -17,7 +14,7 @@ from .context import MemoryContext
|
||||
from .types.updates import UpdateUnion
|
||||
from .types.errors import Error
|
||||
|
||||
from .methods.types.getted_updates import process_update_webhook, process_update_request
|
||||
from .methods.types.getted_updates import process_update_request, process_update_webhook
|
||||
|
||||
from .filters import filter_attrs
|
||||
|
||||
@ -25,12 +22,25 @@ from .bot import Bot
|
||||
from .enums.update import UpdateType
|
||||
from .loggers import logger_dp
|
||||
|
||||
|
||||
try:
|
||||
from fastapi import FastAPI, Request # type: ignore
|
||||
from fastapi.responses import JSONResponse # type: ignore
|
||||
FASTAPI_INSTALLED = True
|
||||
except ImportError:
|
||||
FASTAPI_INSTALLED = False
|
||||
|
||||
|
||||
try:
|
||||
from uvicorn import Config, Server # type: ignore
|
||||
UVICORN_INSTALLED = True
|
||||
except ImportError:
|
||||
UVICORN_INSTALLED = False
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from magic_filter import MagicFilter
|
||||
|
||||
|
||||
webhook_app = FastAPI()
|
||||
|
||||
CONNECTION_RETRY_DELAY = 30
|
||||
GET_UPDATES_RETRY_DELAY = 5
|
||||
|
||||
@ -44,12 +54,14 @@ class Dispatcher:
|
||||
применение middleware, фильтров и вызов соответствующих обработчиков.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, router_id: str | None = None) -> None:
|
||||
|
||||
"""
|
||||
Инициализация диспетчера.
|
||||
"""
|
||||
|
||||
self.router_id = router_id
|
||||
|
||||
self.event_handlers: List[Handler] = []
|
||||
self.contexts: List[MemoryContext] = []
|
||||
self.routers: List[Router | Dispatcher] = []
|
||||
@ -57,12 +69,17 @@ class Dispatcher:
|
||||
self.middlewares: List[BaseMiddleware] = []
|
||||
|
||||
self.bot: Optional[Bot] = None
|
||||
self.webhook_app: Optional[FastAPI] = None
|
||||
self.on_started_func: Optional[Callable] = None
|
||||
|
||||
self.message_created = Event(update_type=UpdateType.MESSAGE_CREATED, router=self)
|
||||
self.bot_added = Event(update_type=UpdateType.BOT_ADDED, router=self)
|
||||
self.bot_removed = Event(update_type=UpdateType.BOT_REMOVED, router=self)
|
||||
self.bot_started = Event(update_type=UpdateType.BOT_STARTED, router=self)
|
||||
self.bot_stopped = Event(update_type=UpdateType.BOT_STOPPED, router=self)
|
||||
self.dialog_cleared = Event(update_type=UpdateType.DIALOG_CLEARED, router=self)
|
||||
self.dialog_muted = Event(update_type=UpdateType.DIALOG_MUTED, router=self)
|
||||
self.dialog_unmuted = Event(update_type=UpdateType.DIALOG_UNMUTED, router=self)
|
||||
self.chat_title_changed = Event(update_type=UpdateType.CHAT_TITLE_CHANGED, router=self)
|
||||
self.message_callback = Event(update_type=UpdateType.MESSAGE_CALLBACK, router=self)
|
||||
self.message_chat_created = Event(update_type=UpdateType.MESSAGE_CHAT_CREATED, router=self)
|
||||
@ -72,6 +89,23 @@ class Dispatcher:
|
||||
self.user_removed = Event(update_type=UpdateType.USER_REMOVED, router=self)
|
||||
self.on_started = Event(update_type=UpdateType.ON_STARTED, router=self)
|
||||
|
||||
def webhook_post(self, path: str):
|
||||
def decorator(func):
|
||||
if self.webhook_app is None:
|
||||
try:
|
||||
from fastapi import FastAPI # type: ignore
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
'\n\t Не установлен fastapi!'
|
||||
'\n\t Выполните команду для установки fastapi: '
|
||||
'\n\t pip install fastapi>=0.68.0'
|
||||
'\n\t Или сразу все зависимости для работы вебхука:'
|
||||
'\n\t pip install maxapi[webhook]'
|
||||
)
|
||||
self.webhook_app = FastAPI()
|
||||
return self.webhook_app.post(path)(func)
|
||||
return decorator
|
||||
|
||||
async def check_me(self):
|
||||
|
||||
"""
|
||||
@ -178,14 +212,19 @@ class Dispatcher:
|
||||
memory_context = self.__get_memory_context(*ids)
|
||||
current_state = await memory_context.get_state()
|
||||
kwargs = {'context': memory_context}
|
||||
router_id = None
|
||||
|
||||
process_info = f'{event_object.update_type} | chat_id: {ids[0]}, user_id: {ids[1]}'
|
||||
|
||||
is_handled = False
|
||||
|
||||
for router in self.routers:
|
||||
for index, router in enumerate(self.routers):
|
||||
|
||||
if is_handled:
|
||||
break
|
||||
|
||||
router_id = router.router_id or index
|
||||
|
||||
if router.filters:
|
||||
if not filter_attrs(event_object, *router.filters):
|
||||
continue
|
||||
@ -225,16 +264,16 @@ class Dispatcher:
|
||||
|
||||
await handler.func_event(event_object, **kwargs)
|
||||
|
||||
logger_dp.info(f'Обработано: {event_object.update_type} | chat_id: {ids[0]}, user_id: {ids[1]}')
|
||||
logger_dp.info(f'Обработано: {router_id} | {process_info}')
|
||||
|
||||
is_handled = True
|
||||
break
|
||||
|
||||
if not is_handled:
|
||||
logger_dp.info(f'Проигнорировано: {event_object.update_type} | chat_id: {ids[0]}, user_id: {ids[1]}')
|
||||
logger_dp.info(f'Проигнорировано: {router_id} | {process_info}')
|
||||
|
||||
except Exception as e:
|
||||
logger_dp.error(f"Ошибка при обработке события: {event_object.update_type} | chat_id: {ids[0]}, user_id: {ids[1]} | {e} ")
|
||||
logger_dp.error(f"Ошибка при обработке события: {router_id} | {process_info} | {e} ")
|
||||
|
||||
async def start_polling(self, bot: Bot):
|
||||
|
||||
@ -279,7 +318,7 @@ class Dispatcher:
|
||||
except Exception as e:
|
||||
logger_dp.error(f'Общая ошибка при обработке событий: {e.__class__} - {e}')
|
||||
|
||||
async def handle_webhook(self, bot: Bot, host: str = '127.0.0.1', port: int = 8080):
|
||||
async def handle_webhook(self, bot: Bot, host: str = 'localhost', port: int = 8080, **kwargs):
|
||||
|
||||
"""
|
||||
Запускает FastAPI-приложение для приёма обновлений через вебхук.
|
||||
@ -288,33 +327,58 @@ class Dispatcher:
|
||||
:param host: Хост, на котором запускается сервер.
|
||||
:param port: Порт сервера.
|
||||
"""
|
||||
|
||||
@webhook_app.post('/')
|
||||
async def _(request: Request):
|
||||
if self.bot is None:
|
||||
raise RuntimeError('Bot не инициализирован')
|
||||
|
||||
try:
|
||||
event_json = await request.json()
|
||||
|
||||
event_object = await process_update_webhook(
|
||||
event_json=event_json,
|
||||
bot=self.bot
|
||||
)
|
||||
|
||||
await self.handle(event_object)
|
||||
|
||||
return JSONResponse(content={'ok': True}, status_code=200)
|
||||
except Exception as e:
|
||||
logger_dp.error(f"Ошибка при обработке события: {event_json['update_type']}: {e}")
|
||||
|
||||
if not FASTAPI_INSTALLED:
|
||||
raise ImportError(
|
||||
'\n\t Не установлен fastapi!'
|
||||
'\n\t Выполните команду для установки fastapi: '
|
||||
'\n\t pip install fastapi>=0.68.0'
|
||||
'\n\t Или сразу все зависимости для работы вебхука:'
|
||||
'\n\t pip install maxapi[webhook]'
|
||||
)
|
||||
|
||||
elif not UVICORN_INSTALLED:
|
||||
raise ImportError(
|
||||
'\n\t Не установлен uvicorn!'
|
||||
'\n\t Выполните команду для установки uvicorn: '
|
||||
'\n\t pip install uvicorn>=0.15.0'
|
||||
'\n\t Или сразу все зависимости для работы вебхука:'
|
||||
'\n\t pip install maxapi[webhook]'
|
||||
)
|
||||
|
||||
# try:
|
||||
# from fastapi import Request
|
||||
# from fastapi.responses import JSONResponse
|
||||
# except ImportError:
|
||||
# raise ImportError(
|
||||
# '\n\t Не установлен fastapi!'
|
||||
# '\n\t Выполните команду для установки fastapi: '
|
||||
# '\n\t pip install fastapi>=0.68.0'
|
||||
# '\n\t Или сразу все зависимости для работы вебхука:'
|
||||
# '\n\t pip install maxapi[webhook]'
|
||||
# )
|
||||
|
||||
|
||||
@self.webhook_post('/')
|
||||
async def _(request: Request):
|
||||
event_json = await request.json()
|
||||
event_object = await process_update_webhook(
|
||||
event_json=event_json,
|
||||
bot=bot
|
||||
)
|
||||
|
||||
await self.handle(event_object)
|
||||
return JSONResponse(content={'ok': True}, status_code=200)
|
||||
|
||||
|
||||
await self.init_serve(
|
||||
bot=bot,
|
||||
host=host,
|
||||
port=port
|
||||
port=port,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
async def init_serve(self, bot: Bot, host: str = '127.0.0.1', port: int = 8080, **kwargs):
|
||||
async def init_serve(self, bot: Bot, host: str = 'localhost', port: int = 8080, **kwargs):
|
||||
|
||||
"""
|
||||
Запускает сервер для обработки входящих вебхуков.
|
||||
@ -324,7 +388,30 @@ class Dispatcher:
|
||||
:param port: Порт сервера.
|
||||
"""
|
||||
|
||||
config = Config(app=webhook_app, host=host, port=port, **kwargs)
|
||||
# try:
|
||||
# from uvicorn import Config, Server
|
||||
# except ImportError:
|
||||
# raise ImportError(
|
||||
# '\n\t Не установлен uvicorn!'
|
||||
# '\n\t Выполните команду для установки uvicorn: '
|
||||
# '\n\t pip install uvicorn>=0.15.0'
|
||||
# '\n\t Или сразу все зависимости для работы вебхука:'
|
||||
# '\n\t pip install maxapi[webhook]'
|
||||
# )
|
||||
|
||||
if not UVICORN_INSTALLED:
|
||||
raise ImportError(
|
||||
'\n\t Не установлен uvicorn!'
|
||||
'\n\t Выполните команду для установки uvicorn: '
|
||||
'\n\t pip install uvicorn>=0.15.0'
|
||||
'\n\t Или сразу все зависимости для работы вебхука:'
|
||||
'\n\t pip install maxapi[webhook]'
|
||||
)
|
||||
|
||||
if self.webhook_app is None:
|
||||
raise RuntimeError('webhook_app не инициализирован')
|
||||
|
||||
config = Config(app=self.webhook_app, host=host, port=port, **kwargs)
|
||||
server = Server(config)
|
||||
|
||||
await self.__ready(bot)
|
||||
@ -338,8 +425,8 @@ class Router(Dispatcher):
|
||||
Роутер для группировки обработчиков событий.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
def __init__(self, router_id: str | None = None):
|
||||
super().__init__(router_id)
|
||||
|
||||
|
||||
class Event:
|
||||
|
Loading…
x
Reference in New Issue
Block a user