Webhook integration in 3.0 (#737)

* Added base webhook implementation and example
* Added example
* Enable on_startup callback
* Correctly handle response into webhook (silent call)
* Fixed State filter
This commit is contained in:
Alex Root Junior 2021-11-08 23:20:12 +02:00 committed by GitHub
parent e0ab7d8bd3
commit 1c2c7fd88c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 865 additions and 246 deletions

83
examples/multibot.py Normal file
View file

@ -0,0 +1,83 @@
from os import getenv
from typing import Any, Dict, Union
from aiohttp import web
from finite_state_machine import form_router
from aiogram import Bot, Dispatcher, F, Router
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.dispatcher.filters import Command, CommandObject
from aiogram.dispatcher.fsm.storage.redis import DefaultKeyBuilder, RedisStorage
from aiogram.dispatcher.webhook.aiohttp_server import (
SimpleRequestHandler,
TokenBasedRequestHandler,
setup_application,
)
from aiogram.exceptions import TelegramUnauthorizedError
from aiogram.types import Message
from aiogram.utils.token import TokenValidationError, validate_token
main_router = Router()
BASE_URL = getenv("BASE_URL", "https://example.com")
MAIN_BOT_TOKEN = getenv("TELEGRAM_TOKEN")
WEB_SERVER_HOST = "127.0.0.1"
WEB_SERVER_PORT = 8080
MAIN_BOT_PATH = "/webhook/main"
OTHER_BOTS_PATH = "/webhook/bot/{bot_token}"
REDIS_DSN = "redis://127.0.0.1:6479"
def is_bot_token(value: str) -> Union[bool, Dict[str, Any]]:
try:
validate_token(value)
except TokenValidationError:
return False
return True
@main_router.message(Command(commands=["add"], command_magic=F.args.func(is_bot_token)))
async def command_add_bot(message: Message, command: CommandObject, bot: Bot):
new_bot = Bot(token=command.args, session=bot.session)
try:
bot_user = await new_bot.get_me()
except TelegramUnauthorizedError:
return message.answer("Invalid token")
await new_bot.delete_webhook(drop_pending_updates=True)
await new_bot.set_webhook(f"{BASE_URL}{OTHER_BOTS_PATH}")
await message.answer(f"Bot @{bot_user.username} successful added")
async def on_startup(dispatcher: Dispatcher, bot: Bot):
await bot.set_webhook(f"{BASE_URL}{MAIN_BOT_PATH}")
def main():
session = AiohttpSession()
bot_settings = {"session": session, "parse_mode": "HTML"}
bot = Bot(token=MAIN_BOT_TOKEN, **bot_settings)
storage = RedisStorage.from_url(REDIS_DSN, key_builder=DefaultKeyBuilder(with_bot_id=True))
main_dispatcher = Dispatcher(storage=storage)
main_dispatcher.include_router(main_router)
main_dispatcher.startup.register(on_startup)
multibot_dispatcher = Dispatcher(storage=storage)
multibot_dispatcher.include_router(form_router)
app = web.Application()
SimpleRequestHandler(dispatcher=main_dispatcher, bot=bot).register(app, path=MAIN_BOT_PATH)
TokenBasedRequestHandler(
dispatcher=multibot_dispatcher,
bot_settings=bot_settings,
).register(app, path=OTHER_BOTS_PATH)
setup_application(app, main_dispatcher, bot=bot)
setup_application(app, multibot_dispatcher)
web.run_app(app, host=WEB_SERVER_HOST, port=WEB_SERVER_PORT)
if __name__ == "__main__":
main()