
Привет, Хабр! В качестве пет-проекта для работы с 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 показал себя как отличный инструмент для микротранзакций - конверсия в покупку выше, чем при использовании сторонних платежек, так как пользователю не нужно покидать мессенджер.