import asyncio import logging import sys import signal # Import the signal module from aiogram import Bot, Dispatcher, Router from aiogram.enums import ParseMode from aiogram.filters import CommandStart from aiogram.types import Message, ChatJoinRequest, CallbackQuery, ChatMemberUpdated from aiogram.enums import ChatMemberStatus from config import BOT_TOKEN, FEEDBACK_CHAT_ID from handlers.routing import handle_routing from handlers.callback_unlink import handle_unlink from handlers.callback_vouch import handle_button from handlers.handle_join_request import handle_join_request from handlers.handle_startup import handle_startup from handlers.handle_members_change import handle_join, handle_left from state import State from storage import Profile logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) router = Router() bot = Bot(BOT_TOKEN, parse_mode=ParseMode.HTML) dp = Dispatcher() state = State() @router.message(CommandStart()) async def command_start_handler(message: Message) -> None: caption = "Напишите своё сообщение для нас" if message.from_user.llanguage_code == 'ru' else "Write your message for us" await message.answer(caption) @router.callback_query() async def process_callback(callback_query: CallbackQuery): cbq = vars(callback_query) try: cbq["from"] = vars(callback_query.from_user) cbq["message"] = vars(callback_query.message) data = cbq["data"] if data.startswith("vouch"): await handle_button(cbq) elif data.startswith("unlink"): await handle_unlink(cbq, state) except Exception as e: logger.error(f"[main.process_callback] ERROR {e}") logger.debug(cbq) import traceback text = traceback.format_exc() await bot.send_message(FEEDBACK_CHAT_ID, text) @router.chat_join_request() async def join_request_handler(update: ChatJoinRequest) -> None: print("chat join request") join_request = vars(update) try: join_request["from"] = vars(update.from_user) join_request["chat"] = vars(update.chat) await handle_join_request(join_request) except Exception as e: logger.error(f"[main.join_request_handler] ERROR {e}") logger.debug(join_request) import traceback text = traceback.format_exc() await bot.send_message(FEEDBACK_CHAT_ID, text) @router.message() async def all_handler(message: Message) -> None: msg = vars(message) try: msg["from"] = vars(message.from_user) msg["chat"] = vars(message.chat) if message.reply_to_message: msg["reply_to_message"] = vars(message.reply_to_message) await handle_routing(msg, state) await asyncio.sleep(1.0) except Exception as e: logger.error(f"[main.all_handler] ERROR {e}") logger.debug(msg) import traceback text = traceback.format_exc() await bot.send_message(FEEDBACK_CHAT_ID, text) @router.my_chat_member() async def chat_members_change(update: ChatMemberUpdated): msg = vars(update) try: msg["chat"] = vars(update.chat) msg["from"] = vars(update.from_user) old_member = vars(msg["old_chat_member"]) new_member = vars(msg["new_chat_member"]) if old_member: if old_member.status == ChatMemberStatus.KICKED: Profile.erase(msg["from"]["id"]) await handle_left(msg) elif new_member: await handle_join(msg) else: logger.info("unhandled members update") except Exception as e: logger.error(f"[main.my_chat_member] ERROR {e}") logger.debug(msg) import traceback text = traceback.format_exc() await bot.send_message(FEEDBACK_CHAT_ID, text) async def main() -> None: # connect router dp.include_router(router) # storage revalidation await handle_startup() # Start event dispatching await dp.start_polling(bot) if __name__ == "__main__": logging.basicConfig(level=logging.INFO, stream=sys.stdout) # Define a function to handle SIGTERM def handle_sigterm(signum, frame): logger.info("Received SIGTERM. Shutting down gracefully...") asyncio.get_event_loop().stop() # Register the SIGTERM signal handler signal.signal(signal.SIGTERM, handle_sigterm) asyncio.get_event_loop().run_until_complete(main())