feat: all project setup
This commit is contained in:
231
project.md
Normal file
231
project.md
Normal file
@@ -0,0 +1,231 @@
|
||||
# **Общее описание системы**
|
||||
|
||||
Система для владельцев каналов позволяющая удобно систематизировать информацию о закупках рекламы и предоставляющая удобный интерфейс для анализа проведенных рекламных компаний
|
||||
|
||||
# **Термины и определения**
|
||||
|
||||
«Целевой канал» — канал, в который мы приводим подписчиков. Им владеет пользователь (владелец проекта) и именно для него считаем подписки.
|
||||
|
||||
«Внешний канал» — сторонний канал, в котором покупаем размещение рекламы выбранного креатива. Пользователю он **не принадлежит**, бот туда **не добавляется**.
|
||||
|
||||
«Креатив» — сущность/шаблон текста сообщения, **привязанная к целевому каналу**.
|
||||
|
||||
«Закуп» — факт размещения креатива во **внешнем канале**. Для каждого закупа создаётся отдельная 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 в списках закупов, креативов и внешних каналов
|
||||
* Отображать столбчатую диаграмму с объемом закупок с группировкой по дате (день, неделя, месяц, квартал, год) и возможностью фильтрации по целевым каналам на отдельном экране “Аналитика” → “Затраты”
|
||||
Reference in New Issue
Block a user