diff --git a/database.py b/database.py
index b50d1896..07c87fa9 100644
--- a/database.py
+++ b/database.py
@@ -52,6 +52,13 @@ async def init_db():
''')
except asyncpg.exceptions.DuplicateColumnError:
pass
+ try:
+ await conn.execute('''
+ ALTER TABLE keys
+ ADD COLUMN notified_24h BOOLEAN NOT NULL DEFAULT FALSE
+ ''')
+ except asyncpg.exceptions.DuplicateColumnError:
+ pass
await conn.close()
diff --git a/handlers/__pycache__/notifications.cpython-310.pyc b/handlers/__pycache__/notifications.cpython-310.pyc
index f211f260..89fe99c3 100644
Binary files a/handlers/__pycache__/notifications.cpython-310.pyc and b/handlers/__pycache__/notifications.cpython-310.pyc differ
diff --git a/handlers/notifications.py b/handlers/notifications.py
index 8d829a29..c2257ced 100644
--- a/handlers/notifications.py
+++ b/handlers/notifications.py
@@ -1,11 +1,9 @@
from datetime import datetime, timedelta
-
import asyncpg
from aiogram import Bot, Router, types
from aiogram.filters import Command
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
-
from auth import login_with_credentials
from bot import bot
from client import delete_client, extend_client_key
@@ -21,57 +19,37 @@ async def notify_expiring_keys(bot: Bot):
try:
conn = await asyncpg.connect(DATABASE_URL)
try:
- # Напоминание за 10 часов
- threshold_time_10h = (datetime.utcnow() + timedelta(hours=10)).timestamp() * 1000
- records_10h = await conn.fetch('''
+ current_time = datetime.utcnow().timestamp() * 1000
+ threshold_time_10h = (datetime.utcnow() + timedelta(hours=10)).timestamp() * 1000
+ threshold_time_24h = (datetime.utcnow() + timedelta(days=1)).timestamp() * 1000
+
+ # Уведомления за 10 часов
+ records = await conn.fetch('''
SELECT tg_id, email, expiry_time, client_id, server_id FROM keys
WHERE expiry_time <= $1 AND expiry_time > $2 AND notified = FALSE
- ''', threshold_time_10h, datetime.utcnow().timestamp() * 1000)
+ ''', threshold_time_10h, current_time)
- for record in records_10h:
+ for record in records:
tg_id = record['tg_id']
email = record['email']
expiry_time = record['expiry_time']
server_id = record['server_id']
- time_left = (expiry_time / 1000) - datetime.utcnow().timestamp()
- hours_left = max(0, int(time_left // 3600))
+ # Логика формирования и отправки сообщения для уведомлений за 10 часов
+ message = f"🔔 Уведомление: Ваш ключ для сервера {server_id} истекает через 10 часов.\n" \
+ f"Email: {email}\n" \
+ f"Дата истечения: {datetime.utcfromtimestamp(expiry_time / 1000).strftime('%Y-%m-%d %H:%M:%S')}"
+
+ await bot.send_message(tg_id, message)
- expiry_date = datetime.utcfromtimestamp(expiry_time / 1000).strftime('%Y-%m-%d %H:%M:%S')
- balance = await get_balance(tg_id)
+ # Обновление статуса уведомления
+ await conn.execute('UPDATE keys SET notified = TRUE WHERE client_id = $1', record['client_id'])
- keyboard = InlineKeyboardMarkup(inline_keyboard=[
- [
- InlineKeyboardButton(text='1 месяц (100 руб.)', callback_data=f'renew_plan|1|{record["client_id"]}'),
- InlineKeyboardButton(text='3 месяца (285 руб.)', callback_data=f'renew_plan|3|{record["client_id"]}')
- ],
- [
- InlineKeyboardButton(text='6 месяцев (540 руб.)', callback_data=f'renew_plan|6|{record["client_id"]}'),
- InlineKeyboardButton(text='1 год (1000 руб.)', callback_data=f'renew_plan|12|{record["client_id"]}')
- ],
- [
- InlineKeyboardButton(text='Пополнить баланс', callback_data='replenish_balance'),
- InlineKeyboardButton(text='Назад', callback_data='back_to_main')
- ]
- ])
-
- message = (f"Ваш ключ {email} истечет и будет удален через {hours_left} часов "
- f"({expiry_date}). Пожалуйста, продлите его.\n"
- f"Ваш текущий баланс: {balance:.2f} руб.")
-
- try:
- await bot.send_message(chat_id=tg_id, text=message, parse_mode='HTML', reply_markup=keyboard)
-
- await conn.execute('UPDATE keys SET notified = TRUE WHERE client_id = $1', record['client_id'])
- except Exception as e:
- print(f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя.")
-
- # Напоминание за 24 часа
- threshold_time_24h = (datetime.utcnow() + timedelta(days=1)).timestamp() * 1000
+ # Уведомления за 24 часа
records_24h = await conn.fetch('''
SELECT tg_id, email, expiry_time, client_id, server_id FROM keys
WHERE expiry_time <= $1 AND expiry_time > $2 AND notified_24h = FALSE
- ''', threshold_time_24h, datetime.utcnow().timestamp() * 1000)
+ ''', threshold_time_24h, current_time)
for record in records_24h:
tg_id = record['tg_id']
@@ -83,86 +61,19 @@ async def notify_expiring_keys(bot: Bot):
hours_left = max(0, int(time_left // 3600))
expiry_date = datetime.utcfromtimestamp(expiry_time / 1000).strftime('%Y-%m-%d %H:%M:%S')
- balance = await get_balance(tg_id)
-
- keyboard = InlineKeyboardMarkup(inline_keyboard=[
- [
- InlineKeyboardButton(text='1 месяц (100 руб.)', callback_data=f'renew_plan|1|{record["client_id"]}'),
- InlineKeyboardButton(text='3 месяца (285 руб.)', callback_data=f'renew_plan|3|{record["client_id"]}')
- ],
- [
- InlineKeyboardButton(text='6 месяцев (540 руб.)', callback_data=f'renew_plan|6|{record["client_id"]}'),
- InlineKeyboardButton(text='1 год (1000 руб.)', callback_data=f'renew_plan|12|{record["client_id"]}')
- ],
- [
- InlineKeyboardButton(text='Пополнить баланс', callback_data='replenish_balance'),
- InlineKeyboardButton(text='Назад', callback_data='back_to_main')
- ]
- ])
-
- message = (f"Ваш ключ {email} истечет через {hours_left} часов "
- f"({expiry_date}). Пожалуйста, продлите его.\n"
- f"Ваш текущий баланс: {balance:.2f} руб.")
-
- try:
- await bot.send_message(chat_id=tg_id, text=message, parse_mode='HTML', reply_markup=keyboard)
-
- await conn.execute('UPDATE keys SET notified_24h = TRUE WHERE client_id = $1', record['client_id'])
- except Exception as e:
- print(f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя.")
-
- # Обработка истекших ключей
- expired_records = await conn.fetch('''
- SELECT tg_id, email, client_id, server_id FROM keys
- WHERE expiry_time <= $1
- ''', datetime.utcnow().timestamp() * 1000)
-
- for record in expired_records:
- tg_id = record['tg_id']
- email = record['email']
- client_id = record['client_id']
- server_id = record['server_id']
-
balance = await get_balance(tg_id)
- if balance >= 100:
- # Продлеваем ключ на 1 месяц и списываем 100 рублей
- new_expiry_time = datetime.utcnow() + timedelta(days=30)
- await conn.execute('''
- UPDATE keys SET expiry_time = $1 WHERE client_id = $2
- ''', new_expiry_time.timestamp() * 1000, client_id)
+ # Логика формирования и отправки сообщения для уведомлений за 24 часа
+ message_24h = f"⏳ Уведомление: Ваш ключ для сервера {server_id} истекает через 24 часа.\n" \
+ f"Email: {email}\n" \
+ f"Осталось времени: {hours_left} часов\n" \
+ f"Дата истечения: {expiry_date}\n" \
+ f"Баланс: {balance:.2f} руб."
- # Списываем 100 рублей с баланса
- await update_balance(tg_id, -100)
+ await bot.send_message(tg_id, message_24h)
- session = await login_with_credentials(server_id, ADMIN_USERNAME, ADMIN_PASSWORD)
- await extend_client_key(session, server_id, client_id, 30)
-
- message = (f"Ваш ключ {email} был автоматически продлен на 1 месяц, так как у вас на балансе было достаточно средств. "
- f"Новый срок истечения: {new_expiry_time.strftime('%Y-%m-%d %H:%M:%S')}.\n"
- f"Ваш новый баланс: {balance - 100:.2f} руб.")
-
- try:
- await bot.send_message(chat_id=tg_id, text=message, parse_mode='HTML')
- except Exception as e:
- print(f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя.")
- else:
- # Удаляем ключ, если баланс недостаточный
- await conn.execute('DELETE FROM keys WHERE client_id = $1', client_id)
-
- session = await login_with_credentials(server_id, ADMIN_USERNAME, ADMIN_PASSWORD)
- await delete_client(session, server_id, client_id)
-
- keyboard = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text='В профиль', callback_data='view_profile')]
- ])
-
- message = f"Ваш ключ {email} истек, и был удален."
-
- try:
- await bot.send_message(chat_id=tg_id, text=message, parse_mode='HTML', reply_markup=keyboard)
- except Exception as e:
- print(f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя.")
+ # Обновление статуса уведомления за 24 часа
+ await conn.execute('UPDATE keys SET notified_24h = TRUE WHERE client_id = $1', record['client_id'])
finally:
await conn.close()