aiogram 3 da APScheduler bilan rejalashtirilgan eslatmalar
Production botlarda to‘lov eslatmalarini ishonchli yuborish uchun ishlatadigan yondashuvim — event loop’ni bloklamasdan.
Bu maqola hozircha faqat ingliz tilida mavjud.
Reminder bots are one of the most requested Telegram projects: payment reminders, appointment reminders, subscription renewals. Here's the approach I used in the Kindergarten Payment Bot.
The setup
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from aiogram import Bot, Dispatcher
bot = Bot(token=settings.BOT_TOKEN)
dp = Dispatcher()
scheduler = AsyncIOScheduler(timezone="Asia/Tashkent")
AsyncIOScheduler runs jobs inside the same event loop as aiogram, so jobs can await bot methods directly.
The job
async def send_payment_reminders():
debtors = await repo.get_parents_with_debt()
for parent in debtors:
try:
await bot.send_message(
parent.telegram_id,
f"Hello! The fee for {parent.child_name} is due. "
f"Amount: {parent.debt:,} UZS",
)
except TelegramForbiddenError:
await repo.mark_blocked(parent.id)
await asyncio.sleep(0.05) # stay under Telegram limits
Scheduling
scheduler.add_job(send_payment_reminders, "cron", day=1, hour=10)
scheduler.add_job(send_payment_reminders, "cron", day=10, hour=10)
async def main():
scheduler.start()
await dp.start_polling(bot)
Lessons learned
- Handle blocked users. People block bots — catch
TelegramForbiddenErrorand stop messaging them. - Respect rate limits. Telegram allows ~30 messages per second; a small sleep keeps you safe.
- Use the right timezone. Always set it explicitly on the scheduler.
- Make jobs idempotent. Store when a reminder was sent so a restart never sends duplicates.