Bot & Automation
Activity Reminder Bot
/root/hermes-projects/Activity Reminder Bot
apps/activity_reminder_bot/scheduler/reminder_scheduler.py
text
import logging
from aiogram import Bot
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from activity_reminder_bot.bot.keyboards import alarm_action_keyboard
from activity_reminder_bot.core.config import get_settings
from activity_reminder_bot.services.formatters import format_alarm
from activity_reminder_bot.services.reminders import ReminderService
logger = logging.getLogger(__name__)
class ReminderScheduler:
def __init__(self, bot: Bot, service: ReminderService | None = None) -> None:
self.bot = bot
self.service = service or ReminderService()
self.settings = get_settings()
self.scheduler = AsyncIOScheduler(timezone=self.settings.timezone)
async def start(self) -> None:
self.scheduler.add_job(
self.scan_due_reminders,
trigger="interval",
seconds=self.settings.scheduler_scan_seconds,
id="scan_due_reminders",
replace_existing=True,
max_instances=1,
coalesce=True,
)
self.scheduler.start()
logger.info("Reminder scheduler started")
async def shutdown(self) -> None:
self.scheduler.shutdown(wait=False)
async def scan_due_reminders(self) -> None:
if not self.service.is_configured():
logger.warning("Google Sheets is not configured; scheduler scan skipped")
return
due_reminders = await self.service.due_reminders()
now = self.service.now()
for reminder in due_reminders:
try:
sent_message = await self.bot.send_message(
chat_id=reminder.user_id,
text=format_alarm(reminder, now),
reply_markup=alarm_action_keyboard(reminder.public_id),
disable_notification=False,
)
if (
self.settings.alarm_delete_previous_message
and reminder.alarm_message_id
and reminder.alarm_message_id != sent_message.message_id
):
try:
await self.bot.delete_message(
chat_id=reminder.user_id,
message_id=reminder.alarm_message_id,
)
except Exception as exc:
logger.warning(
"Failed to delete previous alarm message %s for reminder %s: %s",
reminder.alarm_message_id,
reminder.public_id,
exc,
)
await self.service.mark_notified(reminder, sent_message.message_id)
except Exception as exc:
logger.exception("Failed to send reminder %s: %s", reminder.public_id, exc)