from __future__ import annotations import asyncio import logging from aiogram import Bot, Dispatcher, Router from aiogram.types import CallbackQuery from aiogram.client.session.aiohttp import AiohttpSession from apscheduler.schedulers.asyncio import AsyncIOScheduler from app.config import load_settings from app.service import OfferProcessingService from app.sources import KworkSource from app.state import SentOffersStore from app.telegram import TelegramPublisher logging.basicConfig( level=logging.DEBUG, format="%(asctime)s | %(levelname)s | %(name)s | %(message)s", ) logger = logging.getLogger(__name__) def build_dispatcher() -> Dispatcher: router = Router() @router.callback_query(lambda callback: callback.data == "delete_post") async def delete_post_callback(callback: CallbackQuery) -> None: if callback.message is None: await callback.answer() return try: await callback.message.delete() logger.info( "Deleted Telegram message chat_id=%s message_id=%s by user_id=%s", callback.message.chat.id, callback.message.message_id, callback.from_user.id, ) await callback.answer("Пост удален") except Exception: logger.exception( "Failed to delete Telegram message chat_id=%s message_id=%s", callback.message.chat.id, callback.message.message_id, ) await callback.answer("Не удалось удалить пост", show_alert=True) dispatcher = Dispatcher() dispatcher.include_router(router) return dispatcher async def main() -> None: settings = load_settings() dispatcher = build_dispatcher() session = AiohttpSession(proxy=settings.telegram_proxy_url) if settings.telegram_proxy_url else None bot = Bot(token=settings.telegram_bot_token, session=session) publisher = TelegramPublisher(bot=bot, channel_id=settings.telegram_channel_id) store = SentOffersStore(settings.state_file) service = OfferProcessingService( sources=[ KworkSource( category_ids=settings.kwork_category_ids, timeout_seconds=settings.requests_timeout_seconds, ) ], publisher=publisher, sent_offers_store=store, include_keywords=settings.keywords_include, exclude_keywords=settings.keywords_exclude, min_price_amount=settings.min_price_amount, ) scheduler = AsyncIOScheduler() scheduler.add_job(service.run_once, "interval", minutes=settings.scheduler_interval_minutes) scheduler.start() await service.run_once() try: await dispatcher.start_polling(bot) finally: scheduler.shutdown() await bot.session.close() if __name__ == "__main__": asyncio.run(main())