# Интеграции — Администрирование

Документ описывает администрирование интеграций 1Формы: где хранится конфигурация, какие формы и API используются, ключевые настройки 1С и внешних сервисов, типовые ошибки и подробные параметры каждого сервиса. Администрирование сосредоточено в разделе `system → подключения`, в контуре `sync1c` и в единой форме AdminSPA «Сервисы» (v2.268+). Материал предназначен для администраторов и инженеров поддержки, настраивающих и диагностирующих интеграции.

## Обзор

Для `integrations` администрирование в основном сосредоточено в разделе `system → подключения` и в отдельном контуре `sync1c`.

Ключевой принцип домена: конфигурация хранится в таблицах сервисов/интеграций, а эксплуатационное управление выполняется через Admin API (очереди, тесты соединения, повторная обработка).

Начиная с версии 2.268 в AdminSPA для управления сервисами доступна единая отдельная форма «Сервисы» (alias `system-services`): универсальный интерфейс с адаптивным набором полей под выбранный тип сервиса.

## Механизмы администрирования

### Автоадминка — сервисы подключений

Формы автоадминки для настройки сервисов подключений:

| Alias формы | Название | Таблица БД | Что настраивается |
|-------------|----------|------------|-------------------|
| `sync-1c` | Синхронизация с 1С | `dbo.SyncSettings1C` | Профили обмена 1С |
| `ews-service-settings` | Сервис ExchangeWebService | `dbo.EwsServiceSettings` | Подключение к Exchange |
| `diadoc-service-settings` | Сервис Diadoc | `dbo.DiadocServiceCredentials` | ЭДО Диадок |
| `sbis-service-settings` | Сервис Sbis | `dbo.SbisCredentials` | ЭДО СБИС |
| `dadata-service-settings` | Сервис Dadata | `dbo.DadataServiceCredentials` | Подсказки/обогащение данных |
| `paycontrol-service-settings` | Сервис PayControl | `dbo.PayControlServiceCredentials` | Мобильная подпись/СКЗИ |
| `tika-service-settings` | Сервис Tika | `dbo.TikaServiceSettings` | Извлечение текста из файлов |
| `azure-service-settings` | Сервис TranslateService | `dbo.AzureCognitiveServiceCredentials` | AI-перевод |
| `universalapi-service-settings` | Сервис UniversalApi | `dbo.UniversalApiServiceSettings` | Универсальные внешние вызовы |
| `vector-search-service-settings` | Сервис VectorSearch | `dbo.VectorSearchServiceSettings` | Поиск/индексация |
| `pt-sandbox-service-settings` | Сервис PT Sandbox | `dbo.PTSandboxServiceSettings` | Антивирусная проверка файлов (PT Sandbox) |
| `pt-sandbox-domain-settings` | Привязка доменов к сервису PT Sandbox | `dbo.PTSandboxDomainSettings` | Фильтрация доменов для проверки файлов |
| `python-executor-service-settings` | Сервис Python Executor | `dbo.PythonExecutorServiceSettings` | Исполнение Python-смарт-скриптов (внешний сервис) |
| `system-services` | Сервисы | `dbo.ServicesSettings` | Глобальная карта сервисов |
| `file-providers` | Провайдеры файлов | `dbo.FileProviders` | Хранилища файлов (MSSQL/S3 и др.) |

### AdminSPA — единая форма «Сервисы» (v2.268+)

Маршрут: `/administration/services` (права администратора). SPA-форма для таблицы `dbo.ServicesSettings` — глобальная конфигурация всех интеграций (URL, порты, флаги, таймауты, сопоставление пользователей). Заменяет устаревшие формы автоадминки `*-service-settings`; серверная часть (таблицы `*Credentials`/`*Settings`) остаётся прежней.

**Принципы:**

- Тип сервиса (`ServiceType`) выбирается в выпадающем списке. Для каждого типа зарегистрирован свой набор полей — после выбора типа форма перестраивается под нужный набор контролов.
- Доступные типы контролов: `text`, `password`, `number`, `checkbox`, `dropdown` (с источником `optionsKey` — например, `user-mapper-types`, `queues`, `queue-flows`, перечислимые типы), `textarea`, `users` (с выбором групп), `smart-filter`, `datetime` (используется для readonly-полей сроков действия токенов — например в форме Passwork).
- Поддерживаемые ServiceType (по состоянию на v2.268): `PTSandbox`, `PythonExecutor`, `KonturCloud`, `KonturKEDO`, `Passwork` и другие — точный список и набор полей по типу зависят от версии.

**API:**

| Метод | Маршрут | Назначение |
|---|---|---|
| `GET` | `/api/admin/services` | Список сервисов (DataSourceGrid) |
| `POST` | `/api/services` | Создание сервиса |
| `DELETE` | `/api/services?settingsId={id}` | Удаление |
| `GET` | `/api/services/settings/{id}` | Чтение настроек |
| `POST` | `/api/services/settings` | Обновление настроек |
| `GET` | `/api/services/settings/user-mapper-types` | Справочник типов сопоставления пользователей |
| `GET` | `/api/admin/queues` | Очереди (для dropdown в формах) |
| `GET` | `/api/admin/queues/flows` | Потоки очередей |

Подписи этой формы, как и настроек синхронизации с 1С и почтовых ящиков, берутся из ресурсных файлов SPA и показываются на языке администратора; значения выпадающих списков — типы сервисов, очереди и потоки — приходят с сервера и на английском языке могут оставаться русскими. Подробнее — [Локализация — Администрирование](https://help.1forma.ru/domains/localization/admin.md).

**Не то же самое, что интерфейс секретов** — `/administration/services` управляет конфигурацией сервиса (URL, порты, таймауты), `/administration/secrets` управляет учётными данными (логины, пароли, токены) (см. [Интеграции — секреты](https://help.1forma.ru/domains/integrations/secrets.md)). Связь между формами по типу: `ServiceType` в Сервисах соответствует префиксу `serviceKey` в Секретах (`PTSandbox` ↔ `pt-sandbox-{id}` и т.д.).

### Сервис Python Executor

**Python Executor** — внешний сервис (HTTP, разворачивается как Docker-контейнер), исполняющий Python-смарт-скрипты (движок Python в смарт-действиях — см. [smart-actions/admin.md](https://help.1forma.ru/domains/smart-actions/admin.md)). Настройки задаются в форме «Сервис Python Executor» (`python-executor-service-settings`) либо в единой форме «Сервисы» (тип `PythonExecutor`) и хранятся в таблице `dbo.PythonExecutorServiceSettings`.

| Поле | Описание |
|------|----------|
| Сервис | Выбор записи сервиса из общей карты сервисов (`ServicesSettings`), к которой привязываются настройки. |
| API Url | Адрес развёрнутого сервиса Python Executor, куда «Первая Форма» отправляет код на исполнение. Сервис внешний (Docker-контейнер), разворачивается при внедрении — адрес его API узнайте у команды внедрения или администратора контура. Обязательное поле. |
| API Key | Ключ доступа к сервису Python Executor, если тот требует авторизации. Необязательное поле. |

### API администрирования и Редактор сущностей

Административные операции выполняются через маршруты API администрирования и схемы Редактора сущностей.

**Редактор сущностей**

| Схема JSON | Таблица | Назначение |
|-----------|---------|------------|
| `fileProviderDefault` | (виртуальная) | Провайдер файлов по умолчанию |
| `authenticationProviders` | `dbo.AuthenticationProviders` | Смежная интеграция авторизации в едином разделе подключений |

**API администрирования**

| Маршрут | Методы | Назначение |
|---------|--------|------------|
| `/api/admin/sync1c/config*` | GET, POST, DELETE | CRUD конфигов 1С, тест соединения, отправка настроек |
| `/api/admin/sync1c/builder/*` | GET, POST | Конвейер-конструктор подготовки конфигурации |
| `/api/admin/sync1c/queue/*` | POST | Обработка/очистка очередей Sync1C |
| `/api/admin/sync1c/usermapping` | GET, POST, DELETE | Сопоставление пользователей 1С и 1Ф |
| `/api/admin/exchange/subscriptions` | GET | Активные подписки Exchange |
| `/api/admin/rebus/unsubscribe` | POST | Отписка от очередей шины сообщений |
| `/api/admin/fileproviders` | GET, POST, DELETE | Управление файловыми провайдерами |
| `/api/admin/services` | GET | Обзор зарегистрированных сервисов |

## Ключевые настройки

### 1. Профили интеграции 1С

**Где настраивается:** `sync-1c`, `/api/admin/sync1c/*`, страницы `1c_sync`/`1c_profile`/`1c_queue`.

**Таблицы БД:**

- `dbo.SyncSettings1C`
- `dbo.Sync1CEventQueues`
- `dbo.Sync1CLog`

**Что контролируется:** адрес обмена, формат и карта синхронизации, очередь событий, лимиты повторов.

⚠️ **Не входит в сертифицируемую сборку (`UniForm.Barebone`).** В такой сборке обмен с 1С не компилируется: входящих точек и административных маршрутов `api/admin/sync1c/*` нет, ядро снято с компиляции, обработчика типа «обмен с 1С» в очереди тоже нет. Реестр административных форм и фронт по профилю сборки не собираются, поэтому форма обмена и клиентский раздел администрирования в такой сборке остаются, но за ними нет ни обработчиков, ни данных обмена, а обращение по маршруту отвечает `404`. Таблицы `SyncSettings1C`, `Sync1CEventQueues` и `Sync1CLog` вместе с записями, которые пришли с дампом базы, тоже остаются в схеме — снят обмен, а не модель данных. Настраивать обмен на такой площадке бессмысленно; сопутствующий эффект — дополнительные параметры с ключами синхронизации перестают исключаться при копировании из родительской задачи, потому что набор исключений в профиле всегда пуст. Подробно об обмене в двух сборках — Интеграция с 1С.

**Конвейер-конструктор:** 4-шаговый мастер для автоматического создания категорий и ДП на основе метаданных 1С. Архитектура сопоставления, типы, виртуальные реквизиты/документы — в [Сопоставление сущностей 1С](https://help.1forma.ru/domains/integrations/1c-entity-mapping.md).

**Привилегированный режим (со стороны 1С).** По умолчанию **включён**: операции с данными выполняются от лица пользователей-1С без проверки прав, что ускоряет обмен и обходит ограничения прав (RLS). Отключается флагом «Отключить привилегированный режим» в общих настройках обмена (раздел `Sync1C` → профиль). Отключать имеет смысл только если обмен явно должен соблюдать пользовательские ограничения 1С (редкий кейс — например, при выгрузке от имени конкретного оператора с ограниченным доступом).

### 2. Учётные данные внешних сервисов

**Где настраивается:** формы `*-service-settings` в `system → подключения`.

**Таблицы БД:**

- `dbo.EwsServiceSettings`
- `dbo.DiadocServiceCredentials`
- `dbo.SbisCredentials`
- `dbo.DadataServiceCredentials`
- `dbo.PayControlServiceCredentials`
- `dbo.TikaServiceSettings`
- `dbo.AzureCognitiveServiceCredentials`
- `dbo.UniversalApiServiceSettings`
- `dbo.VectorSearchServiceSettings`
- `dbo.PTSandboxServiceSettings`
- `dbo.PTSandboxDomainSettings`

**Что контролируется:** URL, ключи, секреты, API-параметры и доступность интеграционного канала.

### 3–4. Файловые провайдеры, эксплуатация очередей и подписок

Файловые провайдеры и эксплуатация очередей настраиваются в разделе подключений и через Admin API.

**Файловые провайдеры как инфраструктурная интеграция**

**Где настраивается:** `file-providers`, `/api/admin/fileproviders`.

**Таблицы БД:**

- `dbo.FileProviders`
- таблицы настроек конкретного провайдера

**Что контролируется:** место физического хранения файлов, сжатие, тест подключения, переключение провайдера записи.

Полная инструкция по подключению — типы провайдеров, требования к таблице MS SQL, параметры S3-хранилища, порядок подключения и режим сжатия — в [files/admin.md](https://help.1forma.ru/domains/files/admin.md), раздел «Провайдеры хранения файлов».

**Эксплуатация очередей и подписок**

**Где настраивается:** `/api/admin/sync1c/queue/*`, `/api/admin/rebus/unsubscribe`, `/api/admin/exchange/subscriptions`.

**Таблицы БД:**

- `dbo.MessageQueue`
- `dbo.MessageQueueLog`
- `dbo.MessageFlows`

**Что контролируется:** повторные попытки, "зависшие" события, остановка/разблокировка потоков.

**Административные формы очередей:**

| Форма | Alias | Таблица | Назначение |
|-------|-------|---------|------------|
| Журнал очередей | `message-queue-log` | `dbo.MessageQueueLog` | История обработанных событий. Колонки: дата, тип потока, событие, статус, **исходный ключ очереди** (`OriginalMessageId` — `ParentMessageId` из `MessageQueue`), параметры, текст ошибки. |
| Содержимое очереди | `queue-log` | `dbo.MessageQueue` | Активные записи в обработке: дата создания/обработки, тип потока, событие, статус, внутренний ID (`ContextId`), внешний ID (`ContextExternalId`), параметры (`Data`), текст ошибки, тип ошибки. Доступны массовые действия «Удалить события с ошибками» и «Обработать события с ошибками». Для каждой строки доступна кнопка **«Выполнить повторно»** — принудительно запускает обработку одного сообщения (v2.268+). |
| Очередь событий Sync1C | `1c_queue` | `dbo.Sync1CEventQueues` | Просмотр очереди событий синхронизации с 1С. Поддерживает мультивыбор строк и массовое удаление кнопкой «Удалить выбранные» в панели инструментов (доступна при праве `AllowDeleteF` конфига формы; на бэкенде требуется привилегированный доступ). При частичном успехе таблица обновляется и выводится сообщение о неудалённых событиях. Удаление пачкой выполняется через `POST /api/admin/sync1c/queue/delete-events`. В сертифицируемой сборке форма остаётся, но записи в ней не обрабатываются: обработчик типа обмена снят с компиляции, а маршрут `api/admin/sync1c/queue/delete-events` отсутствует. |

**API повторного выполнения:** `POST /api/admin/queues/messages/{id}/execute` — повторный запуск конкретного сообщения из очереди. Вызывается кнопкой «Выполнить повторно» в колонке формы `queue-log` (v2.268+). Ответ — `204` при успехе, `404`, если записи нет.

В сертифицируемой сборке (`UniForm.Barebone`) для записи типа «обмен с 1С» обращение отвечает `204`, состояние записи **не меняется** и никакого действия не выполняется: обработчик этого типа снят с компиляции, а маршрут остаётся в обеих сборках. Это ожидаемое поведение, а не сбой.

**Отправка в шину идёт отдельным подключением.** Команды в шину отправляет односторонний клиент: своей очереди он не создаёт и сообщений не принимает, подключение открывается асинхронно и без транзакции. Поэтому публикация не занимает поток сервера приложений на ожидании сети: при запоздавшем или недоступном сервере базы шины приложение продолжает обслуживать пользователей. Приём команд не изменился — сообщение удаляется из очереди и обрабатывается в одной транзакции, при ошибке обработчика возвращается в очередь. Порядок и гарантии доставки прежние: команды доставляются без гарантий, а при публикации из нескольких нод часть нод может получить команду, часть — нет.

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

### 5. Сертификаты внешних сервисов при исходящих подключениях

Платформа проверяет TLS-сертификаты при исходящих защищённых (HTTPS) подключениях к внешним сервисам: SMS-шлюзам, Multifactor, платёжным сервисам (PayControl), Контуру, Exchange (EWS), Р7-Офису и OnlyOffice. Сервер 1Формы должен доверять цепочке сертификата каждого такого адреса.

Для публичных сервисов с действующим сертификатом от общедоверенного удостоверяющего центра дополнительная настройка обычно не требуется. Для сервисов во внутренней сети (локальные SMS-шлюзы, корпоративный Exchange, внутренние Р7-Офис/OnlyOffice и т.п.) с самоподписанным сертификатом или сертификатом внутреннего удостоверяющего центра сертификат этого центра должен быть добавлен в доверенные на сервере 1Формы — иначе подключение завершится ошибкой защищённого соединения.

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

### Импорт данных: псевдоним конечной точки

У поля «Алиас» в форме настройки импорта данных выводится подсказка о допустимом формате: только латинские буквы `a-z`, без пробелов. Подсказка видна у поля сразу, до сохранения, и показывается на языке интерфейса.

Допустимость значения определяет сервер: подсказка описывает рекомендуемый формат ввода и клиентской проверкой не является. Если сервер отклоняет настройку, интерфейс показывает его сообщение целиком, тем же разбором, что и остальные ошибки сохранения, — раньше подсказка о формате дописывалась к ответу только тогда, когда текст ошибки сервера дословно совпадал с одной английской формулировкой, и на других языках и формулировках не появлялась. При диагностике отклонённого псевдонима опирайтесь на фактический ответ сервера.

## Типичные ошибки настройки

Частые проблемы настройки интеграций и способы их диагностики:

| Симптом | Причина | Где проверить | SQL-диагностика |
|---------|---------|---------------|-----------------|
| Тест соединения 1С падает | Неверный адрес/учётные данные в профиле Sync1C | `sync-1c`, `/api/admin/sync1c/config/test-connection` | `select top (50) [Date], SettingsName, Message, TechData from dbo.Sync1CLog order by [Date] desc;` |
| Очередь Sync1C не разгребается | Превышен retry, события не очищены | `/api/admin/sync1c/queue/*` | `select Id, RetryCount, DateAdded, DateOfLastTry from dbo.Sync1CEventQueues order by RetryCount desc, DateAdded asc;` |
| Задача из события 1С сохранилась, но пересчёт тегов или смарт-доступа не применился | Сбой необязательного блока откатился к точке сохранения и не прервал сохранение данных | список некритичных ошибок, `Sync1CLog` | `select top (50) [Date], SettingsName, Message, TechData from dbo.Sync1CLog order by [Date] desc;` |
| Внешний сервис включён, но запросы не проходят | Неверные учётные данные/URL конкретного сервиса | соответствующая `*-service-settings` форма | `select * from dbo.UniversalApiServiceSettings; select * from dbo.DiadocServiceCredentials;` |
| Потоки очередей остановились после ошибки | `MessageFlows.HasErrors = 1` и ActionOnError=Stop | админка очередей | `select Id, FlowName, ActionOnError, HasErrors, FailedAttemptsCounter from dbo.MessageFlows;` |
| После смены FileProvider файлы недоступны | Некорректная конфигурация провайдера или fallback | `file-providers` + тест | `select ID, Name, TypeID, UseToWriteFiles, CompressContent from dbo.FileProviders;` |
| Запись очереди обмена с 1С навсегда осталась в состоянии «Выполняется», кнопка «Выполнить повторно» ничего не делает | Сертифицируемая сборка (`UniForm.Barebone`): обработчик типа «обмен с 1С» снят с компиляции | версия и профиль сборки площадки | `select Id, State, Type, Flow, OccurrencesCounter from dbo.MessageQueue where Type = 4;` |

## Сервисы внешних интеграций — подробные параметры

### Параметры сервисов EWS, Диадок и СБИС

EWS, Диадок и СБИС — внешние сервисы, параметры которых задаются в формах подключений.

> **`sys_general_settings`** в интерфейсе — это меню администратора → **«Система» → «Общие настройки приложения»** (блок «Редактирование пользовательских настроек»). Там включаются/выключаются сервисы (ключи вида «Diadoc Service») и задаются их системные ключи.

**EWS (Exchange Web Services)**

> **Связано.** Параметры подключения EWS описаны в [Календарь — администрирование](https://help.1forma.ru/domains/calendar/admin.md). Там же: приоритет «имперсонализация» над «перевоплощением», правило «показывать только занятость», исключение для Робот 1Ф.

---

**Диадок (ЭДО)**

**Версия:** v2.256+.

Настройки сервиса Diadoc хранятся в `dbo.DiadocServiceCredentials`. Жизненный цикл: после создания сервиса → включить в `sys_general_settings` («Diadoc Service»); перед удалением → сначала убрать из `sys_general_settings`.

**Порядок включения:**

1. Получить у Контура `ClientId` — заявка на API по адресу `diadoc-api@skbkontur.ru`; без него интеграцию не запустить.
2. Создать сервис типа `Diadoc`: «Система» → «Сервисы»; заполнить Логин, Пароль, `BoxId`, `ClientId`, `API Url` (параметры — в таблице ниже).
3. Включить сервис: «Система» → «Общие настройки приложения» → ключ «Diadoc Service».
4. Задать обязательный курсор синхронизации — ключ `DiadocLastEventsId` (там же, в «Общих настройках приложения»; формат — в таблице «CustomSettings ЭДО и интеграций» ниже). **Без него обмен не стартует, даже если сервис включён** — это две разные настройки.
5. Опционально: нестандартную логику обработки документов пишут на JINT-скриптах `[edo]` (ниже); для типовых маршрутов достаточно смарт-действий группы «Диадок».

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом Diadoc (страница «Сервисы») |
| Логин | Учётные данные в системе Диадок |
| Пароль | Пароль к аккаунту Диадок |
| `BoxId` | Идентификатор ящика организации в Диадоке. В веб-интерфейсе Диадока: «Настройки» → «Реквизиты организации», строка «Идентификатор ящика»; либо из адресной строки при входе в ящик — `https://diadoc.kontur.ru/{BoxId}/…` |
| `ClientId` | Уникальный строковый идентификатор клиента. Получается у `diadoc-api@skbkontur.ru` после заключения договора на API |
| API Url | Базовый адрес API Диадока: боевой контур — `https://diadoc-api.kontur.ru`, тестовый (песочница) — `https://diadoc-api.testkontur.ru`. Онлайн-подписание идёт через этот же адрес — отдельный адрес для подписания вводить не нужно |

**Способ авторизации (с 2.268).** У сервиса два варианта: **«Логин и пароль»** и **«OpenID Connect»**. Способ выбирается в поле «Способ авторизации» формы сервиса; для существующих подключений сохраняется «Логин и пароль», и его обмен работает как раньше.

Для OIDC заполняются четыре поля: «OIDC client_id», «OIDC client_secret», «OIDC refresh_token» и «URL OpenID-провайдера». `client_id` и `client_secret` берутся в Кабинете интегратора Диадока; первичный `refresh_token` выпускается там же вручную и вводится в настройку один раз — это разовый операционный шаг, а не часть обмена. Поле «OIDC client_id» не заменяет поле `ClientId` (API-ключ, полученный у Контура по договору): при работе по OIDC заполнены должны быть оба. Если «URL OpenID-провайдера» оставить пустым, используется адрес Контура `https://identity.kontur.ru`; адрес должен быть HTTPS и без параметров и учётных данных. Секреты не выносятся в обращения и журналы.

В OIDC-режиме сервис обменивает `refresh_token` на `access_token` и передаёт его API Диадока в заголовке `Authorization: Bearer`. Токен кэшируется до истечения срока, затем обновляется по refresh token; на парольную авторизацию система не переключается. Обновлённый refresh token сохраняется C#-контуром (фоновым заданием синхронизации) для следующих обменов. Скриптовый контур (библиотека `[edo] diadoc-api`) refresh token только читает и новый не записывает — иначе у сервиса получились бы две конкурирующие цепочки обновления. Если `client_id`, `client_secret` или `refresh_token` не заполнены, настройки не сохраняются — форма показывает ошибку валидации; поля с секретами, заполненные только символами `*` (маска), не принимаются. При истечении или отзыве refresh token выпустите новый в Кабинете интегратора и обновите его в настройке сервиса.

Поддержан только **Refresh Token Flow** — фоновый обмен без участия оператора. **Authorization Code Flow** и **Device Authorization Flow** не поддерживаются. Порядок выпуска токенов — в документации Контура: https://developer.kontur.ru/doc/diadoc-api/authentication.html.

**Доработка на JINT/SmartScript (с v2.267).** Часть бизнес-логики ЭДО можно реализовать не через встроенные C#-смарт-действия, а через системные библиотеки SmartScript на JavaScript (JINT) — без пересборки ядра. Список системных скриптов — в админке: **«Автоматизация» → «SmartScripts»** (скрипты с префиксом `[edo]`).

| Библиотека | Назначение |
|------------|------------|
| `[edo] eds-common` | Базовая. Общие функции: HTTP-вызовы, SQL-хелперы, логирование, кэш токенов, загрузка файлов, работа с JSON. Подключается первой |
| `[edo] diadoc-api` | Обёртка над API Диадок: отправка/приём документов, статусы, подпись |

Шаблон подключения в смарт-скрипте:

```javascript
include("[edo] eds-common");
include("[edo] diadoc-api");
```

**Работа скриптового контура по OpenID Connect (с 2.268).** Если у сервиса обмена Диадока выбран способ «OpenID Connect», библиотека `[edo] diadoc-api` работает по OIDC так же, как C#-контур: сама обменивает `refresh_token` на `access_token` у провайдера (`{URL OpenID-провайдера или https://identity.kontur.ru}/connect/token`, тело `application/x-www-form-urlencoded`: `grant_type=refresh_token`, `client_id`, `client_secret`, `refresh_token`) и передаёт токен API Диадока в заголовке `Authorization: Bearer`. Это касается и обычных операций с JSON, и загрузки бинарного содержимого — контента документа, печатной формы, архива. К устаревшему парольному входу в этом режиме библиотека не обращается.

Секреты `client_secret` и `refresh_token` библиотека читает из хранилища секретов по ключу `diadoc-{Id сервиса}` — из того же источника, что и C#-контур, с тем же переключателем `UseIntegrationSecrets` (см. [Секреты интеграций](https://help.1forma.ru/domains/integrations/secrets.md)). Срок жизни полученного токена библиотека берёт из ответа провайдера и обновляет токен заранее; ротированный refresh-токен она не сохраняет — владелец цепочки обновления C#-контур.

Если способ «OpenID Connect» выбран, но не заполнено одно из полей `OIDC client_id`, `OIDC client_secret` или `OIDC refresh_token`, операция обмена завершается ошибкой валидации; автоматического отката на логин и пароль нет — требования те же, что и для C#-контура. При отказе провайдера или отозванном refresh-токене причина попадает в журнал автоматизаций без `client_secret` и без значений токенов; для продолжения обмена выпустите новый refresh-токен в Кабинете интегратора и обновите его в настройке сервиса.

Прежние C#-смарт-действия продолжают работать и могут использоваться параллельно. Новые сценарии (маршрутизация, обработка ответов API, обмен документами) рекомендуется писать на JavaScript. Отладка — через стандартное логирование SmartScript. Большинство операций в JINT выполняются синхронно; очередь сообщений остаётся актуальной для синхронизации статусов и входящих документов.

---

**СБИС (ЭДО)**

**Версия:** v2.260+.

Настройки сервиса SBIS хранятся в `dbo.SbisCredentials`. Жизненный цикл аналогичен Диадоку: включение через `sys_general_settings` («Sbis Service»), удаление — только после отключения.

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом Sbis |
| Логин | Учётные данные в системе СБИС |
| Пароль | Пароль к аккаунту СБИС |
| API Url | Адрес API для подключения к СБИС |
| ИНН | ИНН компании |
| КПП | КПП компании |
| Уникальный ID | Идентификатор участника ЭДО (participantID) — из личного кабинета СБИС |

---

### CustomSettings ЭДО и интеграций

Глобальные ключи CustomSettings, относящиеся к ЭДО и интеграциям:

| Ключ | Тип | Назначение |
|------|-----|------------|
| `DiadocLastEventsId` | JSON | **Обязателен** для интеграции. Курсор последних событий Диадок: `{"LastEvents":[{"BoxId":"...","ClientId":"...","Timestamp":1704067200}]}`. `Timestamp` — наносекунды от `01.01.0001`; `0` → автозаполнение датой первого подключения |
| `DiadocLogEnabled` | bool | Логирование ответов API Диадок (для диагностики) |
| `SbisLastEventsId` | JSON | **Обязателен** для интеграции. Курсор последних событий СБИС: `{"LastEvents":[{"EventId":N,"ServiceId":N}]}` |
| `Sync1CQueueMaxRetryCount` | int | Количество повторных попыток при неудачной синхронизации из 1Ф в 1С (превышение → событие висит с `HasErrors=1`) |
| `EnableCipherInUniversalApiCallbackUrls` | bool | Шифрование callback-URL в UniversalAPI (для повышения безопасности обратных вызовов) |
| `RedefiningIdentity` | bool | Механизм смещения автоинкремента строк таблиц сущностей. Работает в связке с `dbo.Settings.ServerIdKey` (используется при объединении инсталляций / миграциях с пересечением ID) |
| `TranslationService` | string | Управление сервисом автоматического перевода локализованных значений. По умолчанию используется AI-сервис (`UniversalApi` с типом TranslateService). Настройка позволяет вернуться к Azure Cognitive Services |
| `DadataAddressProviderAppendApiV2Path` | string | Управляет тем, дописывает ли `DadataAddressProvider` сегмент `/api/v2` к URL провайдера из поля «API Url». Только явное значение `"false"` отключает автодоп; отсутствие ключа, `null`, `"true"` и любое другое значение — включают. Подробнее: раздел [DaData (подсказки)](#dadata-подсказки) |

---

### DaData (подсказки)

**Версия:** v2.256+. Сервис используется для работы подсказок ДП «Текст» и ДП «Адрес».

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом Dadata |
| Token | API-ключ из личного кабинета dadata.ru |
| API Url | `https://suggestions.dadata.ru/suggestions/api/4_1/rs` |

#### Поведение флага `DadataAddressProviderAppendApiV2Path`

`DadataAddressProvider` строит итоговый URL через `new Uri(baseUri, "api/v2")` — стандартный relative-URI resolution .NET.

**Значение `"true"` (или ключ отсутствует) — автодоп включён:**

- К URL из поля «API Url» дописывается сегмент `api/v2`
- `https://suggestions.dadata.ru/` → `https://suggestions.dadata.ru/api/v2` ✅
- `https://suggestions.dadata.ru/suggestions/api/4_1/rs` → `https://suggestions.dadata.ru/suggestions/api/4_1/api/v2` ❌ — последний сегмент заменяется, путь сломан; RestSharp получает 404/HTML, десериализует в пустой объект, подсказки и нормализация адресов молча возвращают пустоту, ошибок в логе нет

**Значение `"false"` — автодоп отключён:**

- URL из настроек передаётся в `SuggestClient` без изменений
- `https://suggestions.dadata.ru/suggestions/api/4_1/rs` → `https://suggestions.dadata.ru/suggestions/api/4_1/rs` ✅
- Требуется при использовании актуального формата URL Dadata или корпоративного прокси (клиент, ВСК), где URL уже содержит полный путь

| Значение ключа | Итоговый URL (пример) | Когда использовать |
|---|---|---|
| отсутствует / `null` / `"true"` | `{URL}/api/v2` (relative resolution) | Старый формат URL: `https://suggestions.dadata.ru/` |
| `"false"` | `{URL}` без изменений | Актуальный формат URL или корпоративный прокси |

---

### PayControl (мобильная ЭП)

**Версия:** v2.256+.

> ⚠️ В системе может быть создан **только один** сервис PayControl.

Настройки хранятся в `dbo.PayControlServiceCredentials`. После создания — назначить группы через кнопку «Группа пользователей PC».

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом PayControl |
| `system_id` | Выдаётся при приобретении сервера PayControl |
| Адрес API | Адрес для подписания онлайн |
| Адрес Server Signer API | Адрес для подписания офлайн (если у ЭЦП включён признак «Серверное подписание») |
| Расширенное свойство (`user_id`) | Название расширенного свойства пользователя, в котором хранится `user_id` |
| Расширенное свойство (серверная подпись) | Название свойства, хранящего признак серверной подписи PayControl |
| Расширенное свойство разрешения смены устройства | Название свойства, хранящего признак разрешения повторной регистрации (`true`/`false`; отсутствие = `false`) |

Повторная регистрация требуется при перевыпуске сертификата, утере смартфона или переустановке приложения 1F Mobile.

---

### Apache Tika (извлечение текста)

**Версия:** v2.260+. Сервис необходим для работы `TikaJob` — полнотекстового индексатора файлов (поиск по файлам). Управление: включение/выключение через `sys_general_settings` («Tika Service»).

> ⚠️ Файлы `.md` и `.txt` обрабатываются без обращения к Tika — содержимое читается напрямую с автоматическим определением кодировки.

| Параметр | Описание | Рекомендация |
|----------|---------|--------------|
| Сервис | Предварительно созданный сервис с типом Tika | |
| API Url | Адрес API Tika | |
| Разрешённые типы файлов | Через запятую, без пробелов | `pdf,doc,docx,xls,xlsx,ppt,pptx,txt,xml,html,eml,sql,pgsql,json,md` |
| Максимальный размер (КБ) | Максимальный размер обрабатываемого файла | Рекомендуется 50000 |
| Максимум параллельных запросов | | Рекомендуется 10 |
| Разрешённые языки | Формат: `rus+eng+fre+ger+ita+spa+uzb` (первые 3 буквы, через `+`) | По умолчанию: English, French, German, Italian, Spanish, Uzbek |

---

### Azure TranslateService (AI-перевод)

**Версия:** v2.256+. Используется для автоматического перевода комментариев на все поддерживаемые языки через AI-сервис (задание `AzureCognitiveTranslateJob`).

> ⚠️ **Сценарий применения** (логика, где применяется, лог) — см. [Локализация — администрирование](https://help.1forma.ru/domains/localization/admin.md) § 4. Здесь — только параметры (URL/Ключ/Регион).

> ⚠️ Для AI-перевода используются **только** поля URL и Ключ. Поля «Логин» и «Пароль» в AI-режиме не задействованы.

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом TranslateService |
| URL | `https://api.cognitive.microsofttranslator.com/translate?api-version=3.0` |
| Ключ | Azure Cognitive API key |
| Регион | Например, `westeurope` |

Переключение на Azure: в `SettingsCustom` ключ `TranslationService` = `azure`.

---

### UniversalApi (внешние AI-вызовы)

**Версия:** v2.264+. Асинхронное взаимодействие с внешними AI-сервисами через очередь — запрос отправляется, ответ приходит через callback.

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом UniversalApi |
| ApiUrl | Адрес API внешнего сервиса |
| ApiKey | Уникальный код для идентификации |
| Callback поток | Выбор из существующих потоков очереди |
| Callback очередь | Выбор из существующих произвольных событий очереди |
| Владелец callback (авторизация) | Пользователь-владелец сервиса: выбор одного пользователя, поле необязательное. Callback-эндпоинт принимает вызовы только от него — сессия вызывающего сверяется с владельцем. Строгость проверки задаёт платформенный ключ `EnforceUniversalApiCallbackOwnerAuthorization`: если владелец не задан, при выключенном ключе вызов пропускается с предупреждением в лог, при включённом — отклоняется (403) |

Результат записывается в `MessageQueue`/`MessageQueueLog`: колонка `textResult` (текст), `booleanResult` (да/нет).

Для упрощённого формирования запросов доступно смарт-действие **«Вызов внешнего сервиса»**.

---

### VectorSearch (векторный поиск)

Внешний AI-сервис, обеспечивающий векторный (семантический) поиск по задачам. Настройки хранятся в `dbo.VectorSearchServiceSettings`, форма автоадминки — `vector-search-service-settings`.

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом VectorSearch (страница «Сервисы») |
| ApiUrl | Адрес API внешнего сервиса векторного поиска |

Серверная часть векторного поиска описана в домене «Поиск».

---

### PT Sandbox (антивирусная проверка файлов)

**Версия:** v2.266+. Перехватывает загрузку файлов до записи в хранилище.

> ⚠️ Детальное описание всех 13 параметров конфигурации, архитектура, API PT Sandbox v5.7, фильтры, кеш вердиктов, таблицы БД — в [PT Sandbox — интеграция](https://help.1forma.ru/domains/integrations/pt-sandbox.md).

В этом разделе — только краткая сводка для администратора.

Настройки: форма `pt-sandbox-service-settings` (таблица `dbo.PTSandboxServiceSettings`) + отдельная форма `pt-sandbox-domain-settings` (фильтрация по доменам, таблица `dbo.PTSandboxDomainSettings`). Включение — через `sys_general_settings` («PT Sandbox Service»).

**Нет встроенного теста подключения** — только реальная загрузка файла для проверки.

---

### Контур.Облако (облачная УКЭП)

**Версия:** v2.266+. Облачная электронная подпись без локального токена. Используется для подписания на маршруте согласования, выбора сертификата из Контура, подтверждения SMS-кодом.

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом Контур.Облако |
| API Key | Для заголовка `X-KONTUR-APIKEY` |
| Адрес сервера | Адрес для операций подписания, загрузки файлов, получения статусов |

Процесс подписания: пользователь выбирает сертификат → отправляется SMS-код → ввод кода → подписание.

При наличии сертификатов разных типов (НЭП, УКЭП) система автоматически фильтрует список, показывая только сертификаты нужного типа.

---

### Контур.КЭДО (кадровый ЭДО)

**Версия:** v2.266+. Работает **совместно с Контур.Облако**: КЭДО предоставляет организационный контекст, Облако выполняет подписание.

Возможности: получение списка сотрудников из КЭДО, привязка логина КЭДО к пользователю 1Формы, получение действующих сертификатов, подписание кадровых документов (приём, увольнение, отпуска).

| Параметр | Описание |
|----------|---------|
| Сервис | Предварительно созданный сервис с типом Контур.КЭДО |
| Адрес сервера | Адрес API Контур.КЭДО |
| Идентификатор клиента | ID приложения для OAuth-авторизации в Контуре |
| Идентификатор организации | OrgID для запроса сотрудников и сертификатов (CertificatesRequest.OrgId) |
| API Key | Для заголовка `X-KONTUR-APIKEY` |
| Логин | Сервисный логин для получения access token |
| Пароль | Пароль сервисной учётной записи |

---

### Контур.Фокус (импорт данных о контрагентах)

Интеграция обогащает карточки контрагентов сведениями из сервиса Контур.Фокус по ИНН и/или ОГРН. Настраивается как импорт данных (DataSync): по реквизитам организации из Контур.Фокуса подтягиваются данные и записываются в дополнительные параметры задач.

Это отдельная интеграция, не связанная с Контур.Облако и Контур.КЭДО (подписание/ЭДО). Её также не следует путать со встроенной проверкой контрагентов Анфисой (инструмент kontur_focus_check) — у той свой отдельный ключ и канал.

**Доступные категории данных** (методы API Контур.Фокус):

| Категория | Что импортирует |
|-----------|------------------|
| Реквизиты (`req`) | Наименование, ОГРН, КПП, статус, адрес, руководитель, ОКВЭД и др. |
| Краткий отчёт (`briefReport`) | Сводка по организации с маркерами благонадёжности (зелёный / жёлтый / красный) |
| Аналитика (`analytics`) | Аналитические и скоринговые показатели |
| Бухгалтерская отчётность (`buh`) | Данные бухгалтерской отчётности |
| Финансы (`finan`) | Финансовые показатели |
| Контакты (`contacts`) | Телефоны, сайты и другие контакты |
| Выписка (`excerpt`) | Выписка из ЕГРЮЛ/ЕГРИП |

**Настройки импорта:**

- Ключ доступа — API-ключ Контур.Фокуса, передаётся сервису при каждом запросе.
- ID ДП, содержащего ИНН и ID ДП, содержащего ОГРН — дополнительные параметры задачи, из которых берутся реквизиты для запроса (достаточно одного из них).
- Сопоставление полей — какие поля ответа Контур.Фокуса в какие дополнительные параметры задачи записывать.

Обмен обращается к API Контур.Фокус по адресу https://focus-api.kontur.ru/api3/. Импорт запускается по расписанию или вызовом POST app/v1.0/api/DataSync/Import/{идентификатор}, где идентификатор — числовой Id импорта или его псевдоним (алиас конечной точки).

---

### Matomo (веб-аналитика)

**Версия:** v2.256+.

> ⚠️ В Matomo аналитическая группа устанавливается для `customDimension` с `id=1`. Установка другого ID невозможна.

Настройка: ключ `matomo` в `SettingsCustom`.

**Формат CustomSettings:**
```json
{
  "baseURL": "https://***/matomo.php",
  "serverAddress": "***.***.ru",
  "siteId": 5,
  "analyticGroups": [...]
}
```

**CustomDimension ID=1 (контекст — клиент):**

| Значение | Описание |
|----------|---------|
| `firstForm` | Все внутренние пользователи 1Формы (HD) |
| `firstFormOutstaff` | Внешние пользователи 1Формы |

**CustomDimension ID=2 (действия — тип страницы):**

| Значение | Описание |
|----------|---------|
| `tasksView` | Просмотр карточки задачи на любом синдикате |
| `tasksCreate` | Просмотр карточки создания новой задачи |
| `tasksList` | Просмотр списка задач категорий |
| `templatesView` | Просмотр шаблона МТФ (только для МП) |
| `templatesCreate` | Создание шаблона НТФ (только для МП) |
| `chatsList` | Список чатов |
| `chatsView` | Просмотр чатов |
| `chatsCreate` | Создание чата |
| `dashboardsView` | Портал (дашборд) |
| `contactsList` | Экран просмотра и поиска контактов |
| `profileView` | Просмотр профиля пользователя |
| `calendarsView` | Календарь |
| `feedsList` | Лента |

---

### Telegram-бот (двунаправленный чат)

Чат-бот позволяет дублировать сообщения между чатами Telegram и задачами-чатами 1Формы. Реализуется как **публикация** + Lua-скрипты, в которых проксируются обновления Telegram API в комментарии задачи (и наоборот).

**Архитектура**: интеграция целиком на конфигурации (Lua SmartScripts + публикации + пользовательские таблицы); платформенный код отвечает только за отправку 2FA-кодов.

#### Шаги настройки

**В Telegram:**

1. Через `@BotFather` командой `/newbot` создать бота. Username должен заканчиваться на `bot` (например, `Chat1FBot`); если занят — будет ошибка «Sorry, this username is invalid».
2. Сохранить токен HTTP API (`bot token`) и ID бота — потребуются в Lua-скрипте.
3. Добавить бота как участника в нужный чат Telegram.

**В 1Форме:**

1. Создать **служебного пользователя** для роли чат-бота (его ID подставляется в скрипт).
2. Создать таблицы и представление БД:
   - `cm_Telegram_ChatToTask` — связь TelegramChatID ↔ TaskID.
   - `cm_tlg_tasks` — связь сообщения Telegram с задачей (чат, `message_id`, `task_id`); нужна для последующих edit / delete.
   - View `cm_vw_ChatToTask` — производная от `cm_Telegram_ChatToTask` (через JOIN с `cm_tlg_tasks`); используется во всех smart-фильтрах правил.

   Ещё две таблицы механизма синхронизации заводит миграция при обновлении системы — вручную их создавать не нужно:
   - `cm_tlg_message_map` — связка «сообщение Telegram ↔ комментарий 1Формы» (`ChatID`, `MessageID`, `CommentID`, `TaskID`); уникальность по паре «чат + сообщение» не даёт завести две связки на одно сообщение.
   - `cm_tlg_update_seen` — отметки уже принятых обновлений Telegram (`UpdateID`, дата приёма): Telegram повторяет доставку при таймауте, отметки нужны, чтобы повтор не обрабатывался как новое обновление.

   Обе лежат в схеме `custom`; накат миграции идемпотентный — таблица и каждый индекс проверяются отдельно, поэтому повторный прогон восстановит недостающий индекс.
3. Заполнить в профилях пользователей:
   - `Users.ICQ` — числовой Telegram-ID (для поиска `@id` в `chat_id`/`user_id`).
   - `Users.TelegramUserName` — `@username` (для упоминаний; если не задан, в `entities` используется `text_mention` с `firstName`).
4. Системные категории в разделе **Системный**:
   - **«Общение»** — личные чаты (только два участника: пользователь + бот).
   - **«Группы»** — групповые чаты Telegram.
   Бот один на площадку (на все категории и чаты).

5. Создать **публикацию** с Lua-скриптом — обработчик входящего webhook (точка входа: `dbo.1fSynkChat_webhook_telegram @Mode = @json`).
6. В смарт-действиях системных категорий настроить отправку комментариев из 1Ф обратно в Telegram (см. ниже).

#### Маршруты Bot API

Используются в смарт-действии «Отправить HTTP-запрос» (Url — токен бота + маршрут):

| Маршрут | Используется на событии |
|----------|-------------------------|
| `https://api.telegram.org/bot{token}/sendMessage` | После написания комментария (создание сообщения в Telegram) |
| `https://api.telegram.org/bot{token}/editMessageText` | После редактирования комментария (правка текста по `message_id`) |
| `https://api.telegram.org/bot{token}/deleteMessage` | Перед удалением комментария / После удаления подписчика |

После `sendMessage` ответ парсится: `$.HttpResponse.ResponseContent.result.chat.id` и `$.HttpResponse.ResponseContent.result.message_id` записываются в `cm_tlg_tasks` для последующих `editMessageText` / `deleteMessage`.

#### События-триггеры (исходящие из 1Ф в Telegram)

Исходящие события и отправляемые при них запросы в Telegram:

| Событие | Назначение |
|---------|------------|
| После написания комментария (комментарий не пустой, не ответ, без адресатов) | Отправка обычного сообщения |
| После написания комментария (есть адресаты) | Отправка с `entities` (упоминания) |
| После написания комментария (является ответом) | Отправка с `reply_to_message_id` |
| После редактирования комментария | `editMessageText` по сохранённому `message_id` |
| Перед удалением комментария | `deleteMessage` по `message_id` |
| После удаления подписчика | Удаление пользователя из чата (через Telegram-API) |
| Перед удалением задачи | Очистка чата / связей |
| После перехода / После смены текста задачи | Уведомления в чат |

Все правила используют smart-фильтр вида:

```sql
select 1 from cm_vw_ChatToTask v where v.TaskID = @ContextID
-- + опционально для edit/delete:
join [custom].cm_tlg_tasks t on v.chatid = t.tlg_chat_id
where t.task_id = @eventParam0
```

#### Параметр `entities` (упоминания)

Для упоминаний (`@username` или `text_mention` пользователя без публичного username) формируется JSON-массив с полями `offset`, `length`, `type`, и опциональным `user.id`:

- `type = "mention"` — если у пользователя задан `TelegramUserName` (`@…`).
- `type = "text_mention"` — если только `ICQ` (числовой ID); в `user.id` подставляется `ICQ`.

Список адресатов берётся из `dbo.CommentParticipants` через JOIN с `Users`.

**Распознавание автора при публикации сообщения из Telegram в 1Ф:**

| Условие | Поведение |
|---|---|
| У пользователя в профиле 1Ф указан Telegram ID (`Users.ICQ`) | Сообщение публикуется от его имени |
| ID не указан, но есть подходящая учётная запись | Используется она |
| Нет учётной записи | Создаётся новый пользователь или используется служебный бот-пользователь (зависит от настроек скрипта) |

### WhatsApp (мессенджер)

**Версия:** v2.256+. Интеграция через чат-бота — пользователь пишет ключевое слово или числовой код. Сценарии общения задаются администраторами.

В отличие от Telegram, WhatsApp-бот может **самостоятельно инициировать** диалог (для этого нужен список контактов в 1Форме).

**3 способа интеграции**

| Способ | Преимущества | Недостатки |
|--------|-------------|-----------|
| Бизнес-аккаунт WhatsApp | Безопаснее; может сам инициировать диалог | Долгая процедура оформления; сложная документация |
| Chat API (платная подписка) | Быстрое оформление; подробная документация | Платная; ниже уровень безопасности |
| WAZZUP | Быстрая настройка; множество номеров | Требует прогрев аккаунта |

**WAZZUP — 6 шагов настройки**

1. Зарегистрироваться на wazzup24.ru
2. Добавить канал WhatsApp → сканировать QR-код
3. Скопировать ключ API (раздел «Интеграция с CRM» → API → «Подключить»)

> ⚠️ **Прогрев аккаунта (критично):**
> - Новый аккаунт: переписываться с 10–15 людьми в течение суток
> - Для стабильной работы: открывать WhatsApp раз в пару недель
> - При нарушении: WhatsApp разлогинивает из WAZZUP → переподключение канала

**Отправка сообщений (POST):**
```
POST https://api.wazzup24.com/v3/message
Authorization: Bearer {key}
Content-Type: application/json

{
  "channelId": "...",       // uuidv4 канала
  "chatType": "whatsapp",   // или "whatsgroup"
  "chatId": "...",
  "text": "...",
  "crmMessageId": "..."
}
```

**Webhooks (PATCH):**
```
PATCH https://api.wazzup24.com/v3/webhooks
{
  "webhooksUri": "https://...",
  "subscriptions": {
    "messagesAndStatuses": true,
    "contactsAndDealsCreation": true,
    "channelsUpdates": true,
    "tepmplateStatus": true
  }
}
```

Webhook-URL получает тестовый POST `{test: true}` — должен вернуть 200.

Lua-примеры (отправка ответа, получение входящих, обработка файлов) реализуются отдельным Lua-скриптом.

---

### PHP-интеграция (вызовы из PHP)

**Версия:** v2.184+ (токены); до v2.184 — только cookie.

> **Связано.** Заголовок `1FormaAuth` и схема аутентификации описаны в [Авторизация — администрирование](https://help.1forma.ru/domains/auth/admin.md). Специфика PHP: `json_decode` для токена и особенности curl.

#### Метод 1: токены (v2.184+)

Пример получения токена и запроса к API на PHP:

```php
// Получение токена
$authUrl = $formaUrl . "/app/v1.0/api/auth/token?login=" . $formaUser . "&password=" . $formaPwd;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $authUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Accept: application/json"]);
$result = curl_exec($ch);
curl_close($ch);

// ВАЖНО: json_decode ОБЯЗАТЕЛЕН — токен возвращается как JSON-строка в кавычках
$token = json_decode($result);
```

```php
// Запрос к API
$url = $formaUrl . "/app/v1.0/api/info";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["1FormaAuth: " . $token]);  // НЕ "Authorization: Bearer"
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$result = curl_exec($ch);
curl_close($ch);
```

> ⚠️ `Authorization: Bearer {token}` → **всегда 401**. Только заголовок `1FormaAuth`.

#### Метод 2: cookie (устаревший, до v2.184)

Авторизация по cookie (для версий до 2.184):

```php
$authUrl = $formaUrl . "/iOSClientServices/Auth.ashx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $authUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "UserName=" . $formaUser . "&Pass=" . $formaPwd . "&IsDebug=1");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $result, $matches);
$cookies = [];
foreach ($matches[1] as $item) {
    parse_str($item, $cookie);
    $cookies = array_merge($cookies, $cookie);
}
curl_close($ch);
```

---

### Онлайн-редакторы: MS Office Online и OnlyOffice CE

MS Office Online и OnlyOffice CE — два варианта онлайн-редакторов, параметры которых задаются в `OfficeOnlineEditor`.

**MS Office Online (webApps) — устаревший**

> **Удалено в актуальных версиях.** Ключ `OfficeOnlineEditor.editor=webApps` в актуальной сборке не работает: интеграция с Office Web Apps Server убрана, серверные настройки и WOPI-discovery не используются. Для онлайн-просмотра и редактирования документов используйте Р7-Офис (`editor=r7`) или OnlyOffice CE (`editor=OnlyOffice`, см. ниже). Информация ниже сохранена как историческая.

CustomSettings ключ `OfficeOnlineEditor`:
```json
{"editor": "webApps"}
```

> ⚠️ **Обязательное условие (исторически):** в корневой папке веб-сервера должен существовать файл discovery:
> `C:\inetpub\wwwroot\DevTC\wopi`
>
> Без этого файла редактор не открывался. В актуальной сборке файл больше не учитывается.

Параметры Web Apps задавались в `sys_general_settings#webapps`.

---

**OnlyOffice CE (ограничения)**

**Версия:** v2.257+.

> **Связано.** Версионирование ключа `r7` → `onlyOffice` с v2.265 описано в [Файлы — онлайн-просмотр (диагностика)](https://help.1forma.ru/domains/files/online-preview-troubleshooting.md). CustomSettings формат и персонализация — там же.

**CustomSettings ключ `OfficeOnlineEditor`:**
```json
{"editor": "OnlyOffice", "settings": {"serverAddress": "https://domain/office", "allowedIPs": []}}
```

| Параметр | Описание |
|----------|---------|
| `editor` | `OnlyOffice` (v2.265+); `r7` (v2.264 и ниже — только для Р7-Офис) |
| `serverAddress` | Адрес сервера OnlyOffice (например, `https://domain/office/`) |
| `allowedIPs` | Список разрешённых IP или подсетей (может быть пустым) |

**appsettings.json `R7.SecretKey`** — ключ для подписи запросов к Р7-серверу (минимум 32 символа). Требуется при `OfficeOnlineEditor.editor=r7` или `OnlyOffice` для совместимых развёртываний:

```json
"R7": { "SecretKey": "yourSecretKey" }
```

**Ограничения OnlyOffice CE (критично)**

> ⚠️ **Лимит 20 одновременных сессий.** При превышении все последующие подключения открываются только в режиме **readonly**.

> ⚠️ **Кластеризация не поддерживается.** Для кластеризации/отказоустойчивости/большой нагрузки — OnlyOffice Enterprise или Р7-Офис.

**Требования к ресурсам (OnlyOffice CE)**

| Пользователей | vCPU | RAM | Storage |
|---------------|------|-----|---------|
| < 100 | 1 | 4 GB | 40 GB |
| 100–200 | 2 | 4 GB | 80 GB |
| 200–400 | 4 | 4 GB | 160 GB |

---

### 1С — справочник XML-тегов

Справочник XML-тегов синхронизации с 1С описывает структуру настроек, реквизитов, файлов и событий.

> Теги начинаются с `1C` (настройки 1С:Предприятие) или `TC` (настройки 1Формы).

#### SyncSettings — общие настройки синхронизации

Атрибуты корневого тега синхронизации:

| Атрибут | Описание |
|---------|---------|
| `Name` | Имя настроек (отображается в списке) |
| `OneCAddress` | Адрес сервиса 1С:Предприятие |
| `OneCUserName` / `OneCPassword` | Учётные данные 1С |
| `TCAddress` | Адрес сервиса 1Формы |
| `TCUserName` / `TCPassword` | Учётные данные 1Формы |
| `TCSommentOnEpChange` | Публиковать комментарии об изменении ДП (`true`/`false`). ⚠️ Только в общих настройках, не в категориях |
| `GUIDExtParamID` | ID ДП типа «Текст» для хранения GUID записей 1С. ⚠️ При нескольких задачах в категории с одинаковым GUID обновляется только последняя по `TaskID`; новые не создаются |
| `UsersDic` | Название справочника пользователей в 1С |
| `UsersFilter` | Имя булева реквизита 1С для фильтрации пользователей. Если не указан, но указан `UsersDic` — синхронизируются все |
| `UsersFilterIn1Forma` | Если `true` — фильтрация на стороне 1Ф (позволяет фильтровать по виртуальным реквизитам), но **значительно медленнее** физических реквизитов 1С |
| `QueryRepeatTime` | Интервал проверки очереди (формат `HH:mm:ss`, например `00:05:00`) |
| `TC1C_SyncLog` | Логирование первичной выгрузки: `0` — выкл., `1` — полные (по умолчанию), `2` — только ошибки |
| `UpdateLookupsByGuids` | Синхронизация Lookup ДП по GUID (`true`/`false`) |
| `SendErrorCommentToTask` | Записывать комментарий в задаче и сообщение в лог при ошибке. По умолчанию: `true` (если опция не указана или пустая) |
| `ImportStrategy` | `0` — только создание, `1` — только обновление, `2` — создание+обновление (по умолчанию) |

#### SyncRecords / Record — настройки справочника

Атрибуты тега `SyncRecords` / `Record`:

| Атрибут | Описание |
|---------|---------|
| `OneCDocName` | Системное имя справочника/документа в 1С |
| `OneCSynonym` | Псевдоним справочника/документа в 1С |
| `TCSubcatID` / `TCSubcatName` | ID/название категории в 1Ф |
| `SyncSource` | Источник данных (только источник может создавать задачи/документы): `_1C` / `_TC` / `Both` |
| `SyncDirections` | Направление: `TwoSided` / `From1CtoTC` / `FromTCto1C` |
| `DefaultActionOnError` | При ошибке входящего события: `NotAssigned` (игнорировать) / `Ignore` (только уведомить) / `ForceAddToQuery` (сразу в очередь) / `AddToQuery` (в очередь после первой ошибки) / `Cancel` (отклонить) |
| `DefaultNotificationOnError` | Способ уведомления при ошибке: `NotAssigned` / `Comment` (комментарий к задаче) / `Alert` (предупреждение) / `Both` |
| `DefaultErrorMessage` / `DefaultSuccessMessage` | Сообщения об ошибке/успехе по умолчанию (используются, если не указаны для конкретного события) |
| `SmartFilterID` | ID смарт-фильтра для отбора задач, отправляемых из 1Ф в 1С. `0` — фильтрация выключена |
| `DisableTaskTextSync` | `true` — тексты задач 1Ф не заменяются на тексты из 1С (по умолчанию `false`) |
| `InboxQueueFlowId` | Опциональный flow для входящих документов (`None` по умолчанию). Подробнее — в [Сопоставление сущностей 1С](https://help.1forma.ru/domains/integrations/1c-entity-mapping.md) |

#### Files — синхронизация вложенных файлов

Дочерний для `Record` тег. Управляет синхронизацией файлов между задачами 1Ф и реквизитами 1С.

| Атрибут | Описание |
|---------|---------|
| `CatalogName` | Имя справочника 1С, в котором хранятся вложенные файлы |
| `BinFileProperty` | Имя реквизита 1С с двоичными данными файла |
| `FileNameProperty` | Имя реквизита 1С с именем файла |
| `OwnerProperty` | Имя реквизита 1С со ссылкой на документ-владелец |
| `SyncDirections` | Направление синхронизации файлов: `TwoSided` / `From1CtoTC` / `FromTCto1C` |
| `ExtParamIds` | Список ID ДП «Файл» в 1Ф, для которых выполняется обмен. Если в категории два ДП «Файл», но указан только один — обмен происходит только при работе с этим ДП; вложения в другие ДП и в общие вложения задачи **не синхронизируются** |

#### Сопоставление реквизитов и события синхронизации

**SyncExtParams / Property — сопоставление реквизитов**

| Атрибут | Описание |
|---------|---------|
| `RequisiteName` / `Synonym` | Системное имя и имя реквизита в 1С |
| `ExtParamID` / `ExtParamName` | ID/название ДП в 1Ф |
| `Type` | Тип ДП: `Checkbox`, `Combobox`, `Date`, `DateTime`, `LookUpField`, `Money`, `Numerator`, `NumericValue`, `Select`, `Table`, `Text`, `TextArea`, `TextAreaWOFormat`, `URL` |
| `RepresentAsReadonlyText` | `true` — передавать как текст, без выгрузки подчинённого справочника |

**Event1C — события из 1С (7 типов)**

| Событие | Описание | Action |
|---------|---------|--------|
| `Create` | Создание документа | `ChangeTask` / `ChangeToStatus` / `DeleteTask` |
| `Modify` | Изменение | `ChangeTask` / `ChangeToStatus` / `DeleteTask` |
| `Post` | Проведение | `ChangeTask` / `ChangeToStatus` / `DeleteTask` |
| `ClearPost` | Отмена проведения | `ChangeTask` / `ChangeToStatus` / `DeleteTask` |
| `Repost` | Перепроведение | `ChangeTask` / `ChangeToStatus` / `DeleteTask` |
| `MarkDelete` | Пометка на удаление | `ChangeTask` / `ChangeToStatus` / `DeleteTask` |
| `UnmarkDelete` | Снятие пометки на удаление | `ChangeTask` / `ChangeToStatus` / `DeleteTask` |

**EventTC — события из 1Ф**

| Событие | Описание |
|---------|---------|
| `CreateTask` | Создание задачи |
| `ChangeTask` | Изменение ДП |
| `ChangeToStatus` | Переход в статус |
| `MakeStep` | Переход по маршруту |
| `DeleteTask` | Удаление задачи |
| `FileUpload` / `FileDelete` | Вложение/удаление файла |
| `EPFileUpload` | Загрузка файла в ДП |
| `CustomEvent` | Произвольное событие |

**EventTC → действия в 1С**

| Action | Описание |
|--------|---------|
| `Create` / `Modify` | Создать/изменить документ |
| `Post` / `ClearPost` / `Repost` | Провести/отменить проведение/перепровести |
| `Lock` / `Unlock` | Заблокировать/разблокировать |
| `MarkDelete` / `UnmarkDelete` | Пометить на удаление / снять пометку |

---

## Связанные документы

См. также:

- [PT Sandbox — интеграция](https://help.1forma.ru/domains/integrations/pt-sandbox.md)
- [Календарь — администрирование](https://help.1forma.ru/domains/calendar/admin.md) — EWS
- [Локализация — администрирование](https://help.1forma.ru/domains/localization/admin.md) — Azure TranslateService (сценарий)
- [Файлы — онлайн-просмотр (диагностика)](https://help.1forma.ru/domains/files/online-preview-troubleshooting.md) — OnlyOffice CE, версионирование ключа `r7→onlyOffice`
- [Авторизация — администрирование](https://help.1forma.ru/domains/auth/admin.md) — PHP-интеграция, заголовок `1FormaAuth`
- [Системные настройки](https://help.1forma.ru/domains/system/admin.md)
- [Почта — администрирование](https://help.1forma.ru/domains/mail/admin.md)
