Files
Telegram-bot-old/bot.py
2024-11-08 06:00:09 +03:00

143 lines
8.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import Application, CallbackQueryHandler, ContextTypes, MessageHandler, filters,CommandHandler
from db import User, VPNServer, Transaction, Subscription, get_db_session, init_db, SessionLocal
from sqlalchemy import desc
from service import UserService
import json
from datetime import datetime
from logger_config import setup_logger
# Чтение конфигурации и настройка логгера
with open('config.json', 'r') as file:
config = json.load(file)
logger = setup_logger()
# Общая функция для создания клавиатуры
def create_keyboard(buttons):
return InlineKeyboardMarkup([[InlineKeyboardButton(text, callback_data=data)] for text, data in buttons])
# Функция для отправки сообщений с загрузкой
async def send_loading_message(update, context, text, reply_markup=None):
loading_message = await context.bot.send_message(chat_id=update.effective_chat.id, text="Загрузка...")
await loading_message.edit_text(text, reply_markup=reply_markup)
# Функция для обработки главного меню
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
buttons = [("Личный кабинет", "account"), ("О нас ;)", "about"), ("Поддержка", "support")]
await send_loading_message(update, context, 'Добро пожаловать в ...! Здесь вы можете приобрести VPN. И нечего более', create_keyboard(buttons))
# Функция для обработки личного кабинета
async def personal_account(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
service = UserService(logger)
tgid = str(update.callback_query.from_user.id)
user = service.get_user_by_telegram_id(tgid) or service.add_user(tgid)
subscription = service.last_subscription(user)
buttons = [("Пополнить баланс", "pop_up"), ("Приобрести подписку", "buy_tarif"), ("❔FAQ❔", "faq"), ("История платежей", "payment_history")]
text = (
f'Профиль {user.username}, {user.telegram_id}\n'
f'{"Вы не приобретали ещё у нас подписку, но это явно стоит сделать:)" if not subscription else f"Ваша подписка действует до - {subscription.expiry_date}" if subscription.expiry_date > datetime.now() else f"Ваша подписка истекла - {subscription.expiry_date}"}\n'
f'Ваш счёт составляет: {user.balance}'
)
await send_loading_message(update, context, text, create_keyboard(buttons))
# Функция для отображения информации "О нас"
async def about(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
buttons = [("Главное меню", "start")]
await send_loading_message(update, context, 'Игорь чё нить напишет, я продублирую', create_keyboard(buttons))
# Функция для отображения поддержки
async def support(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
buttons = [("Главное меню", "start"), ("Написать", "sup")]
await send_loading_message(update, context, 'Для связи с поддержкой выберите "Написать" и изложите проблему в одном сообщении.', create_keyboard(buttons))
# Функция для пополнения баланса
async def pop_up(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
buttons = [("Главное меню", "start")]
await send_loading_message(update, context, 'Когда-нибудь эта функция заработает', create_keyboard(buttons))
# Функция для покупки подписки
async def buy_subscription(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
service = UserService(logger)
tgid = str(update.callback_query.from_user.id)
user = service.get_user_by_telegram_id(tgid)
subscription = service.last_subscription(user)
if subscription is None:
buttons = [("Тариф 1 \"Бимжик\"", "Бимжик"), ("Тариф 2 \"Бизнес хомячёк\"", "Бизнес_хомячёк"), ("Тариф 3 \"Продвинутый Акулёнок\"", "Продвинутый_Акулёнок"), ("Главное меню", "start")]
text = 'Какую подписку вы хотите приобрести?\n1. "Бимжик" - 200 руб. на 1 месяц\n2. "Бизнес хомячёк" - 500 руб. на 3 месяца\n3. "Продвинутый Акулёнок" - 888 руб. на 6 месяцев'
else:
buttons = [("Главное меню", "start")]
text = 'У вас уже приобретена подписка'
await send_loading_message(update, context, text, create_keyboard(buttons))
# Функция для отображения FAQ
async def faq(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
buttons = [("Главное меню", "start")]
await send_loading_message(update, context, 'Когда-нибудь здесь появится полезная информация!', create_keyboard(buttons))
# Функция для обработки ввода пользователя в поддержку
async def sup(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if context.user_data.get('awaiting_input'):
user_input = update.message.text
await update.message.reply_text(f"Вы ввели: {user_input}")
context.user_data['awaiting_input'] = False
else:
await update.message.reply_text("Выберите команду или нажмите кнопку для продолжения.")
# Обработчик кнопок
async def button_handler(update: Update, context):
query = update.callback_query
await query.answer()
data = query.data
service = UserService(logger)
tgid = str(query.from_user.id)
try:
if data == 'account':
await personal_account(update, context)
elif data == 'start':
await start(update, context)
elif data == 'about':
await about(update, context)
elif data == 'support':
await support(update, context)
elif data == 'sup':
context.user_data['awaiting_input'] = True
elif data == 'pop_up':
await pop_up(update, context)
elif data == 'buy_tarif':
await buy_subscription(update, context)
elif data == 'faq':
await faq(update, context)
elif data == 'payment_history':
await active_sub(update, context)
elif data in ['Бимжик', 'Бизнес_хомячёк', 'Продвинутый_Акулёнок']:
plan = data.replace('_', ' ')
result = service.buy_sub(tgid, data)
text = {
"OK": "Ваша конфигурация готова!",
"100": "Недостаточно средств.",
"120": "Нет доступных серверов, подождите немного.",
}.get(result, "Неизвестный тариф.")
await query.message.reply_text(text)
except Exception as e:
logger.error(f"Ошибка при обработке запроса пользователя {tgid}: {e}")
await query.message.reply_text("Произошла ошибка. Пожалуйста, попробуйте снова.")
# Запуск приложения
def main() -> None:
init_db()
application = Application.builder().token(config['token']).build()
application.add_handler(CommandHandler("start", start))
application.add_handler(CallbackQueryHandler(button_handler))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, sup))
application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()