mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Merge branch 'dev-3.x' into docs-update
This commit is contained in:
commit
fd5ca38c36
1216 changed files with 25995 additions and 39588 deletions
|
|
@ -6,15 +6,15 @@ BaseHandler
|
|||
|
||||
Base handler is generic abstract class and should be used in all other class-based handlers.
|
||||
|
||||
Import: :code:`from aiogram.handler import BaseHandler`
|
||||
Import: :code:`from aiogram.handlers import BaseHandler`
|
||||
|
||||
By default you will need to override only method :code:`async def handle(self) -> Any: ...`
|
||||
|
||||
This class is also have an default initializer and you don't need to change it.
|
||||
Initializer accepts current event and all contextual data and which
|
||||
This class also has a default initializer and you don't need to change it.
|
||||
The initializer accepts the incoming event and all contextual data, which
|
||||
can be accessed from the handler through attributes: :code:`event: TelegramEvent` and :code:`data: Dict[Any, str]`
|
||||
|
||||
If instance of the bot is specified in context data or current context it can be accessed through *bot* class attribute.
|
||||
If an instance of the bot is specified in context data or current context it can be accessed through *bot* class attribute.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Simple usage
|
|||
Extension
|
||||
=========
|
||||
|
||||
This base handler is subclass of [BaseHandler](basics.md#basehandler) with some extensions:
|
||||
This base handler is subclass of :ref:`BaseHandler <cbh-base-handler>` with some extensions:
|
||||
|
||||
- :code:`self.chat` is alias for :code:`self.event.chat`
|
||||
- :code:`self.from_user` is alias for :code:`self.event.from_user`
|
||||
|
|
|
|||
72
docs/dispatcher/dependency_injection.rst
Normal file
72
docs/dispatcher/dependency_injection.rst
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
####################
|
||||
Dependency injection
|
||||
####################
|
||||
|
||||
Dependency injection is a programming technique that makes a class independent of its dependencies.
|
||||
It achieves that by decoupling the usage of an object from its creation.
|
||||
This helps you to follow `SOLID's <https://en.wikipedia.org/wiki/SOLID>`_ dependency
|
||||
inversion and single responsibility principles.
|
||||
|
||||
|
||||
How it works in aiogram
|
||||
=======================
|
||||
|
||||
For each update :class:`aiogram.dispatcher.dispatcher.Dispatcher` passes handling context data.
|
||||
Filters and middleware can also make changes to the context.
|
||||
|
||||
To access contextual data you should specify corresponding keyword parameter in handler or filter.
|
||||
For example, to get :class:`aiogram.fsm.context.FSMContext` we do it like that:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@router.message(ProfileCompletion.add_photo, F.photo)
|
||||
async def add_photo(
|
||||
message: types.Message, bot: Bot, state: FSMContext
|
||||
) -> Any:
|
||||
... # do something with photo
|
||||
|
||||
|
||||
Injecting own dependencies
|
||||
==========================
|
||||
|
||||
Aiogram provides several ways to complement / modify contextual data.
|
||||
|
||||
The first and easiest way is to simply specify the named arguments in
|
||||
:class:`aiogram.dispatcher.dispatcher.Dispatcher` initialization, polling start methods
|
||||
or :class:`aiogram.webhook.aiohttp_server.SimpleRequestHandler` initialization if you use webhooks.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async def main() -> None:
|
||||
dp = Dispatcher(..., foo=42)
|
||||
return await dp.start_polling(
|
||||
bot, bar="Bazz"
|
||||
)
|
||||
|
||||
Analogy for webhook:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
async def main() -> None:
|
||||
dp = Dispatcher(..., foo=42)
|
||||
handler = SimpleRequestHandler(dispatcher=dp, bot=bot, bar="Bazz")
|
||||
... # starting webhook
|
||||
|
||||
:class:`aiogram.dispatcher.dispatcher.Dispatcher`'s workflow data also can be supplemented
|
||||
by setting values as in a dictionary:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
dp = Dispatcher(...)
|
||||
dp["eggs"] = Spam()
|
||||
|
||||
The middlewares updates the context quite often.
|
||||
You can read more about them on this page:
|
||||
|
||||
- :ref:`Middlewares <middlewares>`
|
||||
|
||||
The last way is to return a dictionary from the filter:
|
||||
|
||||
.. literalinclude:: ../../examples/context_addition_from_filter.py
|
||||
|
||||
...or using :ref:`MagicFilter <magic-filters>` with :code:`.as_(...)` method.
|
||||
|
|
@ -4,14 +4,14 @@ Dispatcher
|
|||
|
||||
Dispatcher is root :obj:`Router` and in code Dispatcher can be used directly for routing updates or attach another routers into dispatcher.
|
||||
|
||||
Here is only listed base information about Dispatcher. All about writing handlers, filters and etc. you can found in next pages:
|
||||
Here is only listed base information about Dispatcher. All about writing handlers, filters and etc. you can find in next pages:
|
||||
|
||||
- `Router <router.html>`__
|
||||
- `Observer <observer.html>`__
|
||||
- :ref:`Router <Router>`
|
||||
- :ref:`Filtering events`
|
||||
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.dispatcher.Dispatcher
|
||||
:members: __init__, feed_update, feed_raw_update, feed_webhook_update, start_polling, run_polling
|
||||
:members: __init__, feed_update, feed_raw_update, feed_webhook_update, start_polling, run_polling, stop_polling
|
||||
|
||||
|
||||
Simple usage
|
||||
|
|
|
|||
49
docs/dispatcher/errors.rst
Normal file
49
docs/dispatcher/errors.rst
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
######
|
||||
Errors
|
||||
######
|
||||
|
||||
|
||||
Handling errors
|
||||
===============
|
||||
|
||||
Is recommended way that you should use errors inside handlers using try-except block,
|
||||
but in common cases you can use global errors handler at router or dispatcher level.
|
||||
|
||||
If you specify errors handler for router - it will be used for all handlers inside this router.
|
||||
|
||||
If you specify errors handler for dispatcher - it will be used for all handlers inside all routers.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@router.error(ExceptionTypeFilter(MyCustomException), F.update.message.as_("message"))
|
||||
async def handle_my_custom_exception(event: ErrorEvent, message: Message):
|
||||
# do something with error
|
||||
await message.answer("Oops, something went wrong!")
|
||||
|
||||
|
||||
@router.error()
|
||||
async def error_handler(event: ErrorEvent):
|
||||
logger.critical("Critical error caused by %s", event.exception, exc_info=True)
|
||||
# do something with error
|
||||
...
|
||||
|
||||
|
||||
.. _error-event:
|
||||
|
||||
ErrorEvent
|
||||
==========
|
||||
|
||||
.. automodule:: aiogram.types.error_event
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
:exclude-members: model_config,model_fields
|
||||
|
||||
.. _error-types:
|
||||
|
||||
Error types
|
||||
===========
|
||||
|
||||
.. automodule:: aiogram.exceptions
|
||||
:members:
|
||||
:member-order: bysource
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
.. _Callback data factory:
|
||||
|
||||
==============================
|
||||
Callback Data Factory & Filter
|
||||
==============================
|
||||
|
|
@ -6,6 +8,7 @@ Callback Data Factory & Filter
|
|||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: False
|
||||
:exclude-members: model_config,model_fields
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
|
|
|||
|
|
@ -2,6 +2,27 @@
|
|||
ChatMemberUpdated
|
||||
=================
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Handle user leave or join events
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiogram.filters import IS_MEMBER, IS_NOT_MEMBER
|
||||
|
||||
@router.chat_member(ChatMemberUpdatedFilter(IS_MEMBER >> IS_NOT_MEMBER))
|
||||
async def on_user_leave(event: ChatMemberUpdated): ...
|
||||
|
||||
@router.chat_member(ChatMemberUpdatedFilter(IS_NOT_MEMBER >> IS_MEMBER))
|
||||
async def on_user_join(event: ChatMemberUpdated): ...
|
||||
|
||||
Or construct your own terms via using pre-defined set of statuses and transitions.
|
||||
|
||||
|
||||
Explanation
|
||||
===========
|
||||
|
||||
.. autoclass:: aiogram.filters.chat_member_updated.ChatMemberUpdatedFilter
|
||||
:members:
|
||||
:member-order: bysource
|
||||
|
|
@ -77,22 +98,6 @@ will produce swap of old and new statuses.
|
|||
Note that if you define the status unions (via :code:`|`) you will need to add brackets for the statement
|
||||
before use shift operator in due to operator priorities.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Handle user leave or join events
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiogram.filters import IS_MEMBER, IS_NOT_MEMBER
|
||||
|
||||
@router.chat_member(ChatMemberUpdatedFilter(IS_MEMBER >> IS_NOT_MEMBER))
|
||||
async def on_user_leave(event: ChatMemberUpdated): ...
|
||||
|
||||
@router.chat_member(ChatMemberUpdatedFilter(IS_NOT_MEMBER >> IS_MEMBER))
|
||||
async def on_user_join(event: ChatMemberUpdated): ...
|
||||
|
||||
Or construct your own terms via using pre-defined set of statuses and transitions.
|
||||
|
||||
Allowed handlers
|
||||
================
|
||||
|
|
|
|||
|
|
@ -2,19 +2,6 @@
|
|||
Command
|
||||
=======
|
||||
|
||||
.. autoclass:: aiogram.filters.command.Command
|
||||
:members: __init__
|
||||
:member-order: bysource
|
||||
:undoc-members: False
|
||||
|
||||
When filter is passed the :class:`aiogram.filters.command.CommandObject` will be passed to the handler argument :code:`command`
|
||||
|
||||
.. autoclass:: aiogram.filters.command.CommandObject
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: False
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
|
|
@ -28,6 +15,19 @@ Usage
|
|||
|
||||
Command cannot include spaces or any whitespace
|
||||
|
||||
|
||||
.. autoclass:: aiogram.filters.command.Command
|
||||
:members: __init__
|
||||
:member-order: bysource
|
||||
:undoc-members: False
|
||||
|
||||
When filter is passed the :class:`aiogram.filters.command.CommandObject` will be passed to the handler argument :code:`command`
|
||||
|
||||
.. autoclass:: aiogram.filters.command.CommandObject
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: False
|
||||
|
||||
Allowed handlers
|
||||
================
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
.. _Filtering events:
|
||||
|
||||
================
|
||||
Filtering events
|
||||
================
|
||||
|
||||
Filters is needed for routing updates to the specific handler.
|
||||
Searching of handler is always stops on first match set of filters are pass.
|
||||
By default, all handlers has empty set of filters, so all updates will be passed to first handler that has empty set of filters.
|
||||
|
||||
*aiogram* has some builtin useful filters.
|
||||
*aiogram* has some builtin useful filters or you can write own filters.
|
||||
|
||||
Builtin filters
|
||||
===============
|
||||
|
|
|
|||
|
|
@ -2,6 +2,14 @@
|
|||
MagicData
|
||||
=========
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
#. :code:`MagicData(F.event.from_user.id == F.config.admin_id)` (Note that :code:`config` should be passed from middleware)
|
||||
|
||||
Explanation
|
||||
===========
|
||||
|
||||
.. autoclass:: aiogram.filters.magic_data.MagicData
|
||||
:members:
|
||||
:member-order: bysource
|
||||
|
|
@ -11,11 +19,6 @@ Can be imported:
|
|||
|
||||
- :code:`from aiogram.filters import MagicData`
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
#. :code:`MagicData(F.event.from_user.id == F.config.admin_id)` (Note that :code:`config` should be passed from middleware)
|
||||
|
||||
|
||||
Allowed handlers
|
||||
================
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
.. _Finite State Machine:
|
||||
|
||||
====================
|
||||
Finite State Machine
|
||||
====================
|
||||
|
|
|
|||
|
|
@ -15,13 +15,23 @@ With dispatcher you can do:
|
|||
Dispatcher is also separated into two entities - Router and Dispatcher.
|
||||
Dispatcher is subclass of router and should be always is root router.
|
||||
|
||||
Telegram supports two ways of receiving updates:
|
||||
|
||||
- :ref:`Webhook <webhook>` - you should configure your web server to receive updates from Telegram;
|
||||
- :ref:`Long polling <long-polling>` - you should request updates from Telegram.
|
||||
|
||||
So, you can use both of them with *aiogram*.
|
||||
|
||||
.. toctree::
|
||||
|
||||
observer
|
||||
router
|
||||
dispatcher
|
||||
class_based_handlers/index
|
||||
dependency_injection
|
||||
filters/index
|
||||
middlewares
|
||||
long_polling
|
||||
webhook
|
||||
finite_state_machine/index
|
||||
middlewares
|
||||
errors
|
||||
flags
|
||||
class_based_handlers/index
|
||||
|
|
|
|||
32
docs/dispatcher/long_polling.rst
Normal file
32
docs/dispatcher/long_polling.rst
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
.. _long-polling:
|
||||
|
||||
############
|
||||
Long-polling
|
||||
############
|
||||
|
||||
Long-polling is a technology that allows a Telegram server to send updates in case
|
||||
when you don't have dedicated IP address or port to receive webhooks for example
|
||||
on a developer machine.
|
||||
|
||||
To use long-polling mode you should use :meth:`aiogram.dispatcher.dispatcher.Dispatcher.start_polling`
|
||||
or :meth:`aiogram.dispatcher.dispatcher.Dispatcher.run_polling` methods.
|
||||
|
||||
.. note::
|
||||
|
||||
You can use polling from only one polling process per single Bot token,
|
||||
in other case Telegram server will return an error.
|
||||
|
||||
.. note::
|
||||
|
||||
If you will need to scale your bot, you should use webhooks instead of long-polling.
|
||||
|
||||
.. note::
|
||||
|
||||
If you will use multibot mode, you should use webhook mode for all bots.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
This example will show you how to create simple echo bot based on long-polling.
|
||||
|
||||
.. literalinclude:: ../../examples/echo_bot.py
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
.. _middlewares:
|
||||
|
||||
===========
|
||||
Middlewares
|
||||
===========
|
||||
|
|
@ -57,7 +59,8 @@ Examples
|
|||
|
||||
.. danger::
|
||||
|
||||
Middleware should always call :code:`await handler(event, data)` to propagate event for next middleware/handler
|
||||
Middleware should always call :code:`await handler(event, data)` to propagate event for next middleware/handler.
|
||||
If you want to stop processing event in middleware you should not call :code:`await handler(event, data)`.
|
||||
|
||||
|
||||
Class-based
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
########
|
||||
Observer
|
||||
########
|
||||
|
||||
Observer is used for filtering and handling different events. That is part of internal API with some public methods and is recommended to don't use methods is not listed here.
|
||||
|
||||
In `aiogram` framework is available two variants of observer:
|
||||
|
||||
- `EventObserver <#eventobserver>`__
|
||||
- `TelegramEventObserver <#telegrameventobserver>`__
|
||||
|
||||
|
||||
EventObserver
|
||||
=============
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.event.event.EventObserver
|
||||
:members: register, trigger, __call__
|
||||
:member-order: bysource
|
||||
|
||||
|
||||
TelegramEventObserver
|
||||
=====================
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.event.telegram.TelegramEventObserver
|
||||
:members: register, trigger, __call__, bind_filter, middleware, outer_middleware
|
||||
:member-order: bysource
|
||||
|
|
@ -1,12 +1,30 @@
|
|||
.. _Router:
|
||||
|
||||
######
|
||||
Router
|
||||
######
|
||||
|
||||
Usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from aiogram import Router
|
||||
from aiogram.types import Message
|
||||
|
||||
my_router = Router(name=__name__)
|
||||
|
||||
@my_router.message()
|
||||
async def message_handler(message: Message) -> Any:
|
||||
await message.answer('Hello from my router!')
|
||||
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.router.Router
|
||||
:members: __init__, include_router
|
||||
:members: __init__, include_router, include_routers, resolve_used_update_types
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
.. _Event observers:
|
||||
|
||||
Event observers
|
||||
===============
|
||||
|
||||
|
|
@ -19,19 +37,6 @@ Here is the list of available observers and examples of how to register handlers
|
|||
|
||||
In these examples only decorator-style registering handlers are used, but if you don't like @decorators just use :obj:`<event type>.register(...)` method instead.
|
||||
|
||||
Update
|
||||
------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@router.update()
|
||||
async def message_handler(update: types.Update) -> Any: pass
|
||||
|
||||
.. note::
|
||||
|
||||
By default Router already has an update handler which route all event types to another observers.
|
||||
|
||||
|
||||
Message
|
||||
-------
|
||||
|
||||
|
|
@ -143,9 +148,12 @@ Errors
|
|||
@router.errors()
|
||||
async def error_handler(exception: ErrorEvent) -> Any: pass
|
||||
|
||||
Is useful for handling errors from other handlers
|
||||
Is useful for handling errors from other handlers, error event described :ref:`here <error-event>`
|
||||
|
||||
|
||||
|
||||
.. _Nested routers:
|
||||
|
||||
Nested routers
|
||||
==============
|
||||
|
||||
|
|
@ -159,8 +167,8 @@ Nested routers
|
|||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
:caption: module_2.py
|
||||
:name: module_2
|
||||
:caption: module_1.py
|
||||
:name: module_1
|
||||
|
||||
router2 = Router()
|
||||
|
||||
|
|
@ -170,7 +178,7 @@ Example:
|
|||
|
||||
.. code-block:: python
|
||||
:caption: module_2.py
|
||||
:name: module_1
|
||||
:name: module_2
|
||||
|
||||
from module_2 import router2
|
||||
|
||||
|
|
@ -179,6 +187,22 @@ Example:
|
|||
router1.include_router(router2)
|
||||
|
||||
|
||||
Update
|
||||
------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@dispatcher.update()
|
||||
async def message_handler(update: types.Update) -> Any: pass
|
||||
|
||||
.. warning::
|
||||
|
||||
The only root Router (Dispatcher) can handle this type of event.
|
||||
|
||||
.. note::
|
||||
|
||||
Dispatcher already has default handler for this event type, so you can use it for handling all updates that are not handled by any other handlers.
|
||||
|
||||
How it works?
|
||||
-------------
|
||||
|
||||
|
|
|
|||
125
docs/dispatcher/webhook.rst
Normal file
125
docs/dispatcher/webhook.rst
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
.. _webhook:
|
||||
|
||||
#######
|
||||
Webhook
|
||||
#######
|
||||
|
||||
Telegram Bot API supports webhook.
|
||||
If you set webhook for your bot, Telegram will send updates to the specified url.
|
||||
You can use :meth:`aiogram.methods.set_webhook.SetWebhook` method to specify a url
|
||||
and receive incoming updates on it.
|
||||
|
||||
.. note::
|
||||
|
||||
If you use webhook, you can't use long polling at the same time.
|
||||
|
||||
Before start i'll recommend you to read `official Telegram's documentation about webhook <https://core.telegram.org/bots/webhooks>`_
|
||||
|
||||
After you read it, you can start to read this section.
|
||||
|
||||
Generally to use webhook with aiogram you should use any async web framework.
|
||||
By out of the box aiogram has an aiohttp integration, so we'll use it.
|
||||
|
||||
.. note::
|
||||
|
||||
You can use any async web framework you want, but you should write your own integration if you don't use aiohttp.
|
||||
|
||||
|
||||
aiohttp integration
|
||||
===================
|
||||
|
||||
Out of the box aiogram has aiohttp integration, so you can use it.
|
||||
|
||||
Here is available few ways to do it using different implementations of the webhook controller:
|
||||
|
||||
- :class:`aiogram.webhook.aiohttp_server.BaseRequestHandler` - Abstract class for aiohttp webhook controller
|
||||
- :class:`aiogram.webhook.aiohttp_server.SimpleRequestHandler` - Simple webhook controller, uses single Bot instance
|
||||
- :class:`aiogram.webhook.aiohttp_server.TokenBasedRequestHandler` - Token based webhook controller, uses multiple Bot instances and tokens
|
||||
|
||||
You can use it as is or inherit from it and override some methods.
|
||||
|
||||
.. autoclass:: aiogram.webhook.aiohttp_server.BaseRequestHandler
|
||||
:members: __init__, register, close, resolve_bot, verify_secret, handle
|
||||
|
||||
.. autoclass:: aiogram.webhook.aiohttp_server.SimpleRequestHandler
|
||||
:members: __init__, register, close, resolve_bot, verify_secret, handle
|
||||
|
||||
.. autoclass:: aiogram.webhook.aiohttp_server.TokenBasedRequestHandler
|
||||
:members: __init__, register, close, resolve_bot, verify_secret, handle
|
||||
|
||||
Security
|
||||
--------
|
||||
|
||||
Telegram supports two methods to verify incoming requests that they are from Telegram:
|
||||
|
||||
Using a secret token
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When you set webhook, you can specify a secret token and then use it to verify incoming requests.
|
||||
|
||||
Using IP filtering
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can specify a list of IP addresses from which you expect incoming requests, and then use it to verify incoming requests.
|
||||
|
||||
It can be acy using firewall rules or nginx configuration or middleware on application level.
|
||||
|
||||
So, aiogram has an implementation of the IP filtering middleware for aiohttp.
|
||||
|
||||
.. autofunction:: aiogram.webhook.aiohttp_server.ip_filter_middleware
|
||||
|
||||
.. autoclass:: aiogram.webhook.security.IPFilter
|
||||
:members: __init__, allow, allow_ip, default, check
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Behind reverse proxy
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In this example we'll use aiohttp as web framework and nginx as reverse proxy.
|
||||
|
||||
.. literalinclude:: ../../examples/echo_bot_webhook.py
|
||||
|
||||
When you use nginx as reverse proxy, you should set `proxy_pass` to your aiohttp server address.
|
||||
|
||||
.. code-block:: nginx
|
||||
|
||||
location /webhook {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
}
|
||||
|
||||
|
||||
Without reverse proxy (not recommended)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In case without using reverse proxy, you can use aiohttp's ssl context.
|
||||
|
||||
Also this example contains usage with self-signed certificate.
|
||||
|
||||
.. literalinclude:: ../../examples/echo_bot_webhook_ssl.py
|
||||
|
||||
|
||||
With using other web framework
|
||||
==============================
|
||||
|
||||
You can pass incoming request to aiogram's webhook controller from any web framework you want.
|
||||
|
||||
Read more about it in :meth:`aiogram.dispatcher.dispatcher.Dispatcher.feed_webhook_update`
|
||||
or :meth:`aiogram.dispatcher.dispatcher.Dispatcher.feed_update` methods.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
update = Update.model_validate(await request.json(), context={"bot": bot})
|
||||
await dispatcher.feed_update(update)
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
If you want to use reply into webhook, you should check that result of the :code:`feed_update`
|
||||
methods is an instance of API method and build :code:`multipart/form-data`
|
||||
or :code:`application/json` response body manually.
|
||||
Loading…
Add table
Add a link
Reference in a new issue