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