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

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

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

JavaScript-обработчик

Как писать transform(input, context), проверять данные, вести логи и преобразовывать ответы внешних систем.

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

Код хранится отдельно от конфигурации автоматизации во вкладке Обработчик. В конфигурации достаточно включить JavaScript-преобразование:

transform:
  type: javascript
  timeout_seconds: 2

Обязательная функция

Скрипт должен объявлять обычную синхронную функцию transform:

function transform(input, context) {
  return input;
}
Аргумент Содержимое
input Данные, полученные из источника или источников и уже разобранные согласно response.format.
context Служебные сведения о запуске.

Возвращаемое значение становится результатом обработчика и передаётся в назначение. Возвращайте данные, которые можно представить в JSON: объект, массив, строку, число, логическое значение или null.

Обработчик выполняется синхронно. Не используйте async, Promise или ожидание внешних операций.

Что находится в input

Один источник

При конфигурации source + destination в input сразу находится ответ источника:

function transform(input, context) {
  return {
    employees: input.items,
    importedAt: context.started_at
  };
}

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

При использовании steps в input находится объект. Его ключи совпадают с id шагов-источников:

steps:
  - id: employees
    kind: source
    # ...
  - id: departments
    kind: source
    # ...
function transform(input, context) {
  return {
    employees: input.employees,
    departments: input.departments
  };
}

Подробнее о распределении результата между несколькими назначениями: Несколько источников и назначений.

context

Для обычного запуска доступны:

Поле Назначение
provider_id Идентификатор компании в Synchra24.
run_id Идентификатор запуска. Удобен для сопоставления с журналом запусков.
started_at Время запуска в формате ISO 8601.

При проверочном запуске вместо run_id передаётся test: true.

function transform(input, context) {
  console.info("Режим проверки:", context.test === true);
  return input;
}

Пример: переименование и фильтрация полей

function transform(input, context) {
  if (!Array.isArray(input.items)) {
    throw new Error("Источник не вернул массив items");
  }

  return input.items
    .filter(function (item) {
      return item.active === true;
    })
    .map(function (item) {
      return {
        externalId: String(item.id),
        fullName: [item.last_name, item.first_name, item.middle_name]
          .filter(Boolean)
          .join(" "),
        phone: item.phone || null,
        department: item.department_name || "Без отдела"
      };
    });
}

Пример: XML из 1С

XML преобразуется в JavaScript-объект до запуска функции. Одинаковый XML-элемент может стать объектом или массивом: это зависит от количества элементов в ответе. Удобно сразу привести значение к массиву.

function asArray(value) {
  if (value == null) return [];
  return Array.isArray(value) ? value : [value];
}

function transform(input, context) {
  var rows = asArray(input.CommercialInformation.Document);

  return rows.map(function (document) {
    return {
      number: String(document.Number || ""),
      date: document.Date,
      amount: Number(document.Amount || 0),
      currency: document.Currency || "RUB"
    };
  });
}

Особенности XML, атрибутов и кодировки Windows-1251 описаны в разделе Форматы данных.

Пример: числа из CSV

Значения CSV поступают как строки. Преобразуйте числа явно и учитывайте запятую как десятичный разделитель, если её использует источник.

function toNumber(value) {
  var normalized = String(value || "0")
    .replace(/\s/g, "")
    .replace(",", ".");
  var result = Number(normalized);
  return Number.isFinite(result) ? result : 0;
}

function transform(input, context) {
  return input.map(function (row) {
    return {
      employeeId: row.employee_id,
      workedHours: toNumber(row.worked_hours),
      amount: toNumber(row.amount)
    };
  });
}

Пример: разные данные для двух назначений

Обработчик может вернуть объект, а шаги-назначения — выбрать из него нужные части:

function transform(input, context) {
  var employees = input.employees || [];

  return {
    hrPayload: {
      employees: employees
    },
    analyticsPayload: {
      employeeCount: employees.length,
      generatedAt: context.started_at
    }
  };
}
- id: send_to_hr
  kind: destination
  input: ${transform.output.hrPayload}
  # ...

- id: send_to_analytics
  kind: destination
  input: ${transform.output.analyticsPayload}
  # ...

Логи обработчика

Во время проверочного запуска можно использовать четыре уровня:

function transform(input, context) {
  console.log("Получено записей:", Array.isArray(input) ? input.length : 1);
  console.info("Запуск:", context.started_at);
  console.warn("Пустые телефоны будут пропущены");

  if (!input) {
    console.error("Источник вернул пустой ответ");
    throw new Error("Нет данных для обработки");
  }

  return input;
}

Логи отображаются отдельным блоком в результате проверки. За один запуск сохраняется до 200 сообщений, каждое — до 4000 символов. Не выводите в лог токены, пароли, персональные данные и полные ответы внешних систем.

Ошибки и проверка входных данных

Останавливайте обработку с понятным сообщением, если данные не соответствуют ожидаемой структуре:

function transform(input, context) {
  if (!input || !Array.isArray(input.orders)) {
    throw new Error("Ожидался объект с массивом orders");
  }

  var invalid = input.orders.find(function (order) {
    return !order.id;
  });

  if (invalid) {
    throw new Error("У одной из записей отсутствует order.id");
  }

  return input.orders;
}

Такое сообщение будет видно в проверочном запуске и журнале запусков.

Ограничения среды

  • Размер скрипта — от 1 байта до 256 КБ.
  • Время выполнения — от 1 до 5 секунд, по умолчанию 2 секунды.
  • Доступа к сети и файловой системе из JavaScript нет.
  • Недоступны fetch, XMLHttpRequest, require, import, process и Deno.
  • Внешние запросы описываются в source, destination или steps, а не выполняются из обработчика.
  • Секретные переменные не передаются в JavaScript. Подставляйте их в URL и заголовки конфигурации.

Помощь AI-агента

В редакторе обработчика можно включить AI-агента и описать преобразование обычным текстом, например:

Из массива input.orders оставь только оплаченные заказы. Переименуй client_id в customerId, сумму преобразуй в число, а дату — в ISO 8601.

Агент предложит функцию и покажет изменения до вставки. Проверь названия полей, обработку пустых значений и результат через Проверочный запуск. Код попадает в редактор только после подтверждения. Функция доступна, если в лицензии компании включён AI-агент.

Рекомендации

  1. Делайте функцию небольшой и детерминированной: одинаковый вход должен давать одинаковый результат.
  2. Проверяйте обязательные поля до преобразования.
  3. Не меняйте исходный объект без необходимости — собирайте новый результат через map.
  4. Сначала проверяйте функцию на небольшом объёме данных.
  5. Логируйте количество и этап обработки, а не содержимое секретных или персональных полей.