Files
stickerbot/OPENCODE.md
coding f634b884ec Initial commit: Telegram Sticker Bot Manager
Features:
- Create and manage sticker packs
- Add existing sticker sets to database
- Automatic image optimization (512px, WebP conversion)
- GIF to animated video sticker conversion (WebM, VP9)
- Background removal (local rembg + optional Remove.bg API)
- Hybrid API with retry logic and usage tracking
- Premium status detection
- SQLite database for persistence
- Docker containerization
- Complete OPENCODE.md documentation

Technical Stack:
- python-telegram-bot 22.7
- Pillow for image processing
- FFmpeg for video conversion
- rembg for local background removal
- aiosqlite for async database operations
2026-03-25 08:59:38 +00:00

9.9 KiB

OPENCODE.md - Telegram Sticker Bot

Overview

This is a Telegram bot for managing sticker packs. Built with python-telegram-bot v22.7, it allows the bot owner to create, manage, and organize sticker sets through an interactive conversation interface.

Architecture

Technology Stack

  • Python: 3.11+
  • Library: python-telegram-bot v22.7 (supports Bot API 9.5)
  • Database: SQLite with aiosqlite for async operations
  • Image Processing: Pillow (PIL) for automatic image conversion
  • Video Processing: FFmpeg for GIF to WebM conversion
  • Background Removal: rembg (local) + remove.bg API (optional)
  • Container: Docker + Docker Compose
  • Environment: python-dotenv for configuration

Project Structure

stickerbot/
├── bot.py                   # Main bot with ConversationHandler
├── config.py                # Configuration and environment loading
├── database.py              # SQLite database operations
├── sticker_manager.py       # Sticker management utilities
├── image_processor.py       # Automatic image conversion
├── gif_processor.py         # GIF to WebM conversion
├── background_remover.py    # Background removal (local + API)
├── requirements.txt         # Python dependencies
├── Dockerfile              # Docker image configuration
├── docker-compose.yml      # Docker Compose configuration
├── .env.example            # Environment template
└── data/                   # Persistent data directory

Database Schema

  • sticker_sets: Tracks created sticker sets (user_id, set_name, set_title, timestamps)
  • user_premium: Caches user premium status with last check timestamp
  • stickers: Tracks individual stickers in sets (file_id, emoji, set_name)
  • api_usage: Tracks API usage for external services (remove.bg)

Commands

Available Commands

  • /start - Start the bot and show main menu
  • /hilfe - Display detailed help message
  • /cancel - Cancel current conversation

Build/Lint/Test Commands

Docker

# Build and run
sudo docker-compose up -d --build

# View logs
sudo docker-compose logs -f

# Stop
sudo docker-compose down

# Rebuild after changes
sudo docker-compose up -d --build --force-recreate

Local Development (without Docker)

# Install dependencies
pip install -r requirements.txt

# Run bot
python bot.py

# Run with environment file
python -c "from bot import main; main()"

Testing

  • No test suite implemented yet
  • Manual testing via Telegram bot interface
  • Use /cancel to abort any conversation

Linting

# Optional: Add ruff or flake8
pip install ruff
ruff check .
ruff format .

Code Style Guidelines

Imports

  • Group imports: stdlib, third-party, local
  • Use absolute imports
  • Example:
import logging
from telegram import Update
from telegram.ext import Application
from config import BOT_TOKEN

Async/Await

  • All handlers are async (python-telegram-bot v22.x requirement)
  • Database operations use aiosqlite (async)
  • Always await coroutines
  • Example:
async def handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("Hello")

Types

  • Use type hints where possible
  • Follow telegram library types: Update, ContextTypes, InlineKeyboardMarkup
  • Database functions return Optional[bool], List[Dict[str, Any]]

Naming Conventions

  • Functions: snake_case
  • Constants: UPPER_CASE
  • Classes: PascalCase
  • Private: _prefix

Error Handling

  • Use try-except blocks for API calls
  • Log errors with logger.error()
  • Return success/failure tuples or booleans
  • Always clean up user_data on errors

Conversation States

  • Defined as constants at module level
  • Use range() for sequential states
  • Clear user_data when conversation ends
  • State order: MENU → CREATE_SET_* → SELECT_SET → SET_ACTION → specific actions

Security

  • OWNER_ID check on every /start
  • No group chat support (private only)
  • SQLite for local persistence
  • No secrets in code (use .env)

Key Features

Premium Detection

  • Check via chat.is_premium from Telegram API
  • Cached in database with 24h refresh interval
  • Scheduled job using JobQueue
  • Displayed in main menu

Sticker Operations

1. Create New Sticker Set

Flow: Name → Title → Emoji → Image

  • 4-step wizard with input validation
  • Automatic image optimization
  • Optional background removal

2. Add Existing Sticker Set

Flow: Select "📥 Existierendes hinzufügen" → Enter set name

  • User provides existing sticker set name
  • Bot verifies via getStickerSet() API
  • Auto-appends _by_<bot_username> if not present
  • Duplicate check prevents double entries

3. Add Sticker to Set

Supported formats:

  • Static images: PNG, JPG, WebP (automatic conversion to WebP)
  • GIFs: Converted to animated video stickers (WebM, max 3 seconds)

Features:

  • Automatic resizing to 512px
  • Background removal option (if REMOVE_BG_API_KEY configured)
  • GIF trimming for animations > 3 seconds

4. Delete Sticker

  • Forward sticker to bot
  • Confirmation before deletion

5. Change Emoji

  • Forward sticker → Enter new emoji

6. Rename Set

  • Enter new title (max 64 characters)

7. Delete Set

  • Confirmation required
  • Cannot be undone

Automatic Image Processing

All uploaded images are automatically converted to Telegram sticker format:

  • Resize: One dimension set to 512px (other ≤512px), maintaining aspect ratio
  • Format conversion: Converted to WebP with transparency (RGBA)
  • Compression: Quality adjusted automatically (60-95) to stay under 3MB
  • Supported formats: PNG, JPG, JPEG, WebP, GIF, BMP, TIFF
  • Quality: Uses LANCZOS resampling for best results

Background Removal (Hybrid)

Local Processing (rembg)

  • Cost: Free, runs on server
  • Method: U²Net deep learning model
  • First run: Downloads model (~180MB)
  • Speed: Depends on image size

Remove.bg API (Optional)

  • Cost: 50 free calls/month, then paid
  • Configuration: Set REMOVE_BG_API_KEY in .env
  • Retry logic: 3 attempts with delays (2s, 5s, 10s)
  • Limit tracking: Stored in database, resets monthly
  • Fallback: Automatically falls back to local on API errors

User Interface

Without API key:
Image → [Auto: Local processing] → Emoji → Done

With API key:
Image → Selection:
  ├─ [🤖 Local (free)]
  ├─ [☁️ API (45/50)] or [☁️ API (50/50) ⚠️ Limit]
  └─ [⏭️ Skip removal]

If API fails/limit reached:
  ❌ Remove.bg API limit reached (50/50)
     
  [🤖 Process locally instead]
  [⏭️ Without background removal]
  [❌ Cancel]

GIF to Video Sticker Conversion

  • Format: WebM with VP9 codec
  • Resolution: 512px (one side), other ≤512px
  • FPS: 30 frames per second
  • Duration: Maximum 3 seconds
  • File size: Maximum 256KB
  • Compression: Automatic quality adjustment
  • Trimming: User confirmation for GIFs > 3s

Environment Variables

# Required
BOT_TOKEN=your_telegram_bot_token
OWNER_ID=your_telegram_user_id

# Optional
DATABASE_PATH=/app/data/sticker_bot.db
PREMIUM_CHECK_INTERVAL=24  # Hours, default: 24

# Optional: Remove.bg API for background removal
# 50 free calls/month
REMOVE_BG_API_KEY=your_remove_bg_api_key

Useful Commands

# Check bot is running
sudo docker ps | grep stickerbot

# View logs
sudo docker-compose logs -f

# Database inspection
sqlite3 data/sticker_bot.db ".tables"
sqlite3 data/sticker_bot.db "SELECT * FROM sticker_sets;"
sqlite3 data/sticker_bot.db "SELECT * FROM api_usage;"

# Reset database
rm data/sticker_bot.db

# Rebuild container
sudo docker-compose up -d --build --force-recreate

Important Notes

Sticker Requirements

  • Static stickers: 512x512px, WebP format, max 3MB
  • Animated stickers: WebM (VP9), 512px one side, max 3s, max 256KB
  • Emoji: One per sticker (can be changed later)

Set Names

  • Must end with _by_<bot_username> (handled automatically)
  • 1-64 characters
  • Only alphanumeric and underscores for short name

Limits

  • Regular sets: Max 120 stickers
  • Emoji sets: Max 200 stickers
  • API calls: 50/month for remove.bg (free tier)

Best Practices

  • Send images as file (not compressed photo) for best quality
  • Use /start to return to main menu anytime
  • Use /cancel to abort current operation
  • Database persists in ./data/ volume

API Methods Used

Telegram Bot API

  • create_new_sticker_set() - Create sticker sets
  • add_sticker_to_set() - Add stickers
  • delete_sticker_from_set() - Remove stickers
  • set_sticker_emoji_list() - Change emoji
  • set_sticker_set_title() - Rename set
  • delete_sticker_set() - Delete entire set
  • get_sticker_set() - Retrieve set info (for existing sets)
  • get_chat() - Check premium status

External APIs

  • Remove.bg API: POST https://api.remove.bg/v1.0/removebg - Background removal

Common Issues

  1. Import errors in IDE: Install requirements.txt (pip install -r requirements.txt)
  2. Database locked: Only one process should access SQLite at a time
  3. Sticker creation fails: Check image format (must be valid image file)
  4. Premium check fails: User must have started bot first
  5. API limit reached: Check current usage with /hilfe or in database
  6. Background removal slow: First run downloads ML model (~180MB)
  7. GIF conversion fails: Ensure GIF is under 10MB before upload

Troubleshooting

Bot not responding

# Check if container is running
sudo docker ps | grep stickerbot

# Check logs for errors
sudo docker-compose logs -f

Database issues

# Reset database (removes all data)
rm data/sticker_bot.db
sudo docker-compose restart

API issues

  • Verify REMOVE_BG_API_KEY is correct
  • Check API usage in database: sqlite3 data/sticker_bot.db "SELECT * FROM api_usage;"
  • API automatically falls back to local processing on errors