# **Общее описание системы** Система для владельцев каналов позволяющая удобно систематизировать информацию о закупках рекламы и предоставляющая удобный интерфейс для анализа проведенных рекламных компаний # **Термины и определения** «Целевой канал» — канал, в который мы приводим подписчиков. Им владеет пользователь (владелец проекта) и именно для него считаем подписки. «Внешний канал» — сторонний канал, в котором покупаем размещение рекламы выбранного креатива. Пользователю он **не принадлежит**, бот туда **не добавляется**. «Креатив» — сущность/шаблон текста сообщения, **привязанная к целевому каналу**. «Закуп» — факт размещения креатива во **внешнем канале**. Для каждого закупа создаётся отдельная 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=`. Сайт обменивает токен на сессию. Если пользователя не существовало — создаётся новый профиль; если существовал — выполняется вход. ### **Сценарии использования** **Новый пользователь** 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/\/\ * https://t.me/c/\/\ (для приватных каналов с доступом — см. ограничения ниже) Метрика хранится как снимки (time series) с периодическим опросом (раз в час), чтобы видеть динамику добора просмотров. 💡Тут надо подумать, как частно нужно получать эти данные и как их надо агрегировать, так как у телеграмма как-то заковыристо считается и показывается кол-во просмотров ### **Сценарии использования** **Успешное получение просмотров (публичный канал)** 1. В карточке закупа пользователь добавляет ссылку на пост (t.me/\/\). 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 в списках закупов, креативов и внешних каналов * Отображать столбчатую диаграмму с объемом закупов с группировкой по дате (день, неделя, месяц, квартал, год) и возможностью фильтрации по целевым каналам на отдельном экране “Аналитика” → “Затраты”