232 lines
18 KiB
Markdown
232 lines
18 KiB
Markdown
# **Общее описание системы**
|
||
|
||
Система для владельцев каналов позволяющая удобно систематизировать информацию о закупках рекламы и предоставляющая удобный интерфейс для анализа проведенных рекламных компаний
|
||
|
||
# **Термины и определения**
|
||
|
||
«Целевой канал» — канал, в который мы приводим подписчиков. Им владеет пользователь (владелец проекта) и именно для него считаем подписки.
|
||
|
||
«Внешний канал» — сторонний канал, в котором покупаем размещение рекламы выбранного креатива. Пользователю он **не принадлежит**, бот туда **не добавляется**.
|
||
|
||
«Креатив» — сущность/шаблон текста сообщения, **привязанная к целевому каналу**.
|
||
|
||
«Закуп» — факт размещения креатива во **внешнем канале**. Для каждого закупа создаётся отдельная 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 в списках закупов, креативов и внешних каналов
|
||
* Отображать столбчатую диаграмму с объемом закупок с группировкой по дате (день, неделя, месяц, квартал, год) и возможностью фильтрации по целевым каналам на отдельном экране “Аналитика” → “Затраты”
|