Files
bdbot/handlers/scheduler.py
2026-01-28 11:30:30 +03:00

94 lines
3.3 KiB
Python

"""Scheduler for daily birthday notifications."""
import telebot
from datetime import datetime
from typing import Optional
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
import pytz
from database import get_db_session, User, Chat, UserChat
from messages import format_birthday_greeting
from config import Config
def send_birthday_notifications(bot: telebot.TeleBot) -> None:
"""Send birthday notifications to all chats for users with birthday today."""
db = get_db_session()
try:
today = datetime.now().date()
day = today.day
month = today.month
# Get all users with birthday today
users_with_birthday = db.query(User).filter(
User.birthday_day == day,
User.birthday_month == month
).all()
if not users_with_birthday:
return
# For each user, send greetings to all their chats
for user in users_with_birthday:
# Get all chats where user is a member
user_chats = db.query(Chat).join(UserChat).filter(
UserChat.user_id == user.user_id,
Chat.bot_is_admin == True
).all()
greeting = format_birthday_greeting(user.first_name, user.preference_theme)
for chat in user_chats:
try:
# Check if user is still in chat
member = bot.get_chat_member(chat.chat_id, user.user_id)
if member.status not in ['left', 'kicked']:
bot.send_message(chat.chat_id, greeting)
except telebot.apihelper.ApiTelegramException as e:
# Handle errors: user blocked bot, bot removed from chat, etc.
if e.error_code == 403:
# Bot was blocked or removed from chat
# Update chat status
chat.bot_is_admin = False
db.commit()
elif e.error_code == 400:
# Invalid chat or user
pass
# Silently continue for other errors
except Exception:
# Other errors - continue
pass
finally:
db.close()
def setup_scheduler(bot: telebot.TeleBot) -> BlockingScheduler:
"""Setup and start the scheduler for daily birthday notifications."""
# Parse notification time
time_str: str = Config.NOTIFICATION_TIME
try:
hour, minute = map(int, time_str.split(':'))
except (ValueError, AttributeError):
hour, minute = 9, 0 # Default to 9:00
# Get timezone
timezone_str: str = Config.TIMEZONE
try:
tz = pytz.timezone(timezone_str)
except (pytz.exceptions.UnknownTimeZoneError, AttributeError):
tz = pytz.UTC
# Create scheduler
scheduler = BlockingScheduler(timezone=tz)
# Add daily job
scheduler.add_job(
send_birthday_notifications,
trigger=CronTrigger(hour=hour, minute=minute),
args=[bot],
id='daily_birthday_notifications',
name='Send daily birthday notifications',
replace_existing=True
)
return scheduler