first
This commit is contained in:
93
handlers/scheduler.py
Normal file
93
handlers/scheduler.py
Normal file
@ -0,0 +1,93 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user