mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Added possibility to reply into webhook with files (#1120)
This commit is contained in:
parent
84bc0e347b
commit
58868ec627
6 changed files with 126 additions and 30 deletions
|
|
@ -13,7 +13,7 @@ from ..fsm.middleware import FSMContextMiddleware
|
|||
from ..fsm.storage.base import BaseEventIsolation, BaseStorage
|
||||
from ..fsm.storage.memory import DisabledEventIsolation, MemoryStorage
|
||||
from ..fsm.strategy import FSMStrategy
|
||||
from ..methods import GetUpdates, TelegramMethod
|
||||
from ..methods import GetUpdates, Request, TelegramMethod
|
||||
from ..types import Update, User
|
||||
from ..types.update import UpdateTypeLookupError
|
||||
from ..utils.backoff import Backoff, BackoffConfig
|
||||
|
|
@ -351,7 +351,7 @@ class Dispatcher(Router):
|
|||
|
||||
async def feed_webhook_update(
|
||||
self, bot: Bot, update: Union[Update, Dict[str, Any]], _timeout: float = 55, **kwargs: Any
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
) -> Optional[Request]:
|
||||
if not isinstance(update, Update): # Allow to use raw updates
|
||||
update = Update(**update)
|
||||
|
||||
|
|
@ -397,8 +397,7 @@ class Dispatcher(Router):
|
|||
# TODO: handle exceptions
|
||||
response: Any = process_updates.result()
|
||||
if isinstance(response, TelegramMethod):
|
||||
request = response.build_request(bot=bot)
|
||||
return request.render_webhook_request()
|
||||
return response.build_request(bot=bot)
|
||||
|
||||
else:
|
||||
process_updates.remove_done_callback(release_waiter)
|
||||
|
|
|
|||
|
|
@ -33,12 +33,6 @@ class Request(BaseModel):
|
|||
class Config(BaseConfig):
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
def render_webhook_request(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"method": self.method,
|
||||
**{key: value for key, value in self.data.items() if value is not None},
|
||||
}
|
||||
|
||||
|
||||
class Response(GenericModel, Generic[TelegramType]):
|
||||
ok: bool
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
import asyncio
|
||||
import secrets
|
||||
from abc import ABC, abstractmethod
|
||||
from asyncio import Transport
|
||||
from typing import Any, Awaitable, Callable, Dict, Optional, Tuple, cast
|
||||
|
||||
from aiohttp import web
|
||||
from aiohttp import MultipartWriter, web
|
||||
from aiohttp.abc import Application
|
||||
from aiohttp.typedefs import Handler
|
||||
from aiohttp.web_middlewares import middleware
|
||||
|
||||
from aiogram import Bot, Dispatcher, loggers
|
||||
from aiogram.methods import TelegramMethod
|
||||
from aiogram.methods import Request, TelegramMethod
|
||||
from aiogram.types import UNSET
|
||||
from aiogram.webhook.security import IPFilter
|
||||
|
||||
|
||||
|
|
@ -84,7 +86,10 @@ class BaseRequestHandler(ABC):
|
|||
"""
|
||||
|
||||
def __init__(
|
||||
self, dispatcher: Dispatcher, handle_in_background: bool = True, **data: Any
|
||||
self,
|
||||
dispatcher: Dispatcher,
|
||||
handle_in_background: bool = False,
|
||||
**data: Any,
|
||||
) -> None:
|
||||
"""
|
||||
:param dispatcher: instance of :class:`aiogram.dispatcher.dispatcher.Dispatcher`
|
||||
|
|
@ -138,15 +143,39 @@ class BaseRequestHandler(ABC):
|
|||
)
|
||||
return web.json_response({}, dumps=bot.session.json_dumps)
|
||||
|
||||
def _build_response_writer(self, bot: Bot, result: Optional[Request]) -> MultipartWriter:
|
||||
writer = MultipartWriter(
|
||||
"form-data",
|
||||
boundary=f"webhookBoundary{secrets.token_urlsafe(16)}",
|
||||
)
|
||||
if not result:
|
||||
return writer
|
||||
|
||||
payload = writer.append(result.method)
|
||||
payload.set_content_disposition("form-data", name="method")
|
||||
|
||||
for key, value in result.data.items():
|
||||
if value is None or value is UNSET:
|
||||
continue
|
||||
payload = writer.append(bot.session.prepare_value(value))
|
||||
payload.set_content_disposition("form-data", name=key)
|
||||
|
||||
if not result.files:
|
||||
return writer
|
||||
|
||||
for key, value in result.files.items():
|
||||
payload = writer.append(value)
|
||||
payload.set_content_disposition("form-data", name=key, filename=value.filename)
|
||||
|
||||
return writer
|
||||
|
||||
async def _handle_request(self, bot: Bot, request: web.Request) -> web.Response:
|
||||
result = await self.dispatcher.feed_webhook_update(
|
||||
bot,
|
||||
await request.json(loads=bot.session.json_loads),
|
||||
**self.data,
|
||||
)
|
||||
if result:
|
||||
return web.json_response(result, dumps=bot.session.json_dumps)
|
||||
return web.json_response({}, dumps=bot.session.json_dumps)
|
||||
return web.Response(body=self._build_response_writer(bot=bot, result=result))
|
||||
|
||||
async def handle(self, request: web.Request) -> web.Response:
|
||||
bot = await self.resolve_bot(request)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue