This commit is contained in:
2026-02-13 03:09:19 +05:00
commit 2204b615bc
13 changed files with 620 additions and 0 deletions

27
bot/config.py Normal file
View File

@@ -0,0 +1,27 @@
import os
from dataclasses import dataclass
@dataclass
class Config:
BOT_TOKEN: str
DB_USER: str
DB_PASS: str
DB_HOST: str
DB_PORT: str
DB_NAME: str
@property
def DATABASE_URL(self):
return f"postgresql+asyncpg://{self.DB_USER}:{self.DB_PASS}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
def load_config() -> Config:
return Config(
BOT_TOKEN=os.getenv("BOT_TOKEN"),
DB_USER=os.getenv("DB_USER", "postgres"),
DB_PASS=os.getenv("DB_PASS", "postgres"),
DB_HOST=os.getenv("DB_HOST", "db"), # 'db' - это имя сервиса в docker-compose
DB_PORT=os.getenv("DB_PORT", "5432"),
DB_NAME=os.getenv("DB_NAME", "bot_db"),
)
config = load_config()

24
bot/handlers/__init__.py Normal file
View File

@@ -0,0 +1,24 @@
from aiogram import Router, types
from aiogram.filters import CommandStart
from bot.handlers import payments
from bot.handlers.payments import send_donation_invoice
router = Router()
router.include_router(payments.router)
@router.message(CommandStart())
async def cmd_start(message: types.Message):
await message.answer(f"""Привет, {message.from_user.full_name}!
⭐ Поддержать проект
Если вам нравится проект и вы хотите помочь его развитию, вы можете отправить звёзды в качестве добровольной поддержки.
Пожертвования помогают покрывать:
— еду автору
— аренду серверов
— развитие и улучшение проекта
Поддержка полностью добровольная и не является обязательным условием получения доступа.""")
# Отправляем кнопку оплаты (инвойс) сразу после текста
await send_donation_invoice(message)

46
bot/handlers/payments.py Normal file
View File

@@ -0,0 +1,46 @@
from aiogram import Router, F, types
from aiogram.filters import Command
from aiogram.types import LabeledPrice, PreCheckoutQuery, CallbackQuery
router = Router()
# Функция отправки инвойса (чтобы не дублировать код)
async def send_donation_invoice(message: types.Message):
await message.answer_invoice(
title="Пожертвование",
description="пожертвовать на развитие",
payload="donation_payload",
provider_token="",
currency="XTR",
prices=[LabeledPrice(label="Пожертвование", amount=10)],
start_parameter="donation",
allow_paid_broadcast=False,
)
@router.message(Command("pay"))
async def cmd_pay(message: types.Message):
await send_donation_invoice(message)
@router.callback_query(F.data == "donate_10_stars")
async def on_donate_click(callback: CallbackQuery):
await send_donation_invoice(callback.message)
await callback.answer()
# Обработчик pre_checkout_query (проверка перед оплатой)
# Обработчик pre_checkout_query (проверка перед оплатой)
@router.pre_checkout_query()
async def pre_checkout_handler(pre_checkout_query: PreCheckoutQuery):
await pre_checkout_query.answer(ok=True)
# Обработчик успешной оплаты
@router.message(F.successful_payment)
async def success_payment_handler(message: types.Message):
payment_info = message.successful_payment
# Здесь можно добавить логику начисления дней подписки в БД
await message.answer(
f"✅ Оплата прошла успешно!\n"
f"Сумма: {payment_info.total_amount} {payment_info.currency}\n"
f"Спасибо за пожертвование!"
)

25
bot/main.py Normal file
View File

@@ -0,0 +1,25 @@
from aiogram import Bot, Dispatcher
import asyncio
import logging
from bot.config import config
from bot.handlers import router as main_router
async def main():
# Настройка логирования
logging.basicConfig(level=logging.INFO)
# Инициализация бота и диспетчера
bot = Bot(token=config.BOT_TOKEN)
dp = Dispatcher()
# Регистрация роутеров (хендлеров)
dp.include_router(main_router)
# Запуск polling
try:
await dp.start_polling(bot)
finally:
await bot.session.close()
if __name__ == "__main__":
asyncio.run(main())