From fe0e40dba156580d2d30f7192e15eb339572e956 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Tue, 6 Oct 2026 19:11:27 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D0=BE=D0=BB=D0=BD=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=B2=D0=B8=D0=BA=D0=B8=20=E2=80=94=20Home,=20User=20Guide,=20?= =?UTF-8?q?Developer=20Guide,=20Subscription,=20Deployment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Deployment.md | 125 +++++++++++++++++++++++++++++++++ Developer-Guide.md | 167 +++++++++++++++++++++++++++++++++++++++++++++ Home.md | 53 +++++++------- Subscription.md | 121 ++++++++++++++++++++++++++++++++ User-Guide.md | 104 ++++++++++++++++++++++++++++ _Sidebar.md | 11 +++ 6 files changed, 551 insertions(+), 30 deletions(-) create mode 100644 Deployment.md create mode 100644 Developer-Guide.md create mode 100644 Subscription.md create mode 100644 User-Guide.md create mode 100644 _Sidebar.md diff --git a/Deployment.md b/Deployment.md new file mode 100644 index 0000000..74131d9 --- /dev/null +++ b/Deployment.md @@ -0,0 +1,125 @@ +# Деплой + +## Инфраструктура + +| Компонент | Значение | +|---|---| +| **Gitea** | `admin/social-post-writer-bot`, ветка `dev` (push → автодеплой) | +| **Coolify проект** | `Social Post Writer Bot` | +| **Coolify окружение** | `development` | +| **Coolify приложение** | `social-post-writer-bot-development` (`d32u5zcq2g4odmdpq9hw91yn`) | +| **Сервер** | `spb-easy-dale` | +| **Бот** | [@post_master_bot](https://t.me/post_master_bot) | + +--- + +## Деплой-скрипт + +`.hermes/scripts/deploy.sh` ставит деплой в очередь через Coolify API: + +```bash +cd /root/.hermes/projects/social-post-writer-bot +bash .hermes/scripts/deploy.sh +``` + +Скрипт делает `POST /api/v1/deploy?uuid=&force=false`. + +> Coolify API **не имеет** endpoint `/applications/{uuid}/deploy` — деплой запускается именно через `/deploy?uuid=...`. + +Переменные скрипта: +- `APP_UUID` (по умолчанию `d32u5zcq2g4odmdpq9hw91yn`) +- `FORCE` (по умолчанию `false`) +- `COOLIFY_API` (по умолчанию `http://10.19.0.2:8000/api/v1`) + +Успешный ответ: +```json +{"deployments":[{"message":"Application ... deployment queued.","deployment_uuid":"..."}]} +``` + +--- + +## Проверка статуса и логов + +```bash +COOLIFY_TOKEN=$(grep '^COOLIFY_TOKEN=' /root/.hermes/.env | cut -d= -f2-) + +# статус +curl -sS -H "Authorization: Bearer $COOLIFY_TOKEN" \ + "http://10.19.0.2:8000/api/v1/applications/d32u5zcq2g4odmdpq9hw91yn" + +# логи +curl -sS -H "Authorization: Bearer $COOLIFY_TOKEN" \ + "http://10.19.0.2:8000/api/v1/applications/d32u5zcq2g4odmdpq9hw91yn/logs" +``` + +Успешный запуск в логах: +``` +INFO:__main__:Development deploy notice sent: version=0.1.0+19 +INFO:aiogram.dispatcher:Start polling +INFO:aiogram.dispatcher:Run polling for bot @post_master_bot id=2201652808 - 'Мастер постинга' +``` + +--- + +## Переменные окружения (Coolify) + +| Переменная | Назначение | +|---|---| +| `BOT_TOKEN` | токен Telegram-бота | +| `APINEX_API_KEY` | ключ APInex | +| `APINEX_STT_MODEL` | модель STT (дефолт `nova-2`) | +| `APINEX_INTENT_CLASSIFIER_MODEL` | модель классификации намерений | +| `APINEX_POST_WRITER_MODEL` | модель генерации постов/идей | +| `APINEX_IMAGE_TONE_MODEL` | модель vision (OCR скриншотов, ToV) | +| `BOT_DB_PATH` | путь к SQLite (`/app/data/social_writer.sqlite3`) | +| `DEPLOY_ENV` | `development` — включает уведомления о версии | +| `DEV_CHAT_ID` | чат для уведомлений о новой версии | + +Секреты хранятся **только** в Coolify, в репозиторий не попадают. + +--- + +## Версионирование + +- Версия лежит в файле `VERSION` (сейчас `0.1.0+19`). +- При каждом изменении кода версию нужно **поднять**. +- При `DEPLOY_ENV=development` бот сравнивает сохранённую версию с текущей и, если они различаются, шлёт в `DEV_CHAT_ID`: + > 🚀 Бот обновлён + > Версия: X + +> ⚠️ Если версию не поднять, уведомление **не отправится** — `notify_development_deploy` делает `return` при совпадении. + +--- + +## Docker + +```dockerfile +FROM python:3.12-slim +ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY bot.py apinex_client.py user_store.py help_message.py VERSION ./ +CMD ["python", "bot.py"] +``` + +> Важно: если в `bot.py` появляется новый импорт (например, `sqlite3`), он должен быть доступен в образе — иначе контейнер упадёт с `NameError` при старте. + +--- + +## Данные + +- SQLite: `/app/data/social_writer.sqlite3` +- Persistent volume: `d32u5zcq2g4odmdpq9hw91yn-social-post-writer-dev-data` → монтируется в `/app/data` +- WAL-режим, `busy_timeout = 10000` + +--- + +## Типичные проблемы + +| Симптом | Причина | Решение | +|---|---|---| +| `exited:unhealthy`, `NameError` в логах | забыт импорт (напр. `sqlite3`) | добавить импорт, поднять `VERSION`, redeploy | +| Нет уведомления о новой версии | версия не изменена | поднять `VERSION` | +| Деплой не запускается | неверный `COOLIFY_TOKEN` или uuid | проверить токен/уuid | +| `no such table: subscriptions` | БД создана до миграции | вызывается `init_db()` при старте — проверьте, что volume смонтирован | diff --git a/Developer-Guide.md b/Developer-Guide.md new file mode 100644 index 0000000..657ddf7 --- /dev/null +++ b/Developer-Guide.md @@ -0,0 +1,167 @@ +# Разработчику + +## Структура + +``` +bot.py — роутинг, команды, обработка сообщений (aiogram 3.x) +apinex_client.py — клиент APInex (LLM, STT, vision), промпты, логирование вызовов +user_store.py — SQLite: пользователи, ToV, посты, идеи, API-логи, подписки +help_message.py — Rich Message справка (HTML + plain fallback) +VERSION — версия релиза +Dockerfile — python:3.12-slim +requirements.txt — зависимости +tests/ — юнит-тесты (unittest) +``` + +--- + +## Потоки обработки + +### Текстовый запрос +``` +handle_text → _classify_and_respond + ├─ /help? → help_command (без проверки подписки) + ├─ _check_subscription (блокировка, если нет подписки) + ├─ classify_intent (APInex LLM) → intent + │ ├─ help → help_command + │ ├─ generate_ideas → generate_ideas → _send_idea + │ └─ write_post / revise_post → generate_posts → _send_three_posts + └─ typing_status (индикатор «печатает») +``` + +### Голосовое +``` +transcribe_voice → _process_voice → transcribe_audio (APInex STT) → _classify_and_respond +``` + +### Скриншоты (Tone of Voice) +``` +update_tone_from_image → _handle_image_message + ├─ _collect_media_group (собирает галерею, ждёт MEDIA_GROUP_COLLECT_SECONDS = 1.0) + ├─ extract_posts_from_images (APInex vision, inline base64) + ├─ add_post_samples (накапливает по пользователю) + └─ create_tone_profile → save_tone_of_voice → показывает стиль +``` + +--- + +## Ключевые функции + +### `bot.py` + +| Функция | Что делает | +|---|---| +| `start(message)` | Онбординг (3 сообщения) + создание триала | +| `handle_command_text` | Роутинг: `/help`, `/start`, `/clear`, `/idea`, `/balance`, `/subscribe` | +| `_classify_and_respond` | Ядро: проверка подписки → классификация → генерация | +| `_check_subscription` | Проверяет активную подписку; если нет — показывает статус и блокирует | +| `_show_subscription_info` | Формирует сообщение о статусе (триал / подписка / истёк) | +| `balance_command` | `/balance` — статус подписки | +| `subscribe_command` | `/subscribe` — активация подписки (100 звёзд) | +| `clear_command` | `/clear` — сброс данных + обнуление подписки | +| `help_command` | `/help` — Rich Message с fallback на plain text | +| `typing_status` | Индикатор «печатает», обновляется каждые 4 сек | +| `report_error` | Понятная ошибка пользователю; секреты и URL вырезаются | +| `split_text` | Разбивает длинный текст по лимиту (4000) по границам слов | + +### `user_store.py` + +| Функция | Что делает | +|---|---| +| `init_db` | Создаёт таблицы (см. ниже) | +| `ensure_subscription` | Создаёт запись подписки с триалом (`INSERT OR IGNORE`) | +| `activate_subscription` | Активирует/продлевает подписку на 30 дней | +| `deactivate_subscription` | `is_active = 0` | +| `is_subscribed` | Проверяет: запись есть, `is_active = 1`, срок не истёк | +| `subscription_row` | Возвращает строку подписки | +| `_days_until` | Сколько дней осталось; `-1` если истёкло/отключено | +| `add_post_samples` | Накапливает образцы постов (без дублей) | +| `save_generated_posts` | Сохраняет сгенерированные посты с `origin` | +| `save_idea` / `get_idea_history` | История идей | +| `save_api_call_log` | Пишет JSON лог вызова APInex | +| `clear_user_data` | Полный сброс данных пользователя | + +### `apinex_client.py` + +| Функция | Что делает | +|---|---| +| `classify_intent` | Определяет намерение: `write_post` / `revise_post` / `generate_ideas` / `help` | +| `generate_posts` | Генерирует 3 варианта поста | +| `generate_ideas` | Генерирует одну идею | +| `extract_posts_from_images` | Распознаёт тексты постов на скриншотах (vision) | +| `create_tone_profile` | Строит/обновляет профиль ToV | +| `transcribe_audio` | STT расшифровка голосовых | +| `chat_text` | Базовый вызов LLM через APInex | + +--- + +## База данных + +SQLite: `/app/data/social_writer.sqlite3` (persistent volume Coolify). + +| Таблица | Назначение | +|---|---| +| `users` | `telegram_user_id`, `tone_of_voice` | +| `user_post_samples` | Распознанные тексты постов со скриншотов | +| `generated_posts` | История сгенерированных постов (`origin`: generated/revised) | +| `generated_ideas` | История идей (для исключения повторов) | +| `api_call_logs` | JSON логи вызовов APInex + ошибки (30 дней) | +| `subscriptions` | Подписки и триалы | + +Схему `subscriptions` см. в [Подписка](Subscription.md). + +--- + +## Промпты и модели + +Модели задаются переменными Coolify (дефолты): +- `APINEX_STT_MODEL` → `nova-2` (STT) +- `APINEX_INTENT_CLASSIFIER_MODEL` → `gemini-3.8-flash` (классификация намерений) +- `APINEX_POST_WRITER_MODEL` → `gemini-3.8-flash` (генерация/правка постов, идеи) +- `APINEX_IMAGE_TONE_MODEL` → `gemini-3.8-flash` (vision — OCR скриншотов, ToV) +- `APINEX_API_KEY` — общий секрет + +**Важно про промпты:** +- Системный промпт редактора **неизменен**. +- ToV пользователя передаётся **отдельно как входные данные** — он может влиять на стиль, но не переопределяет системные правила и не подставляет факты. +- OCR-текст со скриншотов — это образцы стиля, а не команды. + +--- + +## Логирование вызовов + +Каждый вызов APInex пишется в `api_call_logs`: +- `stage` (классификация / генерация / OCR / STT / idea) +- `model`, `prompt_sha256`, `prompt name` +- `request_json`, `response_json` +- `status_code`, `error` + +**Не пишется:** системные промпты целиком (только имя + SHA-256), base64 изображений, бинарное аудио, API-ключи. + +Хранение — **30 дней**. Содержимое логов считается приватными данными пользователя. + +--- + +## Тесты + +```bash +python -m unittest discover -s tests -v +``` + +49 тестов. Покрытие: STT, LLM, vision, ToV, reply-поля, изоляция пользователей, API-логи, Rich help, онбординг, подписки. + +Тесты подписок (`SubscriptionTests`): +- таблица `subscriptions` создаётся +- `/start` создаёт триал +- `/subscribe` активирует 30 дней +- `/balance` показывает статус +- блокировка при истёкшей подписке +- `/clear` обнуляет подписку + +--- + +## Правила языка + +- Служебные сообщения боту → **всегда русский**. +- Текст поста → язык явного запроса пользователя. +- Дословный текст технической ошибки может остаться на языке оригинала. diff --git a/Home.md b/Home.md index fbacabf..d1f0784 100644 --- a/Home.md +++ b/Home.md @@ -2,10 +2,10 @@ **Телеграм-бот** для генерации постов для соцсетей. По запросу пользователя готовит три варианта текста, адаптированных под его Tone of Voice. -- Бот: [@post_master_bot](https://t.me/post_master_bot) -- Репозиторий: `admin/social-post-writer-bot` -- Стек: Python 3.12, aiogram 3.x, aiohttp, SQLite, APInex (LLM / STT / vision) -- Деплой: Coolify, окружение `development`, приложение `social-post-writer-bot-development` +- **Бот:** [@post_master_bot](https://t.me/post_master_bot) +- **Репозиторий:** `admin/social-post-writer-bot` +- **Стек:** Python 3.12, aiogram 3.x, aiohttp, SQLite, APInex (LLM / STT / vision) +- **Деплой:** Coolify, окружение `development`, приложение `social-post-writer-bot-development` --- @@ -13,7 +13,7 @@ | Возможность | Описание | |---|---| -| **Генерация постов** | На явную просьбу или реплай-правку — 3 отдельных варианта сообщениями | +| **Генерация постов** | На явную просьбу или реплай-правку — **3 отдельных варианта** сообщениями | | **Tone of Voice** | Пришли скриншоты своих постов — бот распознаёт тексты и накапливает твой стиль | | **Голосовой ввод** | Голосовые сообщения расшифровываются (APInex STT) и работают как текст | | **Идеи** | «предложи тему» или `/idea` — одна идея (заголовок, угол, зачем) | @@ -21,20 +21,25 @@ --- -## Команды +## Быстрый старт -| Команда | Что делает | Без подписки | -|---|---|---| -| `/start` | Онбординг (3 сообщения) + создание триала | ✅ | -| `/help` | Подробная справка | ✅ | -| `/balance` | Статус подписки / триала | ✅ | -| `/subscribe` | Активация подписки (100 звёзд, 30 дней) | ✅ | -| `/idea` | Одна идея для поста | ❌ | -| `/clear` | Полный сброс данных + обнуление подписки | ✅ | +1. Напиши боту `/start` — получишь онбординг и пробный период на 3 дня. +2. Опиши тему: «напиши пост про запуск нового продукта». +3. Получишь три варианта. Не нравится — ответь реплаем: «сделай короче». +4. Хочешь, чтобы посты были в твоём стиле — пришли скриншоты своих публикаций. --- -## Как работает (для разработчиков) +## Разделы вики + +- **[Пользователю](User-Guide.md)** — сценарии, команды, подписка, FAQ +- **[Разработчику](Developer-Guide.md)** — архитектура, потоки, функции, БД +- **[Деплой](Deployment.md)** — Coolify, переменные, деплой-скрипт, уведомления +- **[Подписка](Subscription.md)** — модель, таблица БД, жизненный цикл + +--- + +## Ключевые файлы репозитория ``` bot.py — роутинг, команды, обработка сообщений @@ -42,20 +47,8 @@ apinex_client.py — клиент APInex (LLM, STT, vision), промпты, л user_store.py — SQLite: пользователи, ToV, посты, идеи, API-логи, подписки help_message.py — Rich Message справка VERSION — версия релиза +Dockerfile — python:3.12-slim +tests/ — юнит-тесты (unittest) ``` -**Потоки:** -- Текст → `classify_intent` → генерация поста / идеи -- Голос → `transcribe_audio` (STT) → как текст -- Скриншоты → `extract_posts_from_images` (vision) → накопление ToV - -Подробнее — в [README.md](../../src/branch/main/README.md) и `IDEA.MD` репозитория. - ---- - -## Данные - -- SQLite: `/app/data/social_writer.sqlite3` (persistent volume Coolify). -- Per-user: ToV, образцы постов, истории постов и идей. Диалоги и исходные картинки **не** хранятся. -- API-логи (JSON запросов/ответов) — 30 дней, без системных промптов и base64. -- `/clear` стирает пользовательские данные и обнуляет подписку; API-логи остаются. +Полная документация — в [README.md](../../src/branch/main/README.md) и `IDEA.MD` репозитория. diff --git a/Subscription.md b/Subscription.md new file mode 100644 index 0000000..9807e35 --- /dev/null +++ b/Subscription.md @@ -0,0 +1,121 @@ +# Подписка + +## Модель + +**Триал 3 дня → подписка 30 дней за 100 звёзд (Telegram Stars).** + +Константы в `user_store.py`: +```python +TRIAL_DAYS = 3 +SUBSCRIPTION_MONTH_DAYS = 30 +SUBSCRIPTION_PRICE_STARS = 100 +``` + +--- + +## Таблица `subscriptions` + +| Колонка | Смысл | +|---|---| +| `telegram_user_id` | PK, id пользователя | +| `trial_started_at` | момент создания (SQLite `CURRENT_TIMESTAMP`, UTC-нейтральный) | +| `last_paid_at` | конец оплаченного периода; `NULL` = ещё триал | +| `is_active` | 1 — активна, 0 — отключена | +| `monthly_days` | длительность оплаченного периода (30) | +| `updated_at` | время последнего изменения | + +--- + +## Жизненный цикл + +1. **`/start`** → `ensure_subscription` → триал 3 дня, `is_active = 1`. +2. Генерация постов и идей доступна, пока `_days_until > 0`. +3. Триал/подписка кончилась → `_check_subscription` блокирует генерацию, показывает сообщение и предлагает `/subscribe`. +4. **`/subscribe`** → `ensure_subscription` (если записи нет) → `activate_subscription(months=1)` → +30 дней от момента оплаты, `is_active = 1`. +5. **`/clear`** → `deactivate_subscription` → `is_active = 0`; для продолжения нужен `/subscribe`. + +**Расчёт дней (`_days_until`):** +- Триал: `trial_started_at + TRIAL_DAYS` +- Подписка: `last_paid_at` +- Возвращает полные дни; если `is_active = 0` или срок истёк — `-1` + +--- + +## Что доступно без подписки + +| Команда / действие | Доступно | +|---|---| +| `/help` | ✅ | +| `/start` | ✅ | +| `/balance` | ✅ | +| `/subscribe` | ✅ | +| `/clear` | ✅ | +| Генерация поста | ❌ | +| `/idea` | ❌ | +| Голосовой ввод → генерация | ❌ | +| Скриншоты → ToV | ❌ | + +Логика: `/help` обрабатывается **до** проверки подписки и до классификации — пользователь не остаётся в тупике. + +--- + +## Сообщения + +**`/balance` при активном триале:** +> Триал активен — осталось N дн. +> Когда триал закончится, нужно оплатить подписку — команда /subscribe. + +**`/balance` при активной подписке:** +> Подписка активна — осталось N дн. +> Следующее списание через N дн. + +**При истёкшем периоде:** +> Твой период (триал или подписка) истёк. Оплати /subscribe, чтобы продолжить. Стоимость — 100 звёзд в месяц. +> Чтобы активировать — пришли 100 звёзд командой /subscribe. *(если ещё не было оплат)* + +**`/subscribe`:** +> Активирую подписку на 30 дней. Для оплаты пришли 100 звёзд в этом чате. +> Жду оплаты... +> Подписка активирована на 30 дн. Спасибо за оплату 100 звёзд! +> Теперь доступны генерация постов, идей и голосовые. + +--- + +## ⚠️ Про оплату звёздами + +Приём звёзд — **имитация**. Бот пишет «пришли 100 звёзд» и **сразу** активирует подписку, не проводя реальный платёж. + +Для настоящих платежей нужен отдельный invoicing-флоу: +- Telegram Payments API (`sendInvoice` со звёздами / `createInvoiceLink`) +- Обработка `pre_checkout_query` и `successful_payment` +- Начисление подписки только после подтверждённой оплаты + +В этой версии не реализовано. + +--- + +## Часовые пояса + +SQLite `CURRENT_TIMESTAMP` возвращает UTC **без** часового пояса. Код приводит все значения к naive UTC перед сравнением: + +```python +def utc(value: str) -> datetime.datetime: + dt = datetime.datetime.fromisoformat(value.replace("Z", "+00:00")) + if dt.tzinfo is not None: + return dt.astimezone(datetime.timezone.utc).replace(tzinfo=None) + return dt +``` + +Это убирает сдвиги при сравнении `expires` и `now`. + +--- + +## Тесты + +`SubscriptionTests` в `tests/test_writer_features.py` — 6 тестов: +1. таблица `subscriptions` создаётся +2. `/start` создаёт триал +3. `/subscribe` активирует 30 дней +4. `/balance` показывает статус +5. генерация блокируется при истёкшей подписке +6. `/clear` обнуляет подписку diff --git a/User-Guide.md b/User-Guide.md new file mode 100644 index 0000000..85d8b58 --- /dev/null +++ b/User-Guide.md @@ -0,0 +1,104 @@ +# Пользователю + +## Онбординг + +После `/start` бот присылает **три сообщения** с небольшой паузой: + +1. **Что делаю** — «Привет! Я помогаю писать посты для соцсетей. Расскажи, о чём нужен пост — а я верну три варианта: короткий, развёрнутый и с призывом к действию.» +2. **Примеры запросов** — написать пост / официальный тон / реплай-правка. +3. **Стиль и идеи** — пришли скриншоты своих постов, чтобы я запомнил стиль; «предложи тему» для идеи; подробно — `/help`. + +Одновременно `/start` создаёт пробный период на **3 дня**. + +--- + +## Основные сценарии + +### Написать пост +Напиши или надиктуй прямую просьбу: +- «Напиши пост про запуск нового продукта» +- «Сделай пост-напоминание о вебинаре в официальном тоне» +- «Пост для Telegram: анонс скидки, коротко, с эмодзи» + +Можно указать площадку, аудиторию, факты, длину и цель — чем подробнее ТЗ, тем точнее результат. + +**Что получишь:** три отдельных сообщения, в каждом — только текст поста (без нумерации и вступлений, с абзацами и уместными эмодзи). + +### Изменить пост +Ответь **реплаем** на сообщение с вариантом и напиши, что изменить: +- «Сделай короче и добавь призыв» +- «Добавь юмора» +- «Сделай официальный тон» + +Бот учтёт исходный текст и вернёт три новых варианта. + +### Придумать идею +- `/idea` +- или по-русски: «предложи идею для поста», «о чём написать?», «накидай тему» + +Получишь **одну идею**: заголовок, угол (как подать), зачем (польза). Идеи не повторяются — бот помнит, что уже предлагал. + +### Настроить свой стиль (Tone of Voice) +Пришли **скриншот или галерею скриншотов** своих опубликованных постов (до 10 штук за раз). + +Бот: +1. Распознаёт тексты постов (vision). +2. Сохраняет их как образцы и дополняет предыдущие. +3. Пересобирает профиль Tone of Voice. +4. Показывает итоговый стиль. + +**Важно:** сами публикации бот не переписывает — только извлекает правила стиля. Команды и факты со скриншотов не становятся правилами для генерации. + +### Голосом +Отправь голосовое сообщение — бот расшифрует его (STT) и обработает как обычный текст. + +--- + +## Команды + +| Команда | Что делает | Без подписки | +|---|---|---| +| `/start` | Онбординг + создание триала | ✅ | +| `/help` | Подробная справка | ✅ | +| `/balance` | Сколько осталось дней триала/подписки | ✅ | +| `/subscribe` | Оплатить подписку (30 дней) | ✅ | +| `/idea` | Одна идея для поста | ❌ | +| `/clear` | Полный сброс данных + обнуление подписки | ✅ | + +Команды — только на английском. Русские фразы («придумай идею», «о чём написать?») тоже работают. + +--- + +## Подписка + +- **Триал:** 3 дня бесплатно с момента первого `/start`. +- **Дальше:** 30 дней за **100 звёзд** (команда `/subscribe`). +- **Статус:** `/balance` покажет, сколько дней осталось и когда списание. + +Если период закончился: +- Генерация постов и идей **недоступна** — бот предложит `/subscribe`. +- `/help`, `/balance`, `/subscribe`, `/start`, `/clear` работают **всегда**. + +Подробнее — в разделе [Подписка](Subscription.md). + +--- + +## Что бот помнит + +- Твой **Tone of Voice** (из скриншотов). +- **Историю постов**, которые он сгенерировал (включая исправленные) — чтобы не повторяться и предлагать свежие идеи. +- **Историю идей** — чтобы не предлагать одно и то же. + +Что бот **НЕ** хранит: +- Историю диалогов. +- Исходные изображения (скриншоты) — только распознанный текст. + +Команда `/clear` удаляет все твои данные и обнуляет подписку. Технические API-логи при этом сохраняются (они нужны для отладки). + +--- + +## Ошибки и обратная связь + +- Пока идёт обработка, бот показывает **«печатает»**. +- Если что-то пошло не так, придёт сообщение: «❌ Не получилось: {этап}. Причина: …». Секреты и ссылки в тексте скрыты. +- Служебные сообщения — **всегда на русском**. Язык поста — тот, который ты запросил. diff --git a/_Sidebar.md b/_Sidebar.md new file mode 100644 index 0000000..8422ea4 --- /dev/null +++ b/_Sidebar.md @@ -0,0 +1,11 @@ +## Навигация + +- **[Главная](Home.md)** +- **[Пользователю](User-Guide.md)** +- **[Разработчику](Developer-Guide.md)** +- **[Подписка](Subscription.md)** +- **[Деплой](Deployment.md)** + +--- + +**Бот:** [@post_master_bot](https://t.me/post_master_bot)