Бот публикует посты в канал по расписанию, а управлять ими можно из Telegram Mini App — веб-интерфейса в стиле профиля Instagram: аватар и счётчики, «истории» из ближайших запланированных постов, сетка 3×N, лента с каруселями фото, черновики, очередь и ошибки.
Вы ──► бот (фото/видео/текст) ─┐
├──► SQLite: очередь постов ──► планировщик (каждые 15 с) ──► канал
Вы ──► Mini App «Лента» ───────┘
- Очередь со слотами. В
.envзадаются слоты, например09:00,13:00,19:00. Новый пост встаёт в ближайший свободный слот — очередь сама расходится по дням. - Публикация в конкретное время, «сейчас» или в черновик.
- Альбомы до 10 фото/видео (уходят в канал одним media group), текстовые посты до 4096 символов.
- Ошибки не теряются: если Telegram отклонил пост, он попадает во вкладку «Ошибки» с текстом причины — его можно поправить и отправить заново.
- Удаление опубликованного поста из ленты удаляет его и из канала.
- Создайте бота у @BotFather → получите
BOT_TOKEN. - Добавьте бота в администраторы канала с правами «Публикация» и «Удаление сообщений».
- Узнайте свой Telegram id (например, у @userinfobot).
- Скопируйте настройки и заполните:
cp .env.example .env
- Запустите:
pip install -r requirements.txt python -m app.main # или docker compose up -d --build - Откройте бота и отправьте
/start.
Telegram открывает Mini App только по https://. Варианты:
- сервер с доменом + nginx/Caddy (Caddy выпустит сертификат сам);
- для разработки — туннель:
cloudflared tunnel --url http://localhost:8000илиngrok http 8000.
Полученный адрес укажите в WEBAPP_URL и перезапустите приложение — бот сам добавит
кнопку «Лента» в меню чата. Без Telegram ленту можно открыть в браузере и войти по ADMIN_TOKEN.
- Пришлите фото, видео или текст (можно переслать из другого канала) — пост встанет в очередь, под ответом будут кнопки «🚀 Сейчас» и «🗑 Отменить».
/queue— список запланированного.- Альбомы удобнее собирать в Mini App: там можно выбрать до 10 файлов сразу.
| Переменная | Назначение |
|---|---|
BOT_TOKEN |
токен бота |
CHANNEL_ID |
@username канала или числовой id -100… |
ADMIN_IDS |
Telegram id админов через запятую — только они видят ленту и могут постить |
ADMIN_TOKEN |
пароль для входа в ленту из обычного браузера |
WEBAPP_URL |
публичный HTTPS-адрес приложения |
TIMEZONE |
часовой пояс слотов, например Europe/Moscow |
SCHEDULE_SLOTS |
время автопубликации очереди, HH:MM через запятую |
DB_PATH, MEDIA_DIR |
где хранить базу и загруженные файлы |
app/
main.py FastAPI: REST API + раздача Mini App, запуск бота и планировщика
bot.py обработчики бота (aiogram 3)
publisher.py отправка в канал и фоновый планировщик
slots.py расчёт ближайшего свободного слота
auth.py проверка подписи Telegram WebApp initData
db.py SQLite
static/ интерфейс-лента (HTML/CSS/JS без сборки)
tests/ pytest
Все запросы требуют заголовок X-Telegram-Init-Data (из Mini App) или X-Admin-Token.
| Метод | Путь | |
|---|---|---|
| GET | /api/channel |
название, аватар, счётчики, слоты, ближайший слот |
| GET | /api/posts?status=published|scheduled|draft|failed |
список постов |
| POST | /api/posts |
multipart: caption, files[], mode=queue|at|now|draft, scheduled_at (ISO с часовым поясом) |
| PATCH | /api/posts/{id} |
JSON: caption, scheduled_at, status=draft|scheduled |
| POST | /api/posts/{id}/publish |
опубликовать сейчас |
| DELETE | /api/posts/{id}?from_channel=true |
удалить (и из канала) |
Загруженные файлы раздаются по /media/<случайное имя> без авторизации (имена не угадываются),
так что не загружайте в черновики то, что нельзя показывать.
pip install -r requirements-dev.txt
pytest