enВойти в Senler

RefLink: пример плагина

RefLink — открытый полнофункциональный плагин реферальных кампаний для Senler. В одном репозитории находятся frontend, backend, общие контракты, миграции, пользовательская документация и файлы самостоятельного запуска.

Этот раздел объясняет приложение в том порядке, в котором проходит реальная работа: как открывается встроенная страница, как backend получает доступ к проекту, как AI вызывает действия через MCP и как выполняется шаг автоматизации. После этого можно переходить к конкретным папкам и файлам.

Как пользоваться примером

RefLink полезен, если новому плагину нужны несколько возможностей сразу:

  • встроенная страница внутри кабинета;
  • OAuth-доступ к API Senler от имени проекта;
  • собственный шаг автоматизации и форма его настройки;
  • действия backend, доступные AI через MCP;
  • webhook с проверкой подписи и защитой от повторной обработки;
  • общие типы между frontend и backend;
  • публичная документация на русском и английском языках.

Не копируйте приложение целиком. Сначала выберите нужный сценарий, затем возьмите соответствующий слой и адаптируйте права, данные и время жизни сессий под свой продукт.

RefLink не реализует конфигуратор инструмента агента. Для него используется тот же подход с Senler Bridge, но backend-операция размечается AgentToolConfigurator, а frontend обрабатывает запуск tool_configurator.

Технологии и их роль

ЧастьТехнологияДля чего используется
FrontendReact и Senler UIИнтерфейс встроенной страницы, форма настройки шага и взаимодействие с кабинетом через Senler Bridge.
BackendNestJSHTTP-контроллеры, проверка DTO, модули приложения, OAuth, сессии и обработчики webhook.
API-контрактOpenAPI и NestJS SwaggerОписание обычных endpoint и выбранных действий приложения для MCP.
API Senler@senlerio/apiТипизированные вызовы каналов, лидов, переменных, агентов, сегментов и автоматизаций.
ХранилищеPostgreSQL и TypeORMКампании, OAuth-подключения, обработанные события и техническое состояние выдачи награды.
Локальный запускDocker ComposeСовместный запуск frontend, backend и PostgreSQL с воспроизводимой конфигурацией.

Как проходит запрос

У RefLink есть три основных сценария. Они используют один backend, но разные способы входа и разные полномочия.

В каком порядке читать исходный код

ШагРаздел репозиторияЧто станет понятно
1README.mdНазначение приложения, режимы кампаний, запуск и публикация документации.
2docs/architecture.mdГде хранятся данные и почему реферальная статистика не дублируется в Postgres.
3docs/senler-app-setup.mdКакие URL, события, OAuth-права и поля результата указываются в настройках приложения.
4contracts/src/index.tsОбщие типы, режимы кампаний и результаты шага, которыми пользуются обе части приложения.
5frontend/srcПодключение Bridge, обмен кода на сессию и переключение между основной страницей и конфигуратором.
6backend/src/core/sessionПроверка одноразовых кодов, project-scoped сессии и защита endpoint.
7backend/src/resources/oauthOAuth callback, хранение подключения и обновление токенов.
8backend/src/integrations/senlerИзолированный адаптер для вызовов API Senler.
9backend/src/resources/campaignsCRUD кампаний, статистика, создание автоматизации и OpenAPI-действия.
10backend/src/resources/referralsПодписи webhook, дедупликация, атрибуция и выдача наград.
11docs/public и assets/catalogКак хранить пользовательскую документацию и материалы карточки приложения рядом с кодом.
12docker-compose.ymlКак связаны frontend, backend, база данных, health-check и переменные окружения.

Ключевые архитектурные решения

Проект определяется доверенным контекстом

project_id из query-параметра, тела запроса или аргументов AI нельзя считать доказательством доступа. RefLink определяет проект только после проверки launch_code, сессии приложения, management token, OAuth subject или подписи webhook. Затем сервисы получают уже подтверждённый ID через @EmbeddedProject().

Это решение предотвращает ситуацию, когда пользователь или AI подставляет ID другого проекта в обычный параметр.

Авторизация разделена по назначению

ЗначениеКто выдаётДля чего оно нужно
launch_codeSenlerОдноразово подтвердить запуск страницы или management session и передать подписанный контекст проекта.
session_tokenBackend RefLinkРазрешить открытому frontend обращаться к backend RefLink в рамках одного проекта.
management_tokenBackend RefLinkРазрешить Senler вызвать конкретное действие приложения через MCP.
OAuth access/refresh tokenSenler OAuthРазрешить backend RefLink обращаться к API Senler с подтверждёнными пользователем правами проекта.

Ни один из этих токенов не следует использовать вместо другого. Секреты OAuth хранятся в зашифрованном виде через SecretVaultService, а новая пара access/refresh сохраняется вместе под блокировкой подключения в OAuthConnectionService.

SDK отделён от предметной логики

Контроллеры и сервисы кампаний не формируют HTTP-запросы к Senler напрямую. Все такие вызовы собраны в SenlerApiClient, который использует официальный SDK.

Так проще обновлять SDK, тестировать ответы и временно изолировать операции, которых ещё нет в опубликованной версии клиента.

Источник данных выбирается заранее

В PostgreSQL RefLink хранит настройки кампаний, OAuth-подключения и техническое состояние. Реферальные связи и счётчики остаются в переменных лидов Senler. Приложение не поддерживает вторую копию той же статистики и не синхронизирует два источника истины.

Это не универсальная схема данных, но универсальный принцип: до разработки нужно определить владельца каждого вида данных и хранить локально только то, что действительно принадлежит приложению.

Что переиспользовать в новом приложении

  1. Создайте отдельные пакеты или каталоги для общих контрактов, frontend, backend и интеграционного адаптера.
  2. Реализуйте проверку launch_code и project-scoped сессию до разработки бизнес-форм.
  3. Добавьте OAuth только с необходимыми правами, храните токены зашифрованными и сохраняйте новую пару после refresh атомарно.
  4. Подключите Senler UI и Senler Bridge, затем явно обработайте каждый нужный context.launch.type.
  5. Оставьте бизнес-endpoint обычными контроллерами с DTO, а выбранные операции опубликуйте через AppAction, AgentToolConfigurator или AutomationStepConfigurator.
  6. Проверьте полученный OpenAPI командой senler-app validate-openapi до добавления URL в настройки приложения.
  7. Для webhook сначала реализуйте проверку подписи, event ID, идемпотентность и восстановление зависшей обработки, затем добавляйте предметный сценарий.
  8. Храните пользовательскую документацию и материалы каталога рядом с исходным кодом и проверяйте русскую и английскую версии в CI.

Что не копировать без проверки

  • OAuth-права RefLink: новому приложению может требоваться меньше или больше разрешений.
  • Срок жизни сессии: его выбирают по риску, способу повторного запуска и требованиям продукта.
  • Имена переменных лидов, webhook-события, поля результата и правила награды: это предметная модель реферального приложения.
  • URL endpoint и имена переменных окружения: они должны принадлежать вашему домену и инфраструктуре.
  • Все MCP-действия сразу: публикуйте только операции, которые AI действительно должен вызывать, и точно отмечайте read_only, destructive и idempotent.

Ссылки