5.4 KiB
Favorite stickers Telegram bot
Максимально простой бот для личных стикерпаков «Избранное»: пользователь отправляет медиа или стикер, бот сразу добавляет его в персональный набор. Повторная отправка того же стикера удаляет его.
Возможности
- Принимает фотографии, видео/видеосообщения до 3 секунд, GIF/анимации, документы с медиа и обычные или видео-стикеры.
- Преобразует всё через
ffmpegв Telegram Video Sticker: WEBM/VP9, без звука, до 512 px и 256 КиБ. - Ограничивает входной файл по фактическому размеру и отклоняет разрешение выше 33,5 Мп; конвертации имеют таймаут и общий лимит параллельности.
- Передаёт вход в
ffmpeg/ffprobeчерез отдельный файловый дескриптор и запрещает вложенные файловые и сетевые протоколы. - Поэтому картинки и видео могут находиться в одном наборе.
- Первый набор называется
<bot username> - Favorites <user id>. - После лимита в 120 стикеров автоматически создаётся набор
... [2], затем[3]и т. д. - Повторная отправка исходного стикера или стикера из созданного ботом набора удаляет его.
- Ничего не переставляет и не задаёт дополнительных вопросов.
- Связи пользователей, наборов и стикеров хранятся в SQLite.
TGS — векторный формат Telegram, который
ffmpegне декодирует. Для TGS-стикера бот сразу показывает понятную ошибку. Статические и WEBM-стикеры поддерживаются.
Требования
- Python 3.11+
- uv
ffmpegиffprobeс кодекомlibvpx-vp9- токен Telegram-бота от @BotFather
Запуск
uv sync
export BOT_TOKEN='123456:token-from-botfather'
uv run tg-favorite-stickers --check
uv run tg-favorite-stickers
Бот работает через long polling. Дополнительная настройка в BotFather не требуется.
Переменные окружения
BOT_TOKEN— обязательный токен бота.DATABASE_PATH— SQLite-файл, по умолчаниюdata/favorites.sqlite3.MAX_DOWNLOAD_MB— максимальный размер входного файла, по умолчанию20.FFMPEG_TIMEOUT_SECONDS— общий таймаут одной конвертации, по умолчанию60.MAX_CONVERSIONS— максимальное число одновременных конвертаций, по умолчанию2.
Пример:
cp .env.example .env
set -a
source .env
set +a
uv run tg-favorite-stickers
SQLite-файл нужен не только для списка наборов, но и для распознавания повторно отправленных стикеров. Его следует сохранять при переносе бота. Незавершённые операции Telegram↔SQLite сохраняются в журнале и восстанавливаются при следующем сообщении пользователя. С одной базой одновременно запускается только один экземпляр бота.
Контейнер
Локальная сборка и запуск с постоянным Docker volume:
docker build -t tg-favorite-stickers .
docker volume create tg-favorite-stickers-data
docker run --rm \
--name tg-favorite-stickers \
--env BOT_TOKEN='123456:token-from-botfather' \
--mount source=tg-favorite-stickers-data,target=/app/data \
tg-favorite-stickers
Готовый multi-arch образ для linux/amd64 и linux/arm64 публикуется в
ghcr.io/kr0sh512/tg-favorite-stickers. Ветка main получает теги main,
latest и sha-…, а Git-теги вида v* публикуются под своим именем:
docker pull ghcr.io/kr0sh512/tg-favorite-stickers:latest
GitHub Actions проверяет тесты перед сборкой. Для pull request образ только собирается, но не публикуется в registry.
Проверка
uv sync --extra test
uv run pytest
Структура
src/favorite_stickers/bot.py— обработчики Telegram и выбор медиа.src/favorite_stickers/media.py— проверка и конвертация через ffmpeg.src/favorite_stickers/service.py— добавление/удаление и переход к следующему набору.src/favorite_stickers/store.py— SQLite.src/favorite_stickers/telegram.py— операции Telegram Bot API.