Files
stickerbot/OPENCODE.md
coding 67c85ff8a0 Update OPENCODE.md with Dockerfile docs and CI/CD information
Changes:
- Add Dockerfile Configuration section with code example
- Document Debian-based image choice (python:3.11-slim)
- Add all system dependencies (libgl1, libsm6, etc.)
- Extend Common Issues with Docker build troubleshooting
- New CI/CD section for Gitea Actions
- Document both workflows (autobuild and manual)
- Add required secrets and registry configuration
- Add version history overview
2026-03-25 09:36:06 +00:00

12 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
  • Base Image: python:3.11-slim (Debian-based for better compatibility)
  • Environment: python-dotenv for configuration

Dockerfile Configuration

FROM python:3.11-slim

# System dependencies for OpenCV, FFmpeg and rembg
RUN apt-get update && apt-get install -y --no-install-recommends \
    ffmpeg \
    libgl1 \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libxrender-dev \
    libgomp1 \
    && rm -rf /var/lib/apt/lists/*

Key points:

  • Uses python:3.11-slim (Debian-based) instead of Alpine for better Python package compatibility
  • Includes OpenCV dependencies: libgl1, libglib2.0-0, libsm6, libxext6, libxrender-dev
  • Includes libgomp1 for OpenMP support (required by numba/llvmlite)
  • Non-root user for security

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
  8. Docker build fails with Alpine: We use python:3.11-slim (Debian) instead of Alpine because rembg requires compilation tools that don't work well with Alpine's musl libc

Troubleshooting

Docker Build Issues

If the Docker build fails with package errors:

# The Dockerfile uses Debian-based python:3.11-slim
# NOT Alpine - this is intentional for better Python package compatibility

# Check Dockerfile has correct base image:
grep "FROM" Dockerfile
# Should show: FROM python:3.11-slim

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

CI/CD with Gitea Actions

The project includes automated Docker builds via Gitea Actions.

Workflow Files

.gitea/workflows/docker-autobuild.yaml - Automatic builds on push

  • Triggers on push to main or master branch
  • Builds and pushes to local registry: 192.168.88.201:5000
  • Tags: latest and v{run_number}-autobuild
  • Features:
    • Path ignores for markdown/docs changes
    • Docker Buildx with layer caching
    • Automatic cleanup after build

.gitea/workflows/docker-build.yaml - Manual builds

  • Triggered manually via Gitea web interface
  • Options:
    • Custom version tag (e.g., 1.0.0, v1.0.0)
    • Additional tags (comma-separated, e.g., stable,production)
    • Toggle latest tag
  • Features:
    • Flexible versioning
    • Multiple tag support
    • Docker layer caching

Required Secrets

Configure these in Gitea repository settings:

  • REGISTRY_USERNAME - Username for Docker registry
  • REGISTRY_PASSWORD - Password for Docker registry

Registry Configuration

Default registry: 192.168.88.201:5000

To change the registry, edit both workflow files:

REGISTRY="your-registry:port"

Version History

See git log for detailed commit history:

git log --oneline

Current features:

  • Telegram Sticker Bot with full management capabilities
  • Automatic image optimization (WebP conversion)
  • GIF to Video Sticker conversion
  • Background removal (local + API)
  • Existing sticker set import
  • Gitea Actions CI/CD