Files
tgex-frontend/project.md
2025-11-10 12:07:24 +03:00

232 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# **Общее описание системы**
Система для владельцев каналов позволяющая удобно систематизировать информацию о закупках рекламы и предоставляющая удобный интерфейс для анализа проведенных рекламных компаний
# **Термины и определения**
«Целевой канал» — канал, в который мы приводим подписчиков. Им владеет пользователь (владелец проекта) и именно для него считаем подписки.
«Внешний канал» — сторонний канал, в котором покупаем размещение рекламы выбранного креатива. Пользователю он **не принадлежит**, бот туда **не добавляется**.
«Креатив» — сущность/шаблон текста сообщения, **привязанная к целевому каналу**.
«Закуп» — факт размещения креатива во **внешнем канале**. Для каждого закупа создаётся отдельная invite-ссылка в целевой канал.
CPF — Cost Per Follower — метрика отражающая стоимость привлечения одного подписчика
CPM — Cost Per Mile — метрика отражающая стоимость 1000 просмотров
# **Функционал**
## **1\. Авторизация/регистрация через телеграмм**
Пользователь в веб\-панели нажимает «Войти через Telegram». Его перенаправляет к боту по ссылке вида `https://t.me/example_bot?start=login`. Бот возвращает одноразовую ссылку вида `https://app.example.com/auth/complete?token=<one_time_login_token>`. Сайт обменивает токен на сессию. Если пользователя не существовало — создаётся новый профиль; если существовал — выполняется вход.
### **Сценарии использования**
**Новый пользователь**
1. Пользователь жмёт «Войти через Telegram» на сайте.
2. Редирект в Telegram к боту: `/?start=login`.
3. Создается новый пользователь с данными из события (Telegram ID, username, ФИО)
4. Бот генерирует одноразовый токен для пользователя
5. Бот отправляет кнопку «Войти» со ссылкой вида `/auth/complete?token=....`
6. Пользователь переходит по ссылке и авторизуется.
**Существующий пользователь**
1. Пользователь жмёт «Войти через Telegram».
2. `/?start?login` → бот генерирует ссылку вида `/auth/complete?token=....`
3. Пользователь переходит по ссылке и авторизуется.
## **2\. Подключение целевых каналов**
Пользователь вручную добавляет бота в свой Telegram-канал с правами **администратора** (минимум: право создавать инвайт-ссылки и видеть вступления). Бот получает событие, валидирует, что канал новый/принадлежит пользователю, и регистрирует канал в системе. В веб\-панели доступен список подключённых каналов.
### **Сценарии использования**
**Подключение нового канала**
1. Пользователь в веб\-панели жмёт «Подключить канал» → видит инструкцию «Добавьте бота в нужный канал с правами администратора».
2. Пользователь добавляет бота в канал.
3. Бот получает событие о добавлении в канал
4. Бот создаёт/обновляет запись канала, привязывая её к пользователю.
5. Канал отображается в списке каналов пользователя
**Ошибки (кратко):** нет прав администратора → канал не регистрируется; канал уже подключён → пропускаем, возвращаем «уже в системе».
**Просмотр (и отключение) каналов**
1. Пользователь открывает раздел «Каналы».
2. Система показывает список: название, @username, ссылка
3. Пользователь при необходимости жмёт «Отключить» → система помечает канал как отключённый (и предлагает вручную снять бота из админов в самом канале).
**Результат:** список актуален; отключённые каналы не участвуют в аналитике и создании инвайт-ссылок.
## **3\. Каталог внешних каналов**
### **Описание**
Пользователь ведёт собственный список **внешних каналов** (куда планирует покупать размещения) для целевого канала.
Список можно **редактировать вручную** и **импортировать из Tgstat (Excel)**.
Каждый внешний канал может быть привязан **к одному или нескольким целевым каналам**. При добавлении внешнего канала пользователь указывает, к каким целевым каналам его привязать.
### **Основные действия доступные для каталога каналов**
* Просмотр списка внешних каналов для выбранного целевого канала.
* Добавление/удаление внешнего канала.
* Импорт из Excel (tgstat) с валидацией и дедупликацией.
### **Требования к данным**
Внешний канал и Целевой канал связаны через M2M связь
## **4\. Креативы**
Креатив — это шаблон рекламного сообщения, используемого при закупке рекламы во внешних каналах, содержащий переменную, куда нужно вставить ссылку на целевой канал.
Каждый креатив связан с **одним целевым каналом** и может быть использован в нескольких закупах.
На этапе первой версии поддерживается только **текстовый формат** без медиафайлов.
### **Сценарии использования**
**Создание нового креатива**
1. Пользователь открывает раздел «Креативы» и нажимает «Создать креатив».
2. Указывает:
* Название креатива (для внутреннего использования),
* Текст сообщения,
* Целевой канал, к которому креатив относится.
3. Сохраняет запись.
4. Креатив появляется в списке и доступен для выбора при создании закупа.
**Результат:** создан новый креатив, связанный с выбранным целевым каналом.
**Просмотр и редактирование креативов**
1. Пользователь открывает список креативов.
2. В таблице видны: название, целевой канал, дата создания и количество связанных закупов.
3. При необходимости пользователь может:
* открыть креатив,
* изменить текст,
* переименовать,
* архивировать
* удалить (если не используется в активных закупах).
**Результат:** список актуальных креативов; изменения сохраняются без потери связей с закупами.
## **5\. Закупы**
### **Описание**
**Закуп** — это факт размещения выбранного креатива во внешнем канале.
Для каждого закупа создаётся **уникальная пригласительная ссылка** в целевой канал, по которой отслеживаются подписки.
Закуп связывает между собой три сущности:
* целевой канал (куда ведём трафик),
* внешний канал (где размещаем рекламу),
* креатив (что публикуем).
Пользователь может создавать, редактировать и просматривать закупы, а также видеть их основные показатели эффективности
### **Сценарии использования**
**Создание нового закупа**
1. Пользователь открывает раздел **«Закупы»** и нажимает «Создать закуп».
2. Указывает:
* **Целевой канал**,
* **Внешний канал**,
* **Креатив**,
* Дату размещения (планируемую или фактическую),
* Стоимость закупа (опционально),
* Комментарий,
* Ссылка на рекламное сообщение во внешнем канале (для получение информации о просмотрах).
* Тип ссылки (открытая/с одобрением ботом)
3. После сохранения система создаёт **уникальную публичную или приватную invite-ссылку** (в зависимости от настройки закупа “***тип ссылки***” п.2) в целевой канал через Telegram Bot API.
4. Закуп появляется в списке с возможностью скопировать текст для рекламного сообщений и доступен для просмотра аналитики.
**Результат:** создан новый закуп с уникальной ссылкой для отслеживания переходов и подписок.
**Просмотр и обновление закупов**
1. Пользователь открывает список закупов (таблица).
2. В таблице отображаются: целевой канал, внешний канал, креатив, дата, стоимость, количество подписок.
3. Пользователь может:
* изменить данные закупа (например, обновить стоимость, комментарий или дату),
* удалить закуп (с предупреждением о невозможности восстановления данных),
* архивировать закуп (убрать из статистики и аналитики)
* перейти к просмотру аналитики по конкретному закупу.
## **6\. Обработка события подписки пользователя в целевой канал через Telegram Bot API**
Бот — администратор целевого канала. При вступлении пользователя Telegram шлёт одно из двух событий (`ChatMemberUpdate`, `ChatJoinRequest`) по которым мы **однозначно маппим подписку к закупу**
### **Сценарии использования**
**Подписка по открытой ссылке**
1. Для закупа создана уникальная invite\_link.
2. Пользователь переходит и сразу вступает в канал.
3. Бот получает событие `ChatMemberUpdated`
4. По `invite_link` находим закуп и сохраняем информацию о подписке
5. Инкрементируем метрики закупа (подписки, конверсия).
**Результат:** подписка учтена и привязана к конкретному закупу.
**Запрос на вступление в канла**
1. Для закупа создана уникальная `private_invite_link`.
2. Пользователь переходит по ссылке и отправляет `ChatJoinRequest`.
3. Бот получает событие `ChatJoinRequest`
4. По `invite_link` находим закуп и сохраняем информацию о подписке
5. Инкрементируем метрики закупа (подписки, конверсия).
**Результат:** подписка учтена и привязана к конкретному закупу.
## **7\. Получение информации о кол-ве просмотров через Telegram API**
### **Описание**
Система должна уметь подтягивать **число просмотров** рекламного поста по **ссылке на сообщение** внешнего канала.
Технически корректный способ — через **Telegram API (или MTProto/TDLib)**: для публичных каналов можно читать сообщения и их поле views без добавления бота в канал.
Поддерживаемые форматы ссылок:
* https://t.me/\<username\>/\<message\_id\>
* https://t.me/c/\<internal\_chat\_id\>/\<message\_id\> (для приватных каналов с доступом — см. ограничения ниже)
Метрика хранится как снимки (time series) с периодическим опросом (раз в час), чтобы видеть динамику добора просмотров.
💡Тут надо подумать, как частно нужно получать эти данные и как их надо агрегировать, так как у телеграмма как-то заковыристо считается и показывается кол-во просмотров
### **Сценарии использования**
**Успешное получение просмотров (публичный канал)**
1. В карточке закупа пользователь добавляет ссылку на пост (t.me/\<username\>/\<message\_id\>).
2. Бэкенд через TDLib/MTProto вызывает channels.getMessages и читает поле views.
3. Сохраняет снэпшот: views=12345, fetched\_at=....
4. Планировщик повторяет опрос по расписанию, строится кривая добора просмотров.
**Результат:** в аналитике закупа и сводках отображается актуальный счётчик просмотров и стоимость подписчика с учётом просмотров (пока — только CPS/CPF, просмотры — справочно).
**Недоступно (приватный канал / нет прав / битая ссылка)**
1. Пользователь добавляет ссылку t.me/c/.../123.
2. Запрос через TDLib возвращает «нет доступа» или «не найдено».
3. Система помечает источник как unavailable и предлагает:
* добавить доступ (пригласить учётку чтения), **или**
* указать просмотры вручную, **или**
* загрузить из отчёта Tgstat/экселя.
**Результат:** закуп помечен как недоступный для авто-сбора; допускается ручной ввод/импорт.
## **8\. Просмотр аналитики по целевым каналам, внешним каналам, креативам и закупам**
* Отображать средний CPF в списках закупов, креативов и внешних каналов
* Отображать средний CPM в списках закупов, креативов и внешних каналов
* Отображать столбчатую диаграмму с объемом закупок с группировкой по дате (день, неделя, месяц, квартал, год) и возможностью фильтрации по целевым каналам на отдельном экране “Аналитика” → “Затраты”