@ChatGPTTlgrmBot
@ChatGPTTlgrmBot

Привет, Хабр! В качестве пет-проекта для работы с API и базами данных решил написать своего бота-ассистента. Идея простая: прокси к OpenAI, но с нюансами: хотел разобраться, как работать с относительно новой внутренней валютой Telegram Stars, реализовать собственную систему промокодов и админку без использования громоздких фреймворков, оставаясь на библиотеке telebot (pyTelegramBotAPI).

В этой статье покажу, как реализовал биллинг через Stars, "управление пользователями" и поделюсь исходным кодом.

Стек и задача

Цель была создать MVP, который можно быстро развернуть.

  • Язык: Python 3.13

  • Библиотека: pyTelegramBotAPI (telebot)

  • База данных: SQLite (через самописный менеджер)

  • Платежи: Telegram Stars (XTR).

Реализация оплаты через Telegram Stars

Самое интересное в проекте - это нативная оплата. Telegram относительно давно ввел «Звезды», и мне было важно понять, как их принимать.

В коде это выглядит достаточно просто через метод send_invoice. Важный момент: параметр currency должен быть строго "XTR".

# Фрагмент обработчика кнопки покупки
def create_invoice(chat_id, user_id, amount):
    prices = [types.LabeledPrice(label=f"{amount} запросов", amount=amount)]
    
    bot.send_invoice(
        chat_id=chat_id,
        title=f"Покупка {amount} запросов",
        description=f"Пополнение баланса на {amount} запросов",
        invoice_payload=f"requests_{amount}_{user_id}", # Передаем данные для идентификации платежа
        provider_token="", # Для Stars токен не нужен, оставляем пустым
        currency="XTR",
        prices=prices
    )

Для подтверждения оплаты нужно обработать pre_checkout_query и successful_payment:

@bot.pre_checkout_query_handler(func=lambda query: True)
def process_pre_checkout(pre_checkout_query):
    # Тут можно добавить проверку доступности товара, но у нас цифровой актив
    bot.answer_pre_checkout_query(pre_checkout_query.id, ok=True)

@bot.message_handler(content_types=['successful_payment'])
def process_successful_payment(message):
    payment_info = message.successful_payment
    
    # Парсим payload, который мы зашили при создании инвойса
    payload_parts = payment_info.invoice_payload.split('_')
    amount = int(payload_parts[1])
    user_id = int(payload_parts[2])
    
    # Начисляем запросы в БД
    db_manager.add_requests(user_id, amount)
    
    # Логируем платеж
    db_manager.add_payment(
        tg_id=user_id,
        amount=amount,
        stars_paid=amount,
        payment_id=payment_info.telegram_payment_charge_id
    )
    
    bot.send_message(message.chat.id, f"✅ Оплата прошла успешно! Баланс пополнен.")

Администрирование и "управление пользователями"

Чтобы не лазить каждый раз в базу данных для начисления лимитов или проверки статистики, я реализовал простую админку прямо внутри бота. Основные команды: /stat (статистика), /createpromo (создание промокодов) и /give (ручное начисление запросов).

Команда /give делалась в первую очередь для себя - чтобы можно было быстро накинуть тестовые запросы или компенсировать их пользователю в случае сбоя.

В telebot есть удобный механизм register_next_step_handler, который позволяет выстраивать цепочки диалогов (step-by-step) без подключения сложных FSM-машин. Для хранения промежуточных данных (например, когда админ ввел ID пользователя, но еще не ввел количество запросов) я использовал обычные Python-словари. Для однопользовательской админки это самое быстрое и достаточное решение.

Реализация пошагового начисления запросов:

# Словари для хранения временных данных шагов
waiting_for_user_id = {}

@bot.message_handler(commands=['give'])
def give_requests_command(message):
    # Проверка на админа (ID берется из конфига)
    if message.from_user.id != ADMIN_ID:
        return
    
    bot.send_message(message.chat.id, "? Введите Telegram ID пользователя:")
    # Ждем следующего сообщения от админа
    bot.register_next_step_handler(message, process_give_user_id)

def process_give_user_id(message):
    try:
        user_id = int(message.text.strip())
        # Сохраняем ID во временный словарь
        waiting_for_user_id[message.from_user.id] = user_id 
        
        bot.send_message(message.chat.id, "? Введите количество запросов:")
        # Переходим к следующему шагу — вводу суммы
        bot.register_next_step_handler(message, process_give_amount)
    except ValueError:
        bot.send_message(message.chat.id, "❌ Неверный формат ID")

Такой подход позволяет реализовать любую логику: от анкетирования до заполнения параметров промокода, не усложняя архитектуру бота.

Система промокодов

Для маркетинговых активностей и отслеживания трафика я написал систему промокодов. Они хранятся в SQLite с параметрами:

  • Сам код (уникальный).

  • Количество бонусных запросов.

  • Лимит использования (можно сделать одноразовый код или бесконечный для статьи).

Это позволяет мне генерировать коды вроде HABR2025 (кстати, попробуйте в боте), размещать их в статьях и видеть, сколько людей пришло с конкретной площадки.

def process_promo_max_uses(message):
    # ... здесь код получает данные из временного словаря ...
    result = db_manager.create_promo(
        promo_data['code'],
        promo_data['requests'],
        max_uses if max_uses > 0 else None
    )
    # ... отправка подтверждения админу ...

Исходный код

Проект полностью открыт. Если вы ищете пример работы с Telegram Stars или хотите посмотреть, как реализовать простую админку на telebot без лишних зависимостей - welcome в репозиторий.

Заключение

На данный момент бот выполняет свою главную функцию: работает как удобный интерфейс к LLM с прозрачной системой оплаты. Telegram Stars показал себя как отличный инструмент для микротранзакций - конверсия в покупку выше, чем при использовании сторонних платежек, так как пользователю не нужно покидать мессенджер.

Комментарии (0)