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

421 lines
12 KiB
Markdown

# 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
```dockerfile
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
```bash
# 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)
```bash
# 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
```bash
# 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:
```python
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:
```python
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
```bash
# 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
```bash
# 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:
```bash
# 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
```bash
# Check if container is running
sudo docker ps | grep stickerbot
# Check logs for errors
sudo docker-compose logs -f
```
### Database issues
```bash
# 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:
```yaml
REGISTRY="your-registry:port"
```
## Version History
See git log for detailed commit history:
```bash
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