- keyboards.py: MAIN_MENU (✍️ Написать пост / 💡 Идея / 🎨 Мой стиль / 📖 Помощь / 💳 Подписка / 👤 Баланс) и LOCKED_MENU — при блокировке первой кнопкой идёт «💳 Оплатить подписку» - кнопки не обходят роутинг: resolve_button_text превращает их в slash-команду (/help, /balance, /subscribe, /style) или готовый запрос («Напиши пост», «предложи идею…») - новая команда /style показывает сохранённый Tone of Voice и подсказывает, как его настроить - set_my_commands публикует slash-команды при старте, ошибка не роняет бот - fix: _send_idea вызывалась на bot.py, но была потеряна в коммите про подписку — /idea падал с NameError; функция восстановлена - 17 новых тестов клавиатуры; 92 теста OK; VERSION 0.1.0+26
12 KiB
12 KiB
Social Post Writer Bot
Идея
Telegram-бот, который по запросу пользователя готовит текст публикации для выбранной социальной сети.
Цель
Быстро превращать тему, тезисы или черновик пользователя в готовый к публикации текст, адаптированный под площадку и заданный стиль.
Основной сценарий
- Пользователь описывает, о чём нужен пост, и указывает соцсеть.
- При необходимости задаёт тон, длину и дополнительные требования.
- Бот генерирует текст; пользователь может попросить изменить или переписать его.
Первая версия
- Принимать запрос обычным сообщением.
- Уточнять площадку и стиль, если они не указаны.
- Возвращать готовый текст без автоматической публикации.
- Поддерживать доработку результата сообщениями вроде «короче», «добавь юмора» или «сделай официальный тон».
Технические заметки
- Формат: Telegram-бот.
- Стек: Python 3.12, aiogram 3.x, aiohttp, SQLite.
- APInex Voice STT расшифровывает голосовые; Gemini 3.8 Flash через APInex классифицирует намерения, пишет/правит посты и извлекает ToV из скриншотов.
- Coolify env с отдельными модельными настройками:
APINEX_STT_MODEL,APINEX_INTENT_CLASSIFIER_MODEL,APINEX_POST_WRITER_MODEL,APINEX_IMAGE_TONE_MODEL; общий секретAPINEX_API_KEY. - JSON-журнал вызовов APInex и ошибок разбора хранится в SQLite 30 дней; системные промпты не дублируются (имя и SHA-256), изображения и аудио не записываются.
- Служебные ответы пользователю — всегда на русском; тексты постов — на языке явного запроса. Техническая ошибка может оставаться дословно.
- Настройки пользователей и распознанные тексты публикаций для накопления Tone of Voice хранятся отдельно по Telegram user id; история диалогов и исходные изображения не сохраняются.
- На явную просьбу поста и на реплай-правку бот возвращает 3 отдельных варианта.
Подписка и монетизация
- Модель: триал 3 дня, затем подписка 30 дней за 100 звёзд (Telegram Stars).
- Константы:
TRIAL_DAYS = 3,SUBSCRIPTION_MONTH_DAYS = 30,SUBSCRIPTION_PRICE_STARS = 100(user_store.py). - Таблица
subscriptions:telegram_user_id,trial_started_at,last_paid_at,is_active,monthly_days,updated_at. /startсоздаёт запись триала (ensure_subscription), если её нет./subscribeактивирует подписку: пишет оплату 100 звёзд, продлевает на 30 дней (activate_subscription),is_active = 1./balanceпоказывает статус: триал активен (сколько дней осталось) / подписка активна (сколько дней, когда списание) / период истёк.- Генерация поста и идеи блокируется, если подписка не активна (
_check_subscription)./help,/start,/balance,/subscribeдоступны всегда. /clearобнуляет подписку (deactivate_subscription) и данные пользователя.- Оплата звёздами — имитация: бот не принимает реальные платежи, только симулирует активацию.
Деплой и конфигурация
- Gitea:
admin/social-post-writer-bot, веткаdev. - Coolify проект:
Social Post Writer Bot, окружениеdevelopment. - Coolify приложение:
social-post-writer-bot-development(d32u5zcq2g4odmdpq9hw91yn) наspb-easy-dale. - SQLite:
/app/data/social_writer.sqlite3; persistent volumed32u5zcq2g4odmdpq9hw91yn-social-post-writer-dev-dataмонтируется в/app/data. - Секреты хранятся в переменных окружения приложения Coolify; не сохраняются в репозитории.
DEPLOY_ENV=development,DEV_CHAT_ID— для уведомления о новой версии; версия в файлеVERSION(сейчас0.1.0+26).- Вики Gitea: страницы
Home,User-Guide,Developer-Guide,Subscription,Deployment.
Статус
- Идея проекта зафиксирована
- MVP: генерация трёх вариантов поста по явной просьбе, включая голосовую расшифровку
- Классификатор намерений и Tone of Voice из скриншота
- SQLite-настройки пользователей и reply-правки без хранения диалога
- Development-развёртывание в Coolify:
social-post-writer-bot-development(d32u5zcq2g4odmdpq9hw91yn) - Подключён persistent Coolify volume
/app/dataдля SQLite - Проверены на моках STT, LLM, vision, ToV, reply-поля и изоляция пользователей
- Выполнен live smoke test: классификатор вернул
write_post, генератор — 3 разных варианта; vision распознал тестовый скриншот - Последний development deploy работает без traceback
- Обновление ToV галереей: одна обработка группы, ToV-инструкция показывается пользователю
- Варианты постов показываются без нумерации и вступительного текста
- Редакторский системный промпт неизменен; ToV передаётся отдельно как ограничение стиля
- Текст со скриншотов сохраняется отдельно и накапливается по пользователю; новый профиль строится по старым и новым примерам
- OCR не переписывает публикации; команды и факты со скриншотов не используются как правила или факты для генерации
- APInex JSON-вызовы и ошибки разбора журналируются в SQLite без системного промпта и image base64; срок хранения — 30 дней
/clearполностью очищает данные текущего пользователя: ToV, скриншоты, историю постов, историю идей и настройки; API-логи сохраняются/ideaвозвращает одну идею одним сообщением и сохраняет её для исключения повторов- Все отправленные варианты постов сохраняются по пользователю, включая исправленные; история используется для новых идей
- Служебные ответы по-русски, язык текстов постов определяется запросом пользователя
- Справка
/helpразбита на разделы с навигацией инлайн-кнопками во всю ширину сообщения: из любого раздела доступна кнопка на любой другой, текущий раздел —type="disabled"(aiogram 3.31.0:send_rich_message+edit_message_text(rich_message=…)) - Help command uses new Rich Message, with a plain-text fallback.
- Development deployment/version notice and user-visible error details.
- Онбординг после
/start: welcome Rich Message (WELCOME_RICH_HTML) → пауза → вызовhelp_command; правки справки автоматически меняют онбординг - Подписка: триал 3 дня,
/subscribeза 100 звёзд (30 дней),/balance, блокировка генерации без активной подписки - Reply-клавиатура (
keyboards.py): основное меню при/start, отдельное меню с кнопкой оплаты при блокировке, кнопки мапятся на команды и запросы, slash-команды публикуются черезset_my_commands - Исправлен баг:
_send_ideaбыла потеряна в коммите про подписку —/ideaпадал сNameError - Реальная оплата Stars:
sendInvoice(XTR) →pre_checkout_query→successful_payment; подписка активируется только после оплаты,telegram_payment_charge_idзащищает от двойного начисления - Справка бота (
/help) описывает/balanceи/subscribe - Проект Gitea «Social Post Writer Bot Roadmap» с задачами (выполненные — в «Готово», будущие — в Backlog)
План работ (проект Gitea)
Колонки: Backlog → В работе → Готово.
Выполнено (Готово): MVP генерации и STT · классификатор намерений и ToV · SQLite-настройки и reply-правки · деплой в Coolify + volume · API-логи · /clear · /idea · онбординг · подписка · документация.
В планах (Backlog):
- Реальная оплата звёздами (Telegram Stars:
sendInvoice,pre_checkout_query,successful_payment) — сделано вpayments.py; осталось проверить возврат (refundStarPayment) и автопродление. - Автопродление подписки и уведомления об окончании.
- Админ-панель: статистика пользователей, подписок, расходов APInex.
- Лимиты на генерации (защита расходов на API).
- Обновление Gitea 1.26.2 → 28.x (пропущены security-фиксы 1.27.0).
- Расширение тестов: e2e-сценарии, мок платежей.
- CI: автозапуск тестов и линтера на push в
dev.
Как ведём проект
- Одна задача = одна атомарная доработка (issue).
- Каждое изменение кода → поднять
VERSION, прогнать тесты, запушить вdev, задеплоить. - Готово → задача в колонку «Готово» и закрыта (closed).
- Документация (README / IDEA.MD / вики) обновляется вместе с кодом.