ai did his job.
Container / test (push) Canceled after 0s
Container / image (push) Canceled after 0s

This commit is contained in:
2026-08-08 03:53:10 +03:00
parent 2ffc773113
commit a830623fcd
23 changed files with 3309 additions and 2 deletions
+96 -2
View File
@@ -1,2 +1,96 @@
# tg-favorite-stickers
tg-bot for fast creation of stikerpacks
# 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](https://docs.astral.sh/uv/)
- `ffmpeg` и `ffprobe` с кодеком `libvpx-vp9`
- токен Telegram-бота от [@BotFather](https://t.me/BotFather)
## Запуск
```bash
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`.
Пример:
```bash
cp .env.example .env
set -a
source .env
set +a
uv run tg-favorite-stickers
```
SQLite-файл нужен не только для списка наборов, но и для распознавания повторно отправленных стикеров. Его следует сохранять при переносе бота. Незавершённые операции Telegram↔SQLite сохраняются в журнале и восстанавливаются при следующем сообщении пользователя. С одной базой одновременно запускается только один экземпляр бота.
## Контейнер
Локальная сборка и запуск с постоянным Docker volume:
```bash
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*` публикуются под своим именем:
```bash
docker pull ghcr.io/kr0sh512/tg-favorite-stickers:latest
```
GitHub Actions проверяет тесты перед сборкой. Для pull request образ только
собирается, но не публикуется в registry.
## Проверка
```bash
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.