Compare commits
8
Commits
e9123274a6
...
cdff37a183
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdff37a183 | ||
|
|
376f26b2eb | ||
|
|
2b78351707 | ||
|
|
48a82bd0b3 | ||
|
|
741a27eb27 | ||
|
|
f1712d6db0 | ||
|
|
089c59bc68 | ||
|
|
de638bb4d0 |
No files matched your search
@@ -185,6 +185,8 @@ onboarding. В «Подписке» сразу отображаются тип
|
||||
|
||||
---
|
||||
|
||||
- **Статистика бота:** команда `/stats` доступна в топике «Статистика» группы «Мастер постинга: Админка» (`chat_id=-1008001427913`, `message_thread_id=5`). Отчёт отправляется Rich Message таблицами с колонками «Сегодня», «7 дней», «30 дней», «Всё время». События хранятся по Telegram user id в отдельной SQLite `/app/data/analytics.sqlite3` на persistent volume; текст/медиа пользователей не сохраняются. В режиме генерации учитываются генерации постов, идеи, правки и типы сообщений; в обучении — только типы сообщений. Групповой роутер ограничен аналитическим топиком; доступ к отчёту ограничивается `OWNER_USER_ID`, если переменная задана.
|
||||
|
||||
## Архитектура кода
|
||||
|
||||
```
|
||||
@@ -192,7 +194,8 @@ bot.py — роутинг, команды, обработка со
|
||||
payments.py — оплата Stars: sendInvoice, pre_checkout_query, successful_payment, защита от двойного списания
|
||||
apinex_client.py — клиент APInex (LLM, STT, vision), промпты, логирование вызовов
|
||||
user_store.py — SQLite: пользователи, ToV, посты, идеи, API-логи, подписки
|
||||
raw_updates.py — отдельная SQLite-БД сырых входящих Telegram Update для development
|
||||
analytics.py — отдельная SQLite-аналитика по Telegram user id; события активности и отчёты
|
||||
raw_updates.py — отдельная SQLite-БД сырых входящих Telegram Update (работает и в production)
|
||||
support.py — поддержка: личка ↔ персональный топик в группе операторов
|
||||
keyboards.py — клавиатуры главного меню и режимов; маппинг кнопок на команды
|
||||
help_message.py — Rich Message: `WELCOME_RICH_HTML` (онбординг) + `HELP_SECTIONS`/`help_view()` (справка с кнопками), plain fallback
|
||||
@@ -316,11 +319,13 @@ SUBSCRIPTION_PRICE_STARS = 100
|
||||
|
||||
## Данные и хранилище
|
||||
|
||||
- **SQLite:** `/app/data/social_writer.sqlite3` (persistent Coolify volume).
|
||||
- SQLite `/app/data/social_writer.sqlite3` (persistent Coolify volume) — бизнес-данные пользователей, подписки и платежи.
|
||||
- SQLite `/app/data/analytics.sqlite3` (тот же persistent volume) — append-only события по `telegram_user_id`, режиму, действию и типу входящего сообщения; без пользовательского текста и медиа. Общий отчёт агрегируется запросами, отдельные дублирующие сводки не хранятся.
|
||||
- Команда `/stats` работает в форуме группы «Мастер постинга: Админка», топик `5`, и показывает таблицы за сегодня, последние 7 дней, последние 30 дней и всё время. Счётчики генерации: посты, идеи, правки, сообщения и типы сообщений; обучение — типы входящих сообщений.
|
||||
- **Постоянное хранилище dev:** volume `d32u5zcq2g4odmdpq9hw91yn-social-post-writer-dev-data` смонтирован в `/app/data` контейнера на сервере Coolify `spb-easy-dale` (`31.129.103.242`). Сервер приложения и сервер управления Coolify могут быть разными: сначала смотри назначенный приложению Server в записи Coolify, затем проверяй контейнер именно на нём. Не ищи контейнер только на хосте Coolify.
|
||||
- **Где смотреть ошибки:** подключись к `spb-easy-dale`, найди контейнер по имени `d32u5zcq2g4odmdpq9hw91yn-*` командой `docker ps`, затем смотри его stdout/stderr через `docker logs --since 24h <container>`. После деплоя ротационный файл приложения будет доступен как `/app/data/bot.log` (до 5 MiB и 3 архива); он сохраняется в указанном persistent volume при пересоздании контейнера. До деплоя изменения логирования ещё не действуют.
|
||||
- **API-журнал ошибки:** открой `/app/data/social_writer.sqlite3`, таблицу `api_call_logs`; записи связываются по `operation_id` и времени. Файл/БД находятся в volume на сервере приложения, не в локальном checkout и не на сервере Coolify, если это другой хост.
|
||||
- **Сырые Telegram Update (только dev):** отдельная БД `/app/data/bot_updates.sqlite3`, таблица `raw_updates`; хранится JSON входящего Update, `update_id`, тип события и время получения. Поиск по `update_id`: `SELECT payload FROM raw_updates WHERE update_id = ?`. Записи старше 30 дней удаляются при старте dev-бота и при сохранении новых апдейтов. Чувствительные значения маскируются; Update могут содержать тексты и персональные данные пользователей. В production middleware не подключается и БД не создаётся.
|
||||
- **Сырые Telegram Update (все окружения, включая production):** отдельная БД `/app/data/bot_updates.sqlite3`, таблица `raw_updates`; хранится JSON входящего Update, `update_id`, тип события и время получения. Поиск по `update_id`: `SELECT payload FROM raw_updates WHERE update_id = ?`. Записи старше 30 дней удаляются при старте бота и при сохранении новых апдейтов. Чувствительные значения маскируются; Update могут содержать тексты и персональные данные пользователей. Middleware подключается всегда: в production это единственный способ посмотреть события из групп администрирования и поддержки.
|
||||
- **Обращения в поддержку:** таблица `support_topics` в той же рабочей БД — `telegram_user_id` (PK), `thread_id` топика в группе операторов, `is_active`, время создания и обновления. Один пользователь — один топик; при завершении запись не удаляется, только снимается `is_active`, поэтому повторное обращение продолжается с сохранённой историей. Если топик удалили вручную в Telegram, при следующем сообщении он создаётся заново.
|
||||
- **Per-user данные:** профиль аккаунта/ToV, текстовые обучающие заметки, образцы постов со скриншотов, история сгенерированных постов и идеи. В «Обучении» текст/голос/скриншоты накапливают и обновляют профиль, а не запускают генерацию. История диалогов и исходные изображения **не сохраняются**.
|
||||
- **Пустые ответы APInex:** при пустом `content` бот делает до двух повторов; третий запрос добавляет `reasoning_effort: low`. Если ответ всё ещё пустой, операция завершается ошибкой и каждая попытка попадает в API-журнал. Ошибки HTTP автоматически не повторяются. APInex документирует `low`, но не режим отключения reasoning; поддержка параметра зависит от модели.
|
||||
@@ -332,6 +337,17 @@ SUBSCRIPTION_PRICE_STARS = 100
|
||||
|
||||
---
|
||||
|
||||
## Статистика и аналитика
|
||||
|
||||
- `/stats` доступна в админском форуме, топик «Статистика» (`chat_id=-1008001427913`, `message_thread_id=5`). Отчёт уходит в этот же топик Rich Message-таблицами.
|
||||
- По умолчанию `/stats` показывает данные за всё время; отчёт содержит сопоставимые колонки «Сегодня», «7 дней», «30 дней», «Всё время».
|
||||
- Таблицы: активные пользователи; генерации постов, идеи, правки и сообщения; распределение типов сообщений в генерации; сообщения и типы сообщений в обучении.
|
||||
- Периоды рассчитываются как текущие 24 часа, последние 7×24 часа, последние 30×24 часа и весь срок хранения соответственно.
|
||||
- События хранятся в `/app/data/analytics.sqlite3`, отдельной SQLite на persistent volume. Запись привязана к `telegram_user_id`; общие значения агрегируются запросом без дублирующих таблиц.
|
||||
- Сохраняются только режим, тип действия, тип входящего сообщения и время. Содержимое сообщений, изображений и аудио аналитикой не сохраняется.
|
||||
- В генерации учитываются действие генерации поста, идеи, правки и входящие сообщения по типам. В обучении — только входящие сообщения по типам.
|
||||
- Вход в отчёт проверяет точные `chat_id` и `message_thread_id`; при заданном `OWNER_USER_ID` команда доступна только этому Telegram-пользователю.
|
||||
|
||||
## Команды
|
||||
|
||||
| Команда | Что делает | Режим |
|
||||
@@ -342,6 +358,7 @@ SUBSCRIPTION_PRICE_STARS = 100
|
||||
| `/post`, `/idea` | Самостоятельный пост по обученному профилю; идея | Генерация; для генерации нужна подписка |
|
||||
| `/balance`, `/subscribe` | Статус или оплата Stars | Подписка |
|
||||
| `/support` | Написать в поддержку | Любой |
|
||||
| `/stats` | Отчёт аналитики в админском топике | Топик «Статистика» |
|
||||
|
||||
В режиме «Генерация» русские фразы («придумай идею», «о чём написать?») работают как `/idea`.
|
||||
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ TONE_PROFILE_SYSTEM_PROMPT = """Составь или обнови единый
|
||||
"""
|
||||
|
||||
|
||||
def _setting(name: str, default: str = "gemini-3.8-flash") -> str:
|
||||
def _setting(name: str, default: str = "free/gemini-3.8-flash") -> str:
|
||||
return os.getenv(name, "").strip() or default
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user