Advanced executor example

advanced_executor_example.py
  1#!/usr/bin/env python3
  2"""
  3**This example is outdated**
  4In this example used ArgumentParser for configuring Your bot.
  5
  6Provided to start bot with webhook:
  7    python advanced_executor_example.py \
  8        --token TOKEN_HERE \
  9        --host 0.0.0.0 \
 10        --port 8084 \
 11        --host-name example.com \
 12        --webhook-port 443
 13
 14Or long polling:
 15    python advanced_executor_example.py --token TOKEN_HERE
 16
 17So... In this example found small trouble:
 18    can't get bot instance in handlers.
 19
 20
 21If you want to automatic change getting updates method use executor utils (from aiogram.utils.executor)
 22"""
 23# TODO: Move token to environment variables.
 24
 25import argparse
 26import logging
 27import ssl
 28import sys
 29
 30from aiogram import Bot
 31from aiogram.dispatcher import Dispatcher
 32from aiogram.dispatcher.webhook import *
 33from aiogram.utils.executor import start_polling, start_webhook
 34
 35logging.basicConfig(level=logging.INFO)
 36
 37# Configure arguments parser.
 38parser = argparse.ArgumentParser(description='Python telegram bot')
 39parser.add_argument('--token', '-t', nargs='?', type=str, default=None, help='Set working directory')
 40parser.add_argument('--sock', help='UNIX Socket path')
 41parser.add_argument('--host', help='Webserver host')
 42parser.add_argument('--port', type=int, help='Webserver port')
 43parser.add_argument('--cert', help='Path to SSL certificate')
 44parser.add_argument('--pkey', help='Path to SSL private key')
 45parser.add_argument('--host-name', help='Set webhook host name')
 46parser.add_argument('--webhook-port', type=int, help='Port for webhook (default=port)')
 47parser.add_argument('--webhook-path', default='/webhook', help='Port for webhook (default=port)')
 48
 49
 50async def cmd_start(message: types.Message):
 51    return SendMessage(message.chat.id, f"Hello, {message.from_user.full_name}!")
 52
 53
 54def setup_handlers(dispatcher: Dispatcher):
 55    # This example has only one messages handler
 56    dispatcher.register_message_handler(cmd_start, commands=['start', 'welcome'])
 57
 58
 59async def on_startup(dispatcher, url=None, cert=None):
 60    setup_handlers(dispatcher)
 61
 62    bot = dispatcher.bot
 63
 64    # Get current webhook status
 65    webhook = await bot.get_webhook_info()
 66
 67    if url:
 68        # If URL is bad
 69        if webhook.url != url:
 70            # If URL doesnt match with by current remove webhook
 71            if not webhook.url:
 72                await bot.delete_webhook()
 73
 74            # Set new URL for webhook
 75            if cert:
 76                with open(cert, 'rb') as cert_file:
 77                    await bot.set_webhook(url, certificate=cert_file)
 78            else:
 79                await bot.set_webhook(url)
 80    elif webhook.url:
 81        # Otherwise remove webhook.
 82        await bot.delete_webhook()
 83
 84
 85async def on_shutdown(dispatcher):
 86    print('Shutdown.')
 87
 88
 89def main(arguments):
 90    args = parser.parse_args(arguments)
 91    token = args.token
 92    sock = args.sock
 93    host = args.host
 94    port = args.port
 95    cert = args.cert
 96    pkey = args.pkey
 97    host_name = args.host_name or host
 98    webhook_port = args.webhook_port or port
 99    webhook_path = args.webhook_path
100
101    # Fi webhook path
102    if not webhook_path.startswith('/'):
103        webhook_path = '/' + webhook_path
104
105    # Generate webhook URL
106    webhook_url = f"https://{host_name}:{webhook_port}{webhook_path}"
107
108    # Create bot & dispatcher instances.
109    bot = Bot(token)
110    dispatcher = Dispatcher(bot)
111
112    if (sock or host) and host_name:
113        if cert and pkey:
114            ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
115            ssl_context.load_cert_chain(cert, pkey)
116        else:
117            ssl_context = None
118
119        start_webhook(dispatcher, webhook_path,
120                      on_startup=functools.partial(on_startup, url=webhook_url, cert=cert),
121                      on_shutdown=on_shutdown,
122                      host=host, port=port, path=sock, ssl_context=ssl_context)
123    else:
124        start_polling(dispatcher, on_startup=on_startup, on_shutdown=on_shutdown)
125
126
127if __name__ == '__main__':
128    argv = sys.argv[1:]
129
130    if not len(argv):
131        parser.print_help()
132        sys.exit(1)
133
134    main(argv)