Synchra.24
menu_bookДокументация
Практические материалы по запуску и развитию

Здесь собраны инструкции по запуску, разработке внутренних сценариев и встраиванию собственных инструментов в рабочий контур компании.

folderАвтоматизации

Несколько источников и назначений

Как использовать steps, собирать данные из нескольких систем и отправлять разные части результата в несколько назначений.

Режим steps нужен, когда одной пары source и destination недостаточно. Он позволяет получить данные из нескольких систем, передать их одному JavaScript-обработчику и затем отправить результат в несколько назначений.

Как выполняются steps

Автоматизация разделяет шаги по полю kind:

  • все шаги source выполняются параллельно;
  • результаты источников собираются в объект по их id;
  • обработчик вызывается один раз для собранного объекта;
  • все шаги destination выполняются параллельно;
  • каждому назначению можно передать весь результат или выбранное поле.

Автоматизация должна содержать хотя бы один источник и одно назначение. Максимальное количество шагов — 50.

Структура шага

Поле Обязательно Назначение
id да Уникальное имя шага. Начинается с буквы, содержит буквы, цифры, _ или -, не длиннее 64 символов.
kind да source или destination.
type да Сейчас поддерживается только http.
method нет HTTP-метод. По умолчанию GET для источника и POST для назначения.
url да Абсолютный HTTP- или HTTPS-адрес.
headers нет Заголовки запроса. Поддерживают ${secrets.NAME}.
body нет Тело запроса источника.
response для источника Формат и кодировка ответа.
request для назначения Формат и кодировка отправляемых данных.
input только для назначения Какая часть результата обработчика отправляется в этот шаг.

Пример с двумя источниками

version: 1

trigger:
  type: schedule
  cron: "0 4 * * *"
  timezone: Europe/Moscow

steps:
  - id: orders
    kind: source
    type: http
    method: GET
    url: https://sales.example.com/api/orders
    headers:
      Authorization: "Bearer ${secrets.SALES_TOKEN}"
    response:
      format: json

  - id: employees
    kind: source
    type: http
    method: GET
    url: https://accounting.example.com/export/employees.xml
    headers:
      X-API-Key: "${secrets.ACCOUNTING_KEY}"
    response:
      format: xml
      encoding: windows-1251

  - id: analytics
    kind: destination
    type: http
    method: POST
    url: https://analytics.example.com/import
    headers:
      Authorization: "Bearer ${secrets.ANALYTICS_TOKEN}"
    input: ${transform.output.analytics}
    request:
      format: json

  - id: archive
    kind: destination
    type: http
    method: POST
    url: https://archive.example.com/daily.csv
    headers:
      X-API-Key: "${secrets.ARCHIVE_KEY}"
    input: ${transform.output.archive}
    request:
      format: csv
      encoding: utf-8
      options:
        delimiter: ";"

transform:
  type: javascript
  timeout_seconds: 3

retry:
  attempts: 3
  delay_seconds: 10

Что получает обработчик

Для приведённой конфигурации input имеет следующую форму:

{
  orders: /* декодированный ответ шага orders */,
  employees: /* декодированный ответ шага employees */
}

Ключи объекта совпадают с id источников. Поэтому идентификаторы лучше делать короткими и понятными.

Пример обработчика:

function transform(input, context) {
  const orders = Array.isArray(input.orders?.items)
    ? input.orders.items
    : [];

  const employeeList = input.employees?.Employees?.Employee;
  const employees = Array.isArray(employeeList)
    ? employeeList
    : employeeList
      ? [employeeList]
      : [];

  const employeeById = {};
  for (const employee of employees) {
    employeeById[String(employee.Id)] = employee;
  }

  const rows = orders.map((order) => ({
    orderNumber: String(order.id),
    employeeName: employeeById[String(order.employee_id)]?.Name || "Не найден",
    amount: Number(order.amount || 0),
  }));

  return {
    analytics: {
      generatedAt: context.started_at,
      rows,
    },
    archive: rows,
  };
}

Выбор данных для назначения

Поле input поддерживает два варианта.

Передать весь результат:

input: ${transform.output}

Передать поле объекта:

input: ${transform.output.analytics}

Поддерживаются вложенные поля:

input: ${transform.output.exports.accounting}

Если input не указан, назначение получает весь результат обработчика.

Селектор работает только с полями объектов. Он не поддерживает индексы массивов и произвольные JavaScript-выражения.

Что произойдёт при ошибке

  • Если любой источник завершится ошибкой, обработчик и назначения не запускаются.
  • Если обработчик завершится ошибкой, назначения не запускаются.
  • Если одно или несколько назначений завершатся ошибкой, запуск получает статус Ошибка с перечислением проблемных шагов.
  • Для каждого назначения применяется общая настройка retry.

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

Когда steps не нужны

Не используйте steps только ради будущего расширения. Для простой передачи из одной системы в другую конфигурация с source и destination короче, понятнее и легче поддерживается.

Перейти к справочнику всех полей: Конфигурация автоматизации.