AACsearch
Коннекторы и виджет

Пользовательский коннектор — руководство разработчика

Сборка CMS-коннектора поверх Connector API AACsearch. Использование токенов, full/delta/delete-синхронизация, формат документа, правила маппинга и обязательная обработка ошибок.

Если вашей CMS или каталога товаров нет в списке поддерживаемых платформ, вы можете написать свой коннектор поверх публичного Connector API. На этой странице — минимальный набор требований, при котором коннектор считается production-ready.

Сам API подробно описан в Жизненный цикл Connector API. Здесь — обязанности разработчика, которые живут на стороне CMS.

Что значит «production-ready»

Коннектор считается production-ready, когда он:

  1. Авторизует каждый запрос Bearer-токеном ss_connector_*.
  2. Запускает handshake при установке и при сохранении настроек, сохраняет полученные projectId и indexSlug.
  3. Выполняет первичную полную синхронизацию батчами ≤1000 документов на запрос.
  4. Выполняет дельта-синхронизацию на каждое создание / изменение / изменение цены или склада, батчами ≤100 документов.
  5. Удаляет документ при удалении товара.
  6. Шлёт heartbeat не реже раза в 5 минут из фоновой задачи.
  7. Шлёт diagnostics после каждой полной синхронизации, после ошибок синхронизации и раз в сутки.
  8. Маппит сущности CMS в общий формат документа (ниже), используя все доступные поля.
  9. Реализует стратегию повторов.
  10. Показывает в админке кнопку Test connection.

Если коннектор реализует только пункты 1–6 — это уровень Early preview. Пункты 7–10 нужны для Beta, а наблюдаемая надёжность через ≥3 релизных цикла нужна для Supported.

Структура проекта

Коннектор можно хостить где угодно — лишь бы он мог вызывать HTTP API. Эталонные реализации в монорепозитории следуют одному из трёх шаблонов из wiki/tasks/cms-platform-expansion.md:

  • Шаблон A — PHP CMS-модуль (PrestaShop, Bitrix, WordPress, OpenCart, Magento, Drupal, Joomla)
  • Шаблон B — TypeScript серверный коннектор (Shopify, InSales)
  • Шаблон C — npm-плагин headless CMS (Strapi, Sanity, Contentful, Directus, Payload)

Минимальный набор файлов для любого шаблона:

your-connector/
├── client.{ts,php}           ← HTTP-клиент Connector API
├── product-mapper.{ts,php}   ← Сущность платформы → SyncProductInput
├── full-sync.{ts,php}        ← Постраничный экспорт каталога
├── delta-sync.{ts,php}       ← Обработчик create/update/delete-событий
├── diagnostics.{ts,php}      ← Heartbeat + отчёт об ошибках
└── admin/
    ├── settings.{tsx,php}    ← Форма токена и project ID
    └── test-connection.{tsx,php}

Используйте существующие модули как референс:

  • packages/strapi-plugin/src/server/services/aacsearch.ts — TypeScript-сервис с full и delta sync
  • modules/bitrix/aac.search/lib/aacsearch/ConnectorClient.php — PHP-клиент API
  • modules/prestashop/aacsearch/ — структура PrestaShop-модуля
  • packages/shopify-connector/src/ — OAuth-коннектор с вебхуками

Формат документа

Каждый товар, отправленный в AACsearch, ложится на SyncProductInput. Обязательные поля — external_id и title; остальные опциональны, но крайне рекомендованы.

type SyncProductInput = {
  external_id: string;            // стабильный ID на стороне платформы
  title: string;
  description?: string;
  sku?: string;
  brand?: string;
  categories?: string[];          // путь категорий в человекочитаемом виде
  category_ids?: string[];        // ID категорий для фильтров
  tags?: string[];
  price?: number;                 // основные единицы (например 99.99 USD)
  sale_price?: number;
  currency?: string;              // ISO 4217, 3 буквы
  image_url?: string;
  product_url?: string;
  availability?: "in_stock" | "out_of_stock" | "preorder";
  stock_quantity?: number;
  attributes?: Record<string, unknown>;
  locale?: "en" | "de" | "es" | "fr" | "ru";
  created_at?: string;            // ISO 8601
  updated_at?: string;            // ISO 8601
};

Правила маппинга

  • external_id — должен быть стабильным на всё время жизни товара. Берите первичный ключ CMS, а не slug или SKU.
  • title — локализованное название для настроенного locale. Убирайте HTML, нормализуйте пробелы.
  • description — то же правило. HTML-стрипнуть, оставить чистый текст. Токенизация — на стороне AACsearch.
  • categories — полный путь крошек, корень → лист. ["Обувь", "Беговая", "Трейл"] лучше, чем ["Трейл"].
  • price / sale_price — в основных единицах в формате передачи. Конвертацию в минорные единицы (kopecks-style BigInt) делает ингест-пайплайн AACsearch. Не умножайте на 100 на стороне модуля.
  • attributes — всё, что фильтруется или фасетируется, но не имеет выделенной колонки. Ключи произвольные. Числовые атрибуты (размер, длина, объём) шлите как числа, а не как строки — AACsearch выводит тип индекса из первого батча.
  • locale — если CMS поддерживает локализованные каталоги, шлите один документ на каждую локаль товара, с разными суффиксами в external_id (например, prod-123:en, prod-123:de). Не схлопывайте локали в один документ.

Мультивалютные каталоги

Если ваша CMS поддерживает несколько валют, основную пользовательскую валюту передавайте в currency, а остальные — в объекте attributes.price_by_currency:

{
  "currency": "USD",
  "price": 99.99,
  "attributes": {
    "price_by_currency": { "EUR": 92.5, "GBP": 79.99 }
  }
}

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

Обязательные эндпоинты

Минимально жизнеспособный коннектор вызывает эти эндпоинты в таком порядке:

  1. POST /api/connectors/handshake — при установке и каждом сохранении настроек.
  2. POST /api/projects/:projectId/sync/full — первичный экспорт каталога и ручное «Пересинхронизировать всё».
  3. POST /api/projects/:projectId/sync/delta — на каждое событие товара в CMS.
  4. DELETE /api/projects/:projectId/products/:externalId — при удалении товара.
  5. POST /api/connectors/:connectorId/heartbeat — каждые 5 минут.
  6. POST /api/projects/:projectId/diagnostics — после каждой полной синхронизации и раз в сутки.

Формат payload, коды ошибок и порядок вызовов — в Жизненный цикл Connector API.

Аутентификация, scope и изоляция арендатора

Connector API сам обеспечивает три инварианта — переписывать их не нужно, но обходить нельзя:

  • Каждый вызов привязан к организации, владеющей токеном. :projectId в URL должен совпадать с организацией токена. 404 значит «мерчант вставил не тот токен», а не «AACsearch потерял данные».
  • Проверяется только область connector_write токена. Токены коннектора не могут читать результаты поиска, управлять индексами или читать аналитику. Для поисковых запросов из магазина используется токен ss_search_*.
  • Документы сначала пишутся в SearchIngestBuffer, потом в Typesense фоновым воркером. Ответ 200 означает «буферизовано» — документ может стать доступен для запросов через сотни миллисекунд.

Никогда не обращайтесь к Typesense, административному поисковому ключу AACsearch или внутренним хранилищам напрямую. Connector API — единственный поддерживаемый путь записи. Прямые записи обходят изоляцию арендатора, контроль квот и буфер для повторов — это сломает систему незаметным способом под нагрузкой.

Receiver webhook'ов

Коннекторы, работающие на сервере CMS, могут выбирать между двумя моделями:

  • Outbound push — модуль реагирует на события CMS и зовёт sync-эндпоинты AACsearch. Просто, используется во всех существующих PHP-модулях.
  • Webhook receiver — AACsearch шлёт вебхуки платформе при переиндексации документов; полезно для инвалидации кэшей или аналитики. Эндпоинт: POST /api/webhooks/sync/:indexSlug, подпись HMAC по секрету коннектора.

Большинству CMS-коннекторов receiver не нужен. Используйте его, если хотите, чтобы кэш или CDN платформы узнавал об изменении индекса.

Локальная разработка

Для быстрой итерации:

  1. Запустите AACsearch командой bun run dev — API поднимется на http://localhost:3000/api.
  2. Создайте токен коннектора в панели и скопируйте его.
  3. Настройте свой CMS-модуль на http://localhost:3000/api.
  4. Эндпоинт /api/projects/:projectId/sync/jobs/:jobId или Панель → Connectors → Sync history покажут, как документы попадают в индекс.
  5. Search → Test Search в панели подтвердит, что документы проиндексированы в правильном арендаторе.

В продакшене предпочитайте https://api.aacsearch.com/api и принимайте токен коннектора как есть.

Как сдать свой коннектор

Если вы хотите, чтобы ваш коннектор попал в матрицу поддержки:

  1. Откройте issue с описанием платформы и целевого шаблона (A, B или C).
  2. Пришлите PR, добавляющий коннектор в modules/<platform>/ или packages/<platform>-connector/, и отдельную страницу документации в apps/docs/content/docs/{en,de,es,fr,ru}/connectors/<platform>.mdx.
  3. Установите статус «Early preview» на старте. Перевод в Beta и Supported — по факту наблюдаемой надёжности через несколько релизных циклов.

Связанные страницы

On this page