From Zero to Revenue-Generating Bot
I built a Telegram bot that sells 26+ digital products with Telegram Stars payments. Here's the complete technical breakdown.
Tech Stack
- Python 3.11 + pyTelegramBotAPI
- SQLite for user tracking
- fpdf2 for PDF generation
- Telegram Stars for payments (no Stripe needed!)
Step 1: Bot Setup
import telebot
from telebot.types import LabeledPrice
BOT_TOKEN = "your_token_here"
bot = telebot.TeleBot(BOT_TOKEN)
@bot.message_handler(commands=['start'])
def start(message):
bot.send_message(
message.chat.id,
"Welcome to SwiftUI Dev Shop!\n"
"Browse products with /catalog"
)
Step 2: Product Catalog
PRODUCTS = {
"swiftui_starter": {
"name": "SwiftUI Starter Kit Pro",
"description": "Complete project templates, network layer, auth flow",
"price_stars": 65,
"file": "products/swiftui_starter.pdf"
},
# ... more products
}
@bot.message_handler(commands=['catalog'])
def catalog(message):
for key, product in PRODUCTS.items():
text = f"*{product['name']}*\n{product['description']}\nPrice: {product['price_stars']} Stars"
markup = telebot.types.InlineKeyboardMarkup()
markup.add(telebot.types.InlineKeyboardButton(
"Buy Now", callback_data=f"buy_{key}"
))
bot.send_message(message.chat.id, text, parse_mode="Markdown", reply_markup=markup)
Step 3: Telegram Stars Payment
This is the key part. Telegram Stars is a built-in payment system — no external payment provider needed.
@bot.callback_query_handler(func=lambda call: call.data.startswith("buy_"))
def handle_buy(call):
product_key = call.data.replace("buy_", "")
product = PRODUCTS[product_key]
prices = [LabeledPrice(label=product['name'], amount=product['price_stars'])]
bot.send_invoice(
call.message.chat.id,
title=product['name'],
description=product['description'],
invoice_payload=f"buy_{product_key}",
provider_token="", # Empty for Stars!
currency="XTR", # Telegram Stars currency
prices=prices
)
@bot.pre_checkout_query_handler(func=lambda query: True)
def pre_checkout(query):
bot.answer_pre_checkout_query(query.id, ok=True)
@bot.message_handler(content_types=['successful_payment'])
def successful_payment(message):
payload = message.successful_payment.invoice_payload
product_key = payload.replace("buy_", "")
product = PRODUCTS[product_key]
with open(product['file'], 'rb') as f:
bot.send_document(message.chat.id, f)
bot.send_message(message.chat.id, "Thank you for your purchase!")
Step 4: User Tracking with SQLite
import sqlite3
def init_db():
conn = sqlite3.connect('shop.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY,
username TEXT,
first_name TEXT,
joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)''')
c.execute('''CREATE TABLE IF NOT EXISTS payments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
product_key TEXT,
amount INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)''')
conn.commit()
conn.close()
Step 5: PDF Product Generation
I use fpdf2 with custom fonts to generate professional-looking PDF products from Markdown files.
from fpdf import FPDF
class ProductPDF(FPDF):
def header(self):
self.set_font("DejaVu", "I", 8)
self.cell(0, 10, "SwiftUI Dev Shop", align="C")
def footer(self):
self.set_y(-15)
self.set_font("DejaVu", "I", 8)
self.cell(0, 10, f"Page {self.page_no()}", align="R")
Results
- 26 products in the catalog
- 3 bundles with discounts
- Automated delivery — no manual work
- Revenue tracking via SQLite
Key Takeaways
- Telegram Stars removes payment friction — users already have Stars
- Python + SQLite is enough — no need for complex backends
- PDF products have near-zero marginal cost — create once, sell forever
- Automation is everything — the bot runs 24/7 without my input
Want to build your own? Ask questions in the comments!
Follow me: @SwiftUIDaily on Telegram
Top comments (0)