import asyncio import logging from aiogram import Bot, Dispatcher, F, Router from aiogram.enums import ParseMode from aiogram.filters import Filter from aiogram.types import LinkPreviewOptions, Message from bot.config import Config, load_config logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s", ) logger = logging.getLogger(__name__) class FromLinkedChannel(Filter): """Match messages that Telegram auto-forwards from a linked channel.""" async def __call__(self, message: Message) -> bool: return bool(message.is_automatic_forward) def create_dispatcher(config: Config) -> Dispatcher: dp = Dispatcher() router = Router() @router.message(F.chat.id == config.discussion_chat_id, FromLinkedChannel()) async def on_channel_post(message: Message) -> None: await asyncio.sleep(5) try: await message.reply( config.comment_text, parse_mode=ParseMode.HTML, link_preview_options=LinkPreviewOptions(is_disabled=True), disable_notification=True, ) except Exception: logger.exception( "Failed to reply to channel post message_id=%s in chat_id=%s", message.message_id, message.chat.id, ) return logger.info( "Replied to channel post message_id=%s in chat_id=%s", message.message_id, message.chat.id, ) dp.include_router(router) return dp async def main() -> None: config = load_config() bot = Bot(token=config.bot_token) dp = create_dispatcher(config) try: me = await bot.get_me() logger.info( "Starting bot @%s; watching discussion chat %s", me.username, config.discussion_chat_id, ) await dp.start_polling(bot) finally: await bot.session.close() if __name__ == "__main__": asyncio.run(main())