""" This example shows how to use webhook on behind of any reverse proxy (nginx, traefik, ingress etc.) """ import logging from aiohttp import web from aiogram import Bot, Dispatcher, Router, types from aiogram.enums import ParseMode from aiogram.filters import Command from aiogram.types import Message from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application # Bot token can be obtained via https://t.me/BotFather TOKEN = "42:TOKEN" # Webserver settings # bind localhost only to prevent any external access WEB_SERVER_HOST = "127.0.0.1" # Port for incoming request from reverse proxy. Should be any available port WEB_SERVER_PORT = 8080 # Path to webhook route, on which Telegram will send requests WEBHOOK_PATH = "/webhook" # Secret key to validate requests from Telegram (optional) WEBHOOK_SECRET = "my-secret" # Base URL for webhook will be used to generate webhook URL for Telegram, # in this example it is used public DNS with HTTPS support BASE_WEBHOOK_URL = "https://aiogram.dev/" # All handlers should be attached to the Router (or Dispatcher) router = Router() @router.message(Command(commands=["start"])) async def command_start_handler(message: Message) -> None: """ This handler receives messages with `/start` command """ # Most event objects have aliases for API methods that can be called in events' context # For example if you want to answer to incoming message you can use `message.answer(...)` alias # and the target chat will be passed to :ref:`aiogram.methods.send_message.SendMessage` # method automatically or call API method directly via # Bot instance: `bot.send_message(chat_id=message.chat.id, ...)` await message.answer(f"Hello, {message.from_user.full_name}!") @router.message() async def echo_handler(message: types.Message) -> None: """ Handler will forward receive a message back to the sender By default, message handler will handle all message types (like text, photo, sticker etc.) """ try: # Send a copy of the received message await message.send_copy(chat_id=message.chat.id) except TypeError: # But not all the types is supported to be copied so need to handle it await message.answer("Nice try!") async def on_startup(bot: Bot) -> None: # If you have a self-signed SSL certificate, then you will need to send a public # certificate to Telegram await bot.set_webhook(f"{BASE_WEBHOOK_URL}{WEBHOOK_PATH}") def main() -> None: # Dispatcher is a root router dp = Dispatcher() # ... and all other routers should be attached to Dispatcher dp.include_router(router) # Register startup hook to initialize webhook dp.startup.register(on_startup) # Initialize Bot instance with a default parse mode which will be passed to all API calls bot = Bot(TOKEN, parse_mode=ParseMode.HTML) # Create aiohttp.web.Application instance app = web.Application() # Create an instance of request handler, # aiogram has few implementations for different cases of usage # In this example we use SimpleRequestHandler which is designed to handle simple cases webhook_requests_handler = SimpleRequestHandler( dispatcher=dp, bot=bot, secret_token=WEBHOOK_SECRET, ) # Register webhook handler on application webhook_requests_handler.register(app, path=WEBHOOK_PATH) # Mount dispatcher startup and shutdown hooks to aiohttp application setup_application(app, dp, bot=bot) # And finally start webserver web.run_app(app, host=WEB_SERVER_HOST, port=WEB_SERVER_PORT) if __name__ == "__main__": logging.basicConfig(level=logging.INFO) main()