Merge pull request #23 from Vladless/youkassa
новостные сообщения, поправленный requirements
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
from aiogram import Bot, Dispatcher, Router
|
||||
from aiogram.fsm.storage.memory import MemoryStorage
|
||||
|
||||
from auth import login_with_credentials
|
||||
from config import API_TOKEN
|
||||
|
||||
bot = Bot(token=API_TOKEN)
|
||||
@@ -10,7 +9,6 @@ dp = Dispatcher(bot=bot, storage=storage)
|
||||
router = Router()
|
||||
|
||||
from handlers import key_management, keys, notifications, pay, profile, start
|
||||
from handlers.key_management import router as key_management_router
|
||||
|
||||
# Регистрация обработчиков
|
||||
dp.include_router(start.router)
|
||||
|
||||
@@ -19,6 +19,7 @@ from database import (add_connection, get_balance, has_active_key, store_key,
|
||||
from handlers.instructions import send_instructions
|
||||
from handlers.profile import process_callback_view_profile
|
||||
from handlers.start import start_command
|
||||
from handlers.notifications import send_message_to_all_clients
|
||||
|
||||
router = Router()
|
||||
|
||||
@@ -113,6 +114,10 @@ async def handle_text(message: Message, state: FSMContext):
|
||||
await start_command(message)
|
||||
return
|
||||
|
||||
if message.text in ["/send_to_all"]:
|
||||
await send_message_to_all_clients(message)
|
||||
return
|
||||
|
||||
if current_state == Form.waiting_for_key_name.state:
|
||||
await handle_key_name_input(message, state)
|
||||
|
||||
|
||||
+49
-10
@@ -1,13 +1,13 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import asyncpg
|
||||
from aiogram import Bot, Router
|
||||
from aiogram import Bot, Router, types
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
from aiogram.types import ( # Импортируем необходимые классы
|
||||
InlineKeyboardButton, InlineKeyboardMarkup)
|
||||
|
||||
from bot import bot
|
||||
from config import DATABASE_URL, ADMIN_PASSWORD, ADMIN_USERNAME
|
||||
from config import DATABASE_URL, ADMIN_PASSWORD, ADMIN_USERNAME, ADMIN_ID
|
||||
from client import delete_client
|
||||
from auth import login_with_credentials
|
||||
|
||||
@@ -41,12 +41,16 @@ async def notify_expiring_keys(bot: Bot):
|
||||
# Создаем клавиатуру с выбором тарифов
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text='1 месяц (100 руб.)', callback_data=f'renew_plan|1|{record["client_id"]}')],
|
||||
[InlineKeyboardButton(text='3 месяца (250 руб.)', callback_data=f'renew_plan|3|{record["client_id"]}')],
|
||||
[InlineKeyboardButton(text='3 месяца (285 руб.)', callback_data=f'renew_plan|3|{record["client_id"]}')],
|
||||
[InlineKeyboardButton(text='Пополнить баланс', callback_data='replenish_balance')]
|
||||
])
|
||||
|
||||
message = f"Ваш ключ <b>{email}</b> истечет через <b>{hours_left} часов</b> (<b>{expiry_date}</b>). Пожалуйста, продлите его."
|
||||
await bot.send_message(chat_id=tg_id, text=message, parse_mode='HTML', reply_markup=keyboard)
|
||||
message = f"Ваш ключ <b>{email}</b> истечет и будет удален через <b>{hours_left} часов</b> (<b>{expiry_date}</b>). Пожалуйста, продлите его."
|
||||
|
||||
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}. Пропускаем этого пользователя.")
|
||||
|
||||
# Обрабатываем истекшие ключи
|
||||
expired_records = await conn.fetch('''
|
||||
@@ -68,16 +72,51 @@ async def notify_expiring_keys(bot: Bot):
|
||||
# Удаляем клиента из панели
|
||||
delete_client(session, client_id)
|
||||
|
||||
# Создаем клавиатуру с кнопкой "В профиль"
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text='1 месяц (100 руб.)', callback_data=f'renew_plan|1|{client_id}')],
|
||||
[InlineKeyboardButton(text='3 месяца (250 руб.)', callback_data=f'renew_plan|3|{client_id}')],
|
||||
[InlineKeyboardButton(text='Пополнить баланс', callback_data='replenish_balance')]
|
||||
[InlineKeyboardButton(text='В профиль', callback_data='view_profile')]
|
||||
])
|
||||
|
||||
message = f"Ваш ключ <b>{email}</b> уже истек и был удален. Пожалуйста, продлите его."
|
||||
await bot.send_message(chat_id=tg_id, text=message, parse_mode='HTML', reply_markup=keyboard)
|
||||
message = f"Ваш ключ <b>{email}</b> истек и был удален автоматически."
|
||||
|
||||
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}. Пропускаем этого пользователя.")
|
||||
|
||||
finally:
|
||||
await conn.close()
|
||||
except Exception as e:
|
||||
print(f"Ошибка при отправке уведомлений: {e}")
|
||||
|
||||
@router.message(commands=['send_to_all'])
|
||||
async def send_message_to_all_clients(message: types.Message):
|
||||
# Проверяем, является ли отправитель администратором
|
||||
if message.from_user.id != ADMIN_ID: # Замените ADMIN_ID на ID вашего администратора
|
||||
await message.answer("У вас нет прав для выполнения этой команды.")
|
||||
return
|
||||
|
||||
# Получаем текст сообщения
|
||||
text = message.get_args()
|
||||
if not text:
|
||||
await message.answer("Пожалуйста, введите текст сообщения после команды.")
|
||||
return
|
||||
|
||||
try:
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
# Получаем все tg_id клиентов
|
||||
tg_ids = await conn.fetch('SELECT tg_id FROM keys')
|
||||
|
||||
for record in tg_ids:
|
||||
tg_id = record['tg_id']
|
||||
try:
|
||||
await bot.send_message(chat_id=tg_id, text=text)
|
||||
except Exception as e:
|
||||
print(f"Ошибка при отправке сообщения пользователю {tg_id}: {e}. Пропускаем этого пользователя.")
|
||||
|
||||
await message.answer("Сообщение было отправлено всем клиентам.")
|
||||
except Exception as e:
|
||||
print(f"Ошибка при подключении к базе данных: {e}")
|
||||
await message.answer("Произошла ошибка при отправке сообщения.")
|
||||
finally:
|
||||
await conn.close()
|
||||
@@ -8,26 +8,49 @@ anyio==4.4.0
|
||||
async-timeout==4.0.3
|
||||
asyncpg==0.29.0
|
||||
attrs==24.2.0
|
||||
blinker==1.8.2
|
||||
certifi==2024.8.30
|
||||
charset-normalizer==3.3.2
|
||||
click==8.1.7
|
||||
Deprecated==1.2.14
|
||||
distro==1.9.0
|
||||
exceptiongroup==1.2.2
|
||||
frozenlist==1.4.1
|
||||
greenlet==3.1.0
|
||||
h11==0.14.0
|
||||
h2==4.1.0
|
||||
hpack==4.0.0
|
||||
httpcore==1.0.5
|
||||
httpx==0.27.2
|
||||
Hypercorn==0.17.3
|
||||
hyperframe==6.0.1
|
||||
idna==3.8
|
||||
isort==5.13.2
|
||||
itsdangerous==2.2.0
|
||||
Jinja2==3.1.4
|
||||
magic-filter==1.0.12
|
||||
MarkupSafe==2.1.5
|
||||
multidict==6.1.0
|
||||
netaddr==1.3.0
|
||||
numpy==2.1.1
|
||||
|
||||
packaging==24.1
|
||||
|
||||
priority==2.0.0
|
||||
py3xui==0.2.3
|
||||
pydantic==2.5.3
|
||||
pydantic_core==2.14.6
|
||||
pytz==2024.2
|
||||
Quart==0.19.6
|
||||
requests==2.32.3
|
||||
sniffio==1.3.1
|
||||
SQLAlchemy==2.0.34
|
||||
taskgroup==0.0.0a4
|
||||
tomli==2.0.1
|
||||
typing_extensions==4.12.2
|
||||
urllib3==2.2.3
|
||||
Werkzeug==3.0.4
|
||||
wrapt==1.16.0
|
||||
wsproto==1.2.0
|
||||
yarl==1.11.1
|
||||
yookassa==3.3.0
|
||||
|
||||
Reference in New Issue
Block a user