# Смарт-действия — системные (HTTP, SQL, SmartScript, события)

> ⚠️ Символом **\*** помечены обязательные параметры. Часть [Справочника смарт-действий](https://help.1forma.ru/domains/smart-actions/actions-reference.md); как вызывать действия из SmartScript и типы параметров — там же ([Типы данных](https://help.1forma.ru/domains/smart-actions/actions-reference.md#типы-данных)).

Системные действия: HTTP- и API-запросы, SQL-скрипты, запуск смарт-скриптов, события и очереди, повторения/расписания, импорт данных, пакеты действий и смарт-фильтры.

## Системные действия (HTTP, SQL, SmartScript, события, повторения)

### Отправить HTTP-запрос (`SendHttpRequest`, ID 85)

Произвольный HTTP-вызов из смарт-пакета. Помимо стандартного режима, в SmartScript есть helper-обёртка `HttpRequestJson` (с ретраями и JSON-сериализацией) — описана в начале документа § «Топ-10 действий».

**Результат** — строка JSON в `@ActionResult{N}`: `{ "InnerError": …, "HttpResponse": { "StatusCode": …, "ResponseContent": …, "ResponseHeaders": … } }`. Формы полей: `StatusCode` — число (или `null`, если ответа нет); `ResponseContent` — вложенный JSON, если тело ответа валидный JSON (`{…}`/`[…]`), иначе строка; `ResponseHeaders` — объект «имя: значение»; `InnerError` — описание ошибки при неуспешном вызове, иначе `null`. Читается последующим действием, например `JSON_VALUE(@ActionResult{N}, '$.HttpResponse.ResponseContent')`. Числа вне диапазона `decimal` и целые больше `long.MaxValue` в `ResponseContent` встраиваются строкой, а не числом.

**Гейт адреса.** Перед отправкой адрес проверяется: схема — только `http` или `https`, имя хоста обязано входить в список из настройки `SmartAction_SendHttpRequest_AllowedHosts`. Список действует всегда, включая пустой: незаполненная настройка запрещает любой исходящий вызов этого действия. Проверяется итоговый адрес, поэтому подстановка выражением, скриптом или значением задачи под гейт попадает так же, как литерал. Адрес вне списка или с другой схемой не отправляется — пакет получает отказ с причиной. Общий HTTP-клиент платформы гейт не затрагивает: проверка включена только для этого действия. Проверяется не только исходный адрес, но и каждый шаг цепочки переадресаций: если разрешённый сервер отвечает редиректом на хост вне списка, переход не выполняется, тело и заголовки наружу не уходят, а пакет получает отказ с причиной. Автоматическое следование редиректам у этого действия отключено, переходы выполняются вручную с ограничением их числа; при переходе метод приводится к GET, кроме кодов 307 и 308, сохраняющих метод, а заголовок `Authorization` снимается.

### Отправить универсальный API-запрос (`SendUniversalApiRequest`, ID 184)

HTTP-запрос через сервис UniversalApi (с типизацией, шифрованием callback-URL по `EnableCipherInUniversalApiCallbackUrls`, AI-вызовами).

**Пользователь доступа.** У действия есть необязательный параметр «Пользователь доступа» (в конце списка): доступ к файлам библиотеки, передаваемым в запрос, проверяется от его имени. Пусто — пользователь сессии. Фоновый запуск без сессии и без заданного пользователя завершается отказом в доступе. Системного робота указывают явно и только для доверенных фоновых сценариев.

> **Недоступно в 1F Certificate Edition** (ФСТЭК-сборка): подсистема `ExternalApiRequests`, контроллер приёма обратных вызовов и само действие в этой сборке недоступны.

### Выполнить SQL-скрипт (`ExecuteSql`, ID 96)

Произвольный TSQL/PGSQL. Используется для вспомогательных обновлений/выборок вне типизированных смартов.

> **Недоступно в 1F Certificate Edition** (ФСТЭК-сборка): действие исключено из сборки; пакеты действий, где оно было настроено ранее, в этой редакции не выполняются.

**Гейты безопасности:**

- Добавить это действие в пакет может только пользователь с правами god — проверка на этапе настройки пакета (`PacksLogic.AddAction`), иначе отказ `exception_NotGod`.
- Исполнение блокируется, если в конфигурации приложения включён флаг `DisableSqlShellInSmartExpressions` (по умолчанию выключен). Это отдельный флаг: `DisableSqlShell` относится к административной SQL-консоли и на это смарт-действие не влияет.
- DDL-конструкции `DROP`/`TRUNCATE`/`GRANT`/`ALTER` отклоняются дополнительным фильтром (по границам слов); при отказе пишется запись аудита с префиксом `[SmartAction ExecuteSql]`. Это защита в глубину, а не единственная граница безопасности.

| Параметр | Тип | Описание |
|----------|-----|----------|
| Список параметров | `Collection<CustomParameter>` | Параметры для подстановки в запрос (опционально) |
| SQL-скрипт* | `String` | Текст TSQL/PGSQL |

**Результат:** `String` — результат запроса (JSON).

### Выполнить смарт-скрипт (`ExecuteSmartScript`, ID 106)

Запуск SmartScript (Lua / JS / C# / Python) синхронно или асинхронно. В JS-движке параметры передаются через `params: {...}` и доступны в скрипте через `PARAMS`.

> **Недоступно в 1F Certificate Edition** (ФСТЭК-сборка): действие исключено из сборки вместе с подсистемой смарт-скриптов; пакеты, где оно было настроено, в этой редакции не выполняются и не сохраняются.

| Параметр | Тип | Описание |
|----------|-----|----------|
| Скрипт* | `String` | ID или имя смарт-скрипта |

**Результат:** результат выполнения скрипта (строка).

### Добавить новое событие в очередь (`AddNewEventToQueue`, ID 107) / Запустить пользовательское событие (`FireCustomEvent`, ID 56)

Постановка события в очередь обработки или прямой запуск произвольного события. Используется для асинхронных пайплайнов между категориями (когда нужен trigger без прямой ссылки).

Параметры «Запустить пользовательское событие» (`FireCustomEvent`, 56):

| Параметр | Тип | Описание |
|----------|-----|----------|
| Задача* | `1F.Task` | Задача-контекст |
| Событие* | `1F.CustomEvent` | Событие для запуска |
| Задача-инициатор | `1F.Task` | Задача, инициировавшая событие |
| Пользователь-инициатор | `1F.User` | Инициатор события |

Параметры «Добавить новое событие в очередь» (`AddNewEventToQueue`, 107) — низкоуровневое:

| Параметр | Тип | Описание |
|----------|-----|----------|
| Тип* | `enum QueueType` | Тип очереди |
| Поток* | `QueueFlowDto` | Описание потока обработки |
| Событие | `enum StandardAction` | Стандартное действие-событие |
| Кастомное действие | `CustomQueueActionsEntity` | Пользовательское действие очереди |
| Внутренний ID | `Integer` | Внутренний идентификатор |
| Внешний ID | `Integer` | Внешний идентификатор |
| Параметры | `Collection<CustomParameter>` | Параметры, передаваемые в событие |

### Добавить внешний ключ (`AddExternalKey`, ID 108)

Привязка внешнего идентификатора (из стороннего сервиса) к задаче. Используется в интеграциях.

### Создать или обновить пакет действий (`CreateOrUpdateActionPack`, ID 189) / смарт-фильтр (`CreateOrUpdateSmartFilter`, ID 187)

Программная конфигурация автоматизации (используется при импорте конфигов и в конструкторах решений).

### Установить повторение (`AddRecurrence`, ID 121) / Добавить правило повторения (`AddRecurrenceCalculator`, ID 213) / Удалить правило повторения (`RemoveRecurrenceCalculator`, ID 214) / Удалить рекуррентность (`DeleteRecurrence`, ID 120) / Создать периодические задачи (`CreatePeriodicTasks`, ID 198)

Управление расписанием повторяющихся задач.

#### Параметры «Установить повторение» (`AddRecurrence`)

Параметры действия:

| # | Название | Тип | Описание |
|---|---|---|---|
| 18 | Поведение при нерабочем дне | enum | `NonWorkingDayBehavior` — что делать, если дата попадает на выходной |
| 19 | Материализовывать | bool? | Включить материализацию повторений → `IsMaterializationEnabled`. Если не задан — оставляет текущее значение (по умолчанию `false`) |

#### Параметры «Добавить правило повторения» (`AddRecurrenceCalculator`)

Параметры действия:

| # | Название | Тип | Описание |
|---|---|---|---|
| 13 | Номер рабочего дня | int? | Порядковый номер рабочего дня в месяце (1–31) → `WorkDayNumber`. **Только при `WorkDayType = custom`**, иначе ошибка. При превышении числа рабочих дней в месяце — используется последний |

#### Параметры «Удалить правило повторения» (`RemoveRecurrenceCalculator`)

Параметры действия:

| # | Название | Тип | Описание |
|---|---|---|---|
| 0 | Задача | int | Задача, у которой удаляется правило повторения |
| 1 | RecurrenceInfoId | int | ID правила (калькулятора) повторения для удаления — снимается соответствующая запись из `TaskRecurrenceCalculators` |

Парное действие к `AddRecurrenceCalculator` — для управления несколькими правилами повторения у одной задачи.

#### Формат итоговой метки правила повторения (v2.267+)

Итоговый текст правила отображается в контроле выбора и заголовке настройки. Для комбинации «год + конкретный рабочий день» применяются следующие правила форматирования:

**Компонент «рабочий день»** (аналогично месячным правилам):

| Тип (`WorkDayType`) | Отображение |
|---|---|
| Первый (`first`) | «Первый рабочий день» |
| Последний (`last`) | «Последний рабочий день» |
| Первый и последний (`firstAndLast`) | «Первый и последний рабочий день» |
| Конкретный (`custom`, `WorkDayNumber = N`) | «N-й рабочий день» |

**Компонент «год»:**

| Значение | Отображение |
|---|---|
| 1 | «каждый год» |
| N > 1 | «каждый N год» |

**Примеры итоговых меток:**

| Настройка | Отображаемый текст |
|---|---|
| 5-й раб. день, Январь, каждый год | «5-й рабочий день, каждый Январь, каждый год» |
| 5-й раб. день, Январь, каждый 2-й год | «5-й рабочий день, каждый Январь, каждый 2 год» |
| Первый раб. день, Январь, каждый год | «Первый рабочий день, каждый Январь, каждый год» |
| Последний раб. день, Январь, каждый год | «Последний рабочий день, каждый Январь, каждый год» |
| Первый и последний, Январь, каждый год | «Первый и последний рабочий день, каждый Январь, каждый год» |

### Обновить текст задач, зависящих от лукапа (`UpdateTasksTextDependentOnLookup`, ID 201)

Принудительное обновление `TaskText` в задачах, ссылающихся на изменённую через Lookup-связь задачу.

### Пересчитать смарт-доступ по правилу (`CountedSmartAccessByRule`, ID 74) / для расширенного параметра в подкатегории (`RecalculateSmartAccessForExtParamInSubcat`, ID 90)

Пересборка прав по правилам `SmartAccess` для конкретного набора задач (после изменения правила, чтобы не ждать batch-job).

Параметры обоих действий (отличается только тип правила):

| Параметр | Тип | Описание |
|----------|-----|----------|
| Правило* | `1F.SmartAccess` (74) / `1F.SmartAccessForExtParamsInSubcat` (90) | Правило смарт-доступа |
| ID задачи* | `Collection<1F.Task>` | Набор задач для пересчёта |
| Обновить все активные задачи* | `Boolean` | Пересчитать все активные задачи |

### Отправить сообщение пользователю (`SendMessageToUser`, ID 68) / с открытием задачи (`SendMessageToUserOpenTask`, ID 69) / с обновлением задачи (`SendMessageToUserRefreshTask`, ID 84) / VoIP push (`SendVoipPush`, ID 125) / пользовательское (`SendCustomMessageToUser`, ID 124) / вставить текст (`SendMessageToUserInsertText`, ID 210 — SignalR-команда вставки текста, параметры: пользователь, задача, текст)

Команды интерфейсу пользователя:

- **OpenTask** — посылает SPA-команду открыть карточку задачи (или произвольный URL).
- **RefreshTask** — форсирует перезагрузку карточки задачи в открытых вкладках пользователей.
- **VoipPush** — push для VoIP-звонков.

### Завершить опрос (`CompleteSurvey`, ID 196) / Обновить шаблон опроса (`UpdateSurveyTemplate`, ID 191)

Управление опросами SurveyJS / SurveyProject.

### Импорт данных (`DataImport`, ID 63)

Массовый импорт задач из CSV / xlsx / другой источник.

| Параметр | Тип | Описание |
|----------|-----|----------|
| Пользователь* | `1F.User` | Пользователь-контекст импорта |
| Импорт данных* | `DataImport` | Конфигурация импорта |
| Файл | `String` | Идентификатор файла: `fileId` или `fileId.versionId` |
| Параметры контекста | `String` | Дополнительные параметры (JSON) |

### Установить клиентскую зону задачи (`SetTaskCustomerZone`, ID 65) / Связать с клиентской зоной (`LinkTaskWithCZ`, ID 59)

Привязка задачи к Личному Кабинету (CZ).

### Установить определённый статус (`SetState`, ID 9) / Принудительно изменить статус (`ChangeTaskStateForcibly`, ID 38)

Прямое изменение `Tasks.StateID` без прохождения по маршруту. Принудительная смена обходит проверки переходов.

### Ответить (`Response`, ID 88)

Формирует HTTP-ответ для внешнего вызова (webhook/UniversalAPI): тип ответа, контент, HTTP-статус, заголовки, файл (все параметры опциональны). Результат — сериализованный ответ (`ActionResponseResultDto`). Не путать с ответом на комментарий.

### Синхронизировать статус сообщения (`SyncMessageStatus`, ID 163) / СБИС (`SyncMessageStatusSbis`, ID 188)

Опрос статусов исходящих документов в ЭДО.

### Создать уведомление по задаче (`CreateTaskNotification`, ID 41)

Создание системного уведомления (показывается в индикаторах пользователя).

### Переместить email-сообщение (`MoveEmailMessage`, ID 60)

Перемещение письма между папками почтового ящика.

| Параметр | Тип | Описание |
|----------|-----|----------|
| Почтовое сообщение* | `1F.Email` | Письмо |
| Текущая папка* | `1F.EmailFolder` | Папка-источник |
| Папка назначения* | `1F.EmailFolder` | Целевая папка |

### Отменить (`Cancel`, ID 6)

Прерывает обработку события (только в пакетах, привязанных к **«Перед …»**-событиям). Используется для запретов («нельзя понизить приоритет, если заказчик — гендиректор»).

### Добавить базовый план проекта (`AddProjectBasePlan`, ID 147)

Создание baseline-плана проекта (для сравнения «план-факт»).
