-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbot.py
132 lines (100 loc) · 4.32 KB
/
bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import ssl
from aiogram import Bot, Dispatcher
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.contrib.fsm_storage.redis import RedisStorage2
from aiogram.dispatcher.storage import BaseStorage
from aiogram.types import AllowedUpdates
from aiogram.utils import executor
from loguru import logger
from tgbot.config import load_config, Config
from tgbot import filters
from tgbot import handlers
from tgbot import middlewares
from tgbot.misc import logging
from tgbot.models import db
from tgbot.models.user_tg import UserTG
from tgbot.services.broadcasting import send_to_admins
from tgbot.services.setting_commands import set_bot_command
def setup_logging(config: Config) -> None:
logging.setup(config.log.file_name, config.log.rotation, config.log.retention)
def get_aiogram_storage(config: Config) -> BaseStorage:
if config.tg_bot.use_redis:
return RedisStorage2(host=config.redis.host,
port=config.redis.port,
password=config.redis.password,
pool_size=config.redis.pool_size)
return MemoryStorage()
def setup_dispatcher(config: Config, storage: BaseStorage | None) -> Dispatcher:
bot = Bot(token=config.tg_bot.token, parse_mode='HTML')
bot['config'] = config
dp = Dispatcher(bot, storage=storage)
return dp
async def setup_storages(config: Config, bot: Bot) -> None:
logger.info("Setting up storages...")
await db.on_startup(config.db.uri)
UserTG.bot = bot
async def register_middlewares_filters_handlers(dp: Dispatcher, config: Config) -> None:
logger.info("Registering middlewares, filters, handlers, dialogs...")
await middlewares.register(dp, config)
filters.register(dp)
handlers.register(dp)
async def setup_webhook(bot: Bot, config: Config) -> None:
ssl_cert = open(config.tg_bot.ssl.cert_file_path, 'rb').read()
logger.info(f"Set webhook on {config.tg_bot.webhook.url}")
await bot.set_webhook(
url=config.tg_bot.webhook.url,
certificate=ssl_cert
)
async def on_startup(dp: Dispatcher) -> None:
config: Config = dp.bot["config"]
await setup_storages(config, dp.bot)
await send_to_admins(dp.bot, "🟡 Бот запускается")
if config.tg_bot.use_webhook:
await setup_webhook(dp.bot, config)
await register_middlewares_filters_handlers(dp, config)
await set_bot_command(dp.bot, config)
await send_to_admins(dp.bot, "🟢 Бот запущен")
async def on_shutdown(dp: Dispatcher) -> None:
await send_to_admins(dp.bot, "🔴 Бот остановлен")
await dp.storage.close()
await dp.storage.wait_closed()
await (await dp.bot.get_session()).close()
await db.on_shutdown()
await dp.bot.delete_webhook()
def main() -> None:
config = load_config(".env")
setup_logging(config)
logger.info("Starting bot")
aiogram_storage = get_aiogram_storage(config)
dp = setup_dispatcher(config, aiogram_storage)
if config.tg_bot.use_webhook:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(config.tg_bot.ssl.cert_file_path,
config.tg_bot.ssl.key_file_path)
logger.info(f"Start webhook on webhook_path={config.tg_bot.webhook.path}, "
f"host={config.tg_bot.web_server.host}, port={config.tg_bot.web_server.port}")
executor.start_webhook(
dispatcher=dp,
webhook_path=config.tg_bot.webhook.path,
host=config.tg_bot.web_server.host,
port=config.tg_bot.web_server.port,
ssl_context=ssl_context,
on_startup=on_startup,
on_shutdown=on_shutdown,
skip_updates=config.tg_bot.skip_updates,
)
else:
executor.start_polling(dp,
on_startup=on_startup,
on_shutdown=on_shutdown,
allowed_updates=[
AllowedUpdates.MESSAGE,
AllowedUpdates.CALLBACK_QUERY,
AllowedUpdates.MY_CHAT_MEMBER
])
if __name__ == '__main__':
try:
main()
except (KeyboardInterrupt, SystemExit):
logger.info("Bot stopped!")
raise SystemExit(0)