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

Интеграция с внешними системами может быть реализована посредством вебхуков на определенные API ендпоинты.

Для корректной обе системы должны хранить метаданные сущностей внешней системы. Например, ID заявки во внешней системе. Ниже будет представлен пример интеграции Swarmica со сторонним Helpdesk.

Схема взаимодействия:

Конечный пользователь → внешний Helpdesk → API → Swarmica

Конечный пользователь работает только во внешнем Helpdesk и может вообще не знать о существовании Swarmica.

Для подобного взаимодействия необходимо настроить во внешнем Helpdesk вебхуки, которые будут посылать API запросы в Swarmica в зависимости от событий происходящих во внешнем Helpdesk.

Для всех API запросов в Swarmica используются Headers в зависимости от вида токена.

для Bearer токена:

{
  "Content-Type": "application/json",
  "Authorization": "Bearer BEARER_TOKEN"
}

для API token:

{
  "Content-Type": "application/json",
  "Authorization": "Token API_TOKEN"
}

Сценарии взаимодействия

Сценарий 1: Создание тикета в Swarmica

На стороне внешнего Helpdesk должен быть настроен вебхук, который при определенных условиях(например создание заявки во внешнем Helpdesk) шлет в Swarmica API запрос на создание заявки.

Параметры API запроса в Swarmica:

Endpoint: /api/tickets/

Method: POST

Payload:

{
  "subject": "test API ticket 11111",         # тема заявки
  "comment": "Comment 1",                     # Описание проблемы   
  "ext_id": 12345,                            # ID заявки во внешнем Helpdesk
  "requester_email": "jdoe@example.tld",      # email заявителя
  "idempotency_key": "12345678"               # ключ идемпотентности
}

При успешном запросе возвращается подобный ответ(response):

response_text='{"id":56,"subject":"test API ticket 11111","ext_id":12345,"requester":"j9m7sRnuAHFcWD9Q","assignee":null,"group":null,"status":"OPEN","until":null,"priority":"normal","replies":1,"reopens":0,"created_at":"2026-08-20T08:10:00.432419Z","resolved_at":null,"updated_at":"2026-08-20T08:10:00.547359Z","is_fcr":false,"satisfaction_score":"UNOFFERED","custom_fields":[{"uid":"1KZHEyoEPQhaD0Ii","name":{"en":"Can grant access to environment","ru":"Могу дать доступ, если надо"},"mandatory_for":[],"value":null},{"uid":"ouVl3K0SUvirO-LR","name":{"en":"link","ru":"ссылка"},"mandatory_for":[],"value":null},{"uid":"UJB6rUrOwq0Oarjt","name":{"en":"text 1","ru":"текст 1"},"mandatory_for":[],"value":null},{"uid":"Kd6ln4rmOpbVcmxd","name":{"en":"text 2","ru":"текст 2"},"mandatory_for":[],"value":null}],"platform":null,"product":null,"version":null,"edition":null,"ticketsla":{"ticket":56,"policy":"kjmiYksE1_KY0G-2","schedule":"H51qT1YSgKkq5T48","first_response_time":{"target":"08:00:00.000000","diff":"07:59:59.920475","value":"00:00:00.079525","is_running":true,"out_of_schedule":false,"breach_idx":2.761284722208046e-06},"full_resolution_time":null,"next_response_time":null,"agent_update_time":null,"support_resolution_time":null,"customer_wait_time":null,"sla_breach_idx":2.761284722208046e-06},"comment":null,"license":null,"organization":null,"ticket_session":null,"forked_from":null,"tz_offset_minutes":0,"locked":false,"time_spent":null,"time_estimate":null,"article_not_needed":false,"article_links":0,"channels":[{"uid":"4tzzvd-_6OBOggZB","channel":"jEcHl-ZdUbBhSLnD","channel_type":"EMAIL","name":"main mail channel","identity":"AftZP8cnT2IZmnxM","ext_id":"angry_dm@bk.ru","muted":false}],"source":"jEcHl-ZdUbBhSLnD","last_reply_by":"7Cf0WL7sanTeMRIF","last_reply_at":"2026-08-20T08:10:00.536283Z","issue_count":0,"last_comment_by":"7Cf0WL7sanTeMRIF","last_comment_at":"2026-08-20T08:10:00.536283Z","cc":[],"issues":[],"is_external":false,"parent_ticket":null,"locale":"ru"}'

Из этого ответа надо взять id заявки в целевой системе(Swarmica) и сохранить для дальнейших взаимодействий.

Сценарий 2: Обновление существующего тикета через API

По аналогии с предыдущим сценарием необходимо настроить вебхуки, которые будут обновлять тикет в Swarmica в зависимости от событий в исходном тикете. Для примера мы возьмем следующие события:

Добавление комментария в заявке на стороне внешнего Helpdesk

Параметры API запроса в Swarmica:

Endpoint: /api/tickets/{ID}/comments

здесь вместо ID надо вставить ID заявки в Swarmica, полученный при создании заявки(Сценарий 1)

Method: POST

Payload:

{
  "body": "added comment",
  "public": true
}

пример ответа(response):

{"id":205,"ext_id":null,"ticket":56,"author":"7Cf0WL7sanTeMRIF","is_staff":true,"created_at":"2026-08-20T08:59:28.262866Z","public":true,"pinned":false,"body":"added comment","sensitive_data":null,"attachments":[],"mentioned_users":[],"mentioned_groups":[],"is_system":false,"is_autocomment":false,"timelog_date":null,"time_spent":null,"sync_statuses":[],"quoted_comment":null,"deleted":false,"is_ai_generated":false,"ai_agent_links":[]}

Обновление тикета(статус, приоритет)

Endpoint: /api/tickets/{ID}/

здесь вместо ID надо вставить ID заявки в Swarmica, полученный при создании заявки(Сценарий 1)

Method: PATCH

Payload:

{
  "priority": "high",
  "status": "PENDING"
}

пример ответа(response):

{"id":56,"subject":"test API ticket 11111","ext_id":1,"requester":"j9m7sRnuAHFcWD9Q","assignee":null,"group":null,"status":"PENDING","until":null,"priority":"high","replies":4,"reopens":0,"created_at":"2026-08-20T08:10:00.432419Z","resolved_at":null,"updated_at":"2026-08-20T10:13:11.495034Z","is_fcr":false,"satisfaction_score":"UNOFFERED","custom_fields":[{"uid":"1KZHEyoEPQhaD0Ii","name":{"en":"Can grant access to environment","ru":"Могу дать доступ, если надо"},"mandatory_for":[],"value":null},{"uid":"ouVl3K0SUvirO-LR","name":{"en":"link","ru":"ссылка"},"mandatory_for":[],"value":null},{"uid":"UJB6rUrOwq0Oarjt","name":{"en":"text 1","ru":"текст 1"},"mandatory_for":[],"value":null},{"uid":"Kd6ln4rmOpbVcmxd","name":{"en":"text 2","ru":"текст 2"},"mandatory_for":[],"value":null},{"uid":"VJ8qi-vdMKR0Z7qc","name":{"en":"external ID","ru":"Внешний ID"},"mandatory_for":["ticket"],"value":null}],"platform":null,"product":null,"version":null,"edition":null,"ticketsla":{"ticket":56,"policy":"kjmiYksE1_KY0G-2","schedule":"H51qT1YSgKkq5T48","first_response_time":{"target":"02:00:00.000000","diff":"07:59:59.888136","value":"00:00:00.111864","is_running":false,"out_of_schedule":false,"breach_idx":0.0},"full_resolution_time":{"target":"7 00:00:00.000000","diff":null,"value":null,"is_running":false,"out_of_schedule":false,"breach_idx":0.0},"next_response_time":null,"agent_update_time":null,"support_resolution_time":null,"customer_wait_time":null,"sla_breach_idx":0.0},"comment":null,"license":null,"organization":null,"ticket_session":null,"forked_from":null,"tz_offset_minutes":0,"locked":false,"time_spent":null,"time_estimate":null,"article_not_needed":false,"article_links":0,"channels":[{"uid":"4tzzvd-_6OBOggZB","channel":"jEcHl-ZdUbBhSLnD","channel_type":"EMAIL","name":"main mail channel","identity":"AftZP8cnT2IZmnxM","ext_id":"angry_dm@bk.ru","muted":false}],"source":"jEcHl-ZdUbBhSLnD","last_reply_by":"7Cf0WL7sanTeMRIF","last_reply_at":"2026-08-20T10:06:45.406992Z","issue_count":0,"last_comment_by":"7Cf0WL7sanTeMRIF","last_comment_at":"2026-08-20T10:06:45.406992Z","cc":[],"issues":[],"is_external":false,"parent_ticket":null,"locale":"ru"}

Сценарий 3: Исходящий API запрос из Swarmica во внешнем Helpdesk при появлении комментария или изменении в

Здесь мы зависим от ендпоинта на внесение изменений для конкретной заявки внешнего Helpdesk. Такой ендпоинт для изменения конкретной заявки может:

1 - (Чаще всего) содержать ID заявки в самом ендпоинте. Например, как в Swarmica - /api/tickets/{ID}

2 - (Очень редко) не содержать ID заявки в самом ендпоинте. И ID заявки передается в payload'е API запроса.

В случае 1, в Swarmica необходимо создать действие по событию(Скрипт). В скрипте должен формироваться нужный URL ендпоинта, используя ext_id. Далее посылается соответствующий API запрос с необходимыми headers и payload.

В случае 2, мы используем действие по событию(Вебхук). В настройках вебхука в payload формируем нужные данные с помощью jinja2

Обновлена: 24 авг. 2026 г.

Инструкция

С помощью скрипта

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

В зависимости от результата в заявке создается внутренний комментарий с соответствующим контентом.
Искомый текст и соответствующий контент передаются в доп. контексте скрипта.

1. Авторизуйтесь в Swarmica как администратор

2. Создайте скрипт с ролью Администратор в Настройки - Скрипты:

и на открывшейся странице добавьте скрипт trigger_autonote.py

3. Создайте Действие по событию в Настройки - Действия по событию и в качестве события выберите Скрипт:

4. На открывшейся странице выберите скрипт, добавленный в п.2 и добавьте условия:

Тип события = Статус заявки изменён
Новое значение = Решение предоставлено

5. В поле Добавить данные в контекст введите следующее:

{
  "text": "<ТЕКСТ>",
  "comment_if_text": "<СОДЕРЖИМОЕ_КОММЕНТАРИЯ_1>",
  "comment_ifnot_text": "<СОДЕРЖИМОЕ_КОММЕНТАРИЯ_2>"
}

<ТЕКСТ> - текст, искомый в существующих комментариях
<СОДЕРЖИМОЕ_КОММЕНТАРИЯ_1> - текст нового комментария, если нужный текст встречается во внутренних комментариях заявки
<СОДЕРЖИМОЕ_КОММЕНТАРИЯ_2> - текст нового комментария, если нужный текст НЕ встречается во внутренних комментариях заявки

6. Поменяйте Статус на Включен и нажмите Сохранить

Выглядеть должно так:

С помощью макроса

1. Авторизуйтесь в Swarmica как администратор

2. Создайте макрос с ролью Администратор в Настройки - Макросы

3. В режиме JSON введите Название и Данные такого вида:

{
  "public": false,
  "comment": "<p>{% if event.ticket.comments.filter(body__icontains='<ТЕКСТ>', public=False).exists() %} <СОДЕРЖИМОЕ_КОММЕНТАРИЯ_1> {% else %} <СОДЕРЖИМОЕ_КОММЕНТАРИЯ_2>{% endif %}</p>",
  "subject": "оповещение"
}

<ТЕКСТ> - текст, искомый в существующих комментариях
<СОДЕРЖИМОЕ_КОММЕНТАРИЯ_1> - текст нового комментария, если нужный текст встречается во внутренних комментариях заявки
<СОДЕРЖИМОЕ_КОММЕНТАРИЯ_2> - текст нового комментария, если нужный текст НЕ встречается во внутренних комментариях заявки

4. Создайте Действие по событию в Настройки - Действия по событию и в качестве события выберите Макрос:

5. На открывшейся странице выберите созданный макрос и добавьте условия:

Тип события = Статус заявки изменён
Новое значение = Решение предоставлено

6. Поменяйте Статус на Включен и нажмите Сохранить

Обновлена: 24 авг. 2026 г.

Инструкция

Скрипт реализует кастомную логику для тикетов в статусе Ожидает ответа клиента только для организаций с установленным Режимом работы (расписанием):

- Через заданное время (по умолчанию 1 час) после перевода тикета в статус Ожидает ответа клиента, если нет ответа от клиента и текущее время внутри бизнес-расписания компании, отправляется комментарий с предупреждением о скором закрытии.

- Ещё через заданное время (по умолчанию 1 час), если ответа нет и мы в бизнес-часах, тикет переводится в Решение предоставлено с комментарием.

- Если момент старта или напоминания приходится на нерабочее время, отсчёт начинается с начала следующих бизнес-часов.

- Поддерживается фильтрация по каналам через параметр source_channels в контексте.

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

1. Авторизуйтесь в Swarmica как Администратор

2. Создайте новый скрипт в Настройки - Скрипты

и добавьте в него скрипт recurring_autonotify_autosolve.py

3. Создайте новое Действие по расписанию в Настройки - Действие по расписанию - Скрипт

4. На открывшейся странице выберите созданный в п.2 скрипт, выставите расписание * * * * *(каждую минуту), включите его и нажмите Сохранить:

По умолчанию, скрипт работает с заявками из всех доступных исходных каналов, время после перевода в Ожидает ответа клиента - 1 час, время после напоминания - 1 час. Однако скрипт поддерживает изменение этих параметров. Для этого можно добавить данные в контекст в виде:

{
  "reminder_hours": <HOURS>,                      # кол-во часов до напомнимания
  "close_hours": <HOURS>,                         # кол-во часов до закрытия
  "source_channels":['SOURCE1',[SOURCE2],...]     # список исходных каналов
}

Возможные значения для "source_channels":

'email'
'telegram'
'whatsapp'
'mango_office'
'widget'
'billmanager'
'vk'
'beeline_pbx'
'max'
'web'
'api'

Пример данных для контекста:

{
  "reminder_hours": 3,
  "close_hours": 3,
  "source_channels": ['email','web','widget']
}
Обновлена: 27 июл. 2026 г.

В Swarmica есть возможность отправлять уведомления о разных события во внешние системы с помощью исходящих вебхуков.

Инструкции для настройки уведомлений:

Обновлена: 14 авг. 2026 г.

Инструкция

Для настройки оповещений в Slack необходимо создать вебхук для соответствующего канала такого вида: https://https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

1. Авторизуйтесь в Swarmica как Администратор.

2. Создайте вебхук в Настройки - Исходящие вебхуки, введите Название, URL вебхука, метод - POST и в поле Данные введите данные вида:

{
   "text": "<text>",                 # текст сообщения
   "channel": "<channel_name>",      # название канала
   "username": "<username>",         # от чьего имени отправлено сообщение(существование реального пользователя с таки именем необязательно)
   "icon_url": "<icon_url>"          # (опционально) URL иконки, которая будет отображаться перед именем пользователя
}

Более подробную информацию о формате данных можно найти в официальной документации Slack

Подробнее о формировании текста уведомления можно узнать здесь.

3. Создайте действие по событию в Настройки - Действия по событию - Создать - Исходящий вебхук

4. На открывшейся странице введите Название, в качестве Действия выберите созданный вебхук, выберите Тип события, установите необходимые условия, установите Статус - включен и нажмите Сохранить.

Обновлена: 14 авг. 2026 г.

Инструкция

Для настройки оповещений в Mattermost необходимо создать вебхук для соответствующего канала такого вида: https://your.mattermost.com/hooks/xxxxxxxxxxxxxxxxxxxx

1. Авторизуйтесь в Swarmica как Администратор.

2. Создайте вебхук в Настройки - Исходящие вебхуки, введите Название, URL вебхука, метод - POST и в поле Данные введите данные вида:

{
   "text": "<text>",                 # текст сообщения
   "channel": "<channel_name>",      # название канала
   "username": "<username>",         # от чьего имени отправлено сообщение(существование реального пользователя с таки именем необязательно)
   "icon_url": "<icon_url>",         # (опционально) URL иконки, которая будет отображаться перед именем пользователя
   "props": { "card": "<data>" }     # (опционально) добавляет информационную после имени пользователя, при нажатии которой открывается карточка с доп информацией
}

Более подробную информацию о формате данных можно найти в официальной документации Mattermost

Подробнее о формировании текста уведомления можно узнать здесь.

3. Создайте действие по событию в Настройки - Действия по событию - Создать - Исходящий вебхук

4. На открывшейся странице введите Название, в качестве Действия выберите созданный вебхук, выберите Тип события, установите необходимые условия, установите Статус - включен и нажмите Сохранить.

Обновлена: 14 авг. 2026 г.

В данной статье описана инструкция для миграции/синхронизации статей между двумя установками Swarmica.

Инструкция

Подготовка

1. Авторизуйтесь в исходную (откуда мигрируются статьи) Swarmica как Администратор

2. Создайте API токен в Настройки - API и интеграции

3. Авторизуйтесь в целевую (куда мигрируется) Swarmica как Администратор

4. Создайте скрипт в Настройки - Скрипты с ролью Администратор

5. Добавьте скрипт onetime_hc_migration.py и такую веб-форму:

[
  {
    "name": "host",
    "type": "string",
    "required": true,
    "displayName": "URL (хост)"
  },
  {
    "name": "token",
    "type": "string",
    "required": true,
    "displayName": "API токен"
  },
  {
    "name": "published",
    "type": "boolean",
    "required": false,
    "displayName": "Опубликованные"
  },
  {
    "name": "draft",
    "type": "boolean",
    "required": false,
    "displayName": "Черновик"
  },
  {
    "name": "archived",
    "type": "boolean",
    "required": false,
    "displayName": "Архив"
  },
  {
    "name": "approved",
    "type": "boolean",
    "required": false,
    "displayName": "Проверенные"
  },
  {
    "name": "unapproved",
    "type": "boolean",
    "required": false,
    "displayName": "Непроверенные"
  },
  {
    "name": "refresh_migrated",
    "type": "boolean",
    "required": false,
    "displayName": "Перезаписать существующие статьи"
  }
]

и нажмите Сохранить

Должно выглядеть вот так:

Запуск миграции/синхронизации

В поле URL(хост) введите URL исходной Swarmica(пример: https://source.swarmica.tld), в поле API токен введите токен из п.2, выберите статусы статей, которые будут перенесены (если не выбран ни один из статусов, будут перенесены только опубликованные статьи). Если требуется синхронизировать уже перенесенные статьи включите параметр Перезаписать существующие статьи и нажмите Отправить.

Обновлена: 20 июл. 2026 г.

В данной статье описана инструкция для импорта организаций и клиентов из CSV файла.

Требования к CSV файлу:

  • в файле должны быть 3 колонки: client, email, organization
  • данные должны быть разделены символом ";"

Пример содержимого CSV файла:

client;email;organization
"James Rodriguez";"james_rodriguez_1658@example.tld";"Umbrella Co"
"Thomas Martinez";"thomas_martinez_4320@test.tld";"Hooli"
"Jennifer Lopez";"jennifer_lopez_8285@example.tld";"Massive Dynamic"
...

Инструкция

1. Подключитесь к серверу Swarmica по SSH как root пользователь.

2. Создайте резервную копию Swarmica по этой инструкции.

3. Загрузите CSV файл со списком юзеров в папку uploads в контейнере django:

docker cp <PATH-TO-CSV-FILE> swarmica-django-1:/swarmica/swarmica/uploads

где <PATH-TO-CSV-FILE> - путь к CSV файлу.

4. Авторизуйтесь в веб-интерфейсе Swarmica как Администратор

5. Создайте скрипт для импорта в Swarmica - Настройки - Скрипты для роли Администратор:

6. Загрузите скрипт import_organizations_and_clients.py, добавьте следующие Параметры веб-формы и нажмите Сохранить:

[
  {
    "name": "filename",
    "type": "string",
    "required": true,
    "displayName": "имя CSV-файла"
  }
]

Должно выглядеть вот так:

7. В поле веб-формы введите имя CSV файла, загруженного в п.2, и нажмите Отправить:

Траблшутинг

Отследить процесс можно в логе контейнера celeryworker:

docker logs swarmica-celeryworker-1 -f

Или после отработки скрипта:

docker logs swarmica-celeryworker-1 2>&1 | grep "User import"
Обновлена: 5 июл. 2026 г.

В данной статье представлена инструкция для импорта пользователей с ролью Сотрудник из .csv файла.

Скрипт требователен к формату CSV файла: обязательно должны быть колонки 'Сотрудник' (имя сотрудника) и 'E-Mail' (email адрес), разделенные символом ";"

Пример содержимого:

Сотрудник;E-Mail
John Doe;john.doe@test.tld
Иван Иванов;ivan.ivanov@test.tld
Thomas Smith;thomas.smith@test.tld
...

Инструкция

1. Подключитесь к серверу Swarmica по SSH как root пользователь.

2. Создайте резервную копию Swarmica по этой инструкции.

3. Загрузите CSV файл со списком юзеров в папку uploads в контейнере django:

docker cp <PATH-TO-CSV-FILE> swarmica-django-1:/swarmica/swarmica/uploads

где <PATH-TO-CSV-FILE> - путь к CSV файлу.

4. Авторизуйтесь в веб-интерфейсе Swarmica как Администратор

5. Создайте скрипт для импорта в Swarmica - Настройки - Скрипты для роли Администратор:

6. Загрузите скрипт import_users.py, добавьте следующие Параметры веб-формы и нажмите Сохранить:

[
  {
    "name": "filename",
    "type": "string",
    "required": true,
    "displayName": "имя CSV файла"
  }
]

Должно выглядеть вот так:

7. В веб-форме введите имя CSV файла, загруженного в п.2, и нажмите Отправить:

Траблшутинг

Отследить процесс можно в логе контейнера celeryworker:

docker logs swarmica-celeryworker-1 -f

Или после отработки скрипта

docker logs swarmica-celeryworker-1 2>&1 | grep "User import"
Обновлена: 30 июн. 2026 г.

Вопрос

Можно ли подсвечивать заявки цветом в списке, в зависимости от приоритета?

Ответ

Расцветку можно добавить через CSS стили в Настройках - Управление брендами.

Например, можно вот так по приоритетам подсветить:

Чтобы это сделать, в Стили для темы в бренде необходимо добавить:

tr:has(td span.ticket-priority-urgent) > * {
    background-color: rgba(255, 0, 0, 0.2) !important;
}

tr:has(td span.ticket-priority-high) > * {
    background-color: rgba(0, 255, 255, 0.2) !important;
}

tr:has(td span.ticket-priority-normal) > * {
    background-color: rgba(0, 255, 0, 0.2) !important;
}

Чтобы подсветка тикетов работала, в фильтре обязательно нужно вывести колонку Приоритет.

Обновлена: 18 июн. 2026 г.

Импорт статей в Swarmica. В данной статье описано как импортировать статьи в виде .md файлов в Swarmica.

Инструкция

Рекомендация: Назвать .md файл как тема статьи. Например, тема статьи - "Как создать заявку", тогда рекомендуемое имя файла "Как создать заявку.md"

1. Подключитесь к серверу c Swarmica по SSH как root

2. Создайте папку /root/swarmica/old_articles:

mkdir /root/swarmica/old_articles

3. Загрузите статьи(.md файлы) в созданную папку /root/swarmica/old_articles

4. Создайте резервную копию файла /root/swarmica/docker-compose.yml:

cp /root/swarmica/docker-compose.yml{,.backup}

5. Примонтируйте папку со статьями в контейнер django. Для этого добавьте в файл /root/swarmica/docker-compose.yml в секции контейнера django следующую строку:

<...>
  django: &django
    image: reg.gl.swd.im/swarmica/backend:${SW_BACKEND_VERSION}
    depends_on:
      - postgres
      - redis
    volumes:
      - swarmica_ai_assistant:/swarmica/swarmica/ai_assistant/articles/:z
      - swarmica_runtime:/swarmica/swarmica/runtime_scripts/:z
      - swarmica_static:/swarmica/swarmica/static:z
      - swarmica_ugc:/swarmica/swarmica/attachments:z
      - swarmica_uploads:/swarmica/swarmica/uploads/:z
      - /root/swarmica/old_articles/:/swarmica/swarmica/old_articles/:z   # <------ Эту строку
<...>

И перезапустите Swarmica:

docker compose down; docker compose up -d

6. Авторизуйтесь в Swarmica UI как Администратор.

7. Создайте новый скрипт в Swarmica - Настройки - Скрипты с ролью Администратор

8. В настройках скрипта добавьте этот скрипт и следующее в Параметры веб-формы и нажмите Сохранить:

[
  {
    "name": "author_uid",
    "type": "string",
    "required": false,
    "displayName": "UID автора"
  },
  {
    "name": "category_name",
    "type": "string",
    "required": true,
    "displayName": "Имя раздела статьи"
  }
]

Должно выглядеть так:

9. В веб-форме скрипта укажите UID пользователя, который будет назначен автором статей и Имя раздела статей и нажмите Отправить:

10. На сервере Swarmica в файле /root/swarmica/docker-compose.yml удалите строку, добавленную в шаге 5 и перезапустите Swarmica:

docker compose down; docker compose up -d
Обновлена: 14 июн. 2026 г.

Симптомы

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

Решение

  1. Перейти в Настройки - Действия по событию, нажать Создать , Макрос
  2. Выбрать Тип события = Событие заявки
  3. Добавить значение Тип события = Заявка создана
  4. Добавить Заявка: Создана и выбрать [..]
  5. Создать Макрос справа и написать нужный комментарий.
  6. Не забыть дать названия действию и макросу в соответствующих полях
  7. Включить и сохранить

Обновлена: 1 июн. 2026 г.

Симптомы

Создаются пустые заявки из чатов.

Решение

  1. Создайте новое действие по событию с типом Скрипт в Настройках - Действия по событию.
  2. Укажите следующие условия:
    • Тип события: Заявка создана
    • Заявка: Статус = Новая
    • Количество ответов = 0
    • Исходный канал: Тип канала = Виджет
    • Заявка: Создана: укажите время, через которое заявка будет закрываться, если клиент ничего не написал
  3. В дополнительный контекст добавьте переменную comment_body с текстом ответного сообщения:
    {
      "comment_body": "Здравствуйте! <br/>Вы не написали сообщение, поэтому заявка будет закрыта."
    }
    

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

  4. Прикрепите скрипт из вложения в качестве действия: close_empty_chat.py
  5. Включите триггер.

Причина

Тикет создается по клику Начать чат, даже если клиент ничего не пишет.

Обновлена: 31 июл. 2026 г.

Вопрос

Как использовать переменные(контекст) для создания скриптов для действия по событию

Ответ

В Swarmica для Действия по событию в качестве действия можно использовать Python скрипты.

Подробнее о написании скриптов можно узнать в этой статье.

В зависимости от сценария в скрипт передаются данные о конкретном событии и дополнительный контекст(если требуется).

Для действий по событию используется 5 видов событий:

ArticleEvent - События Статьи
CustomFieldEvent - События Кастомного поля
KCSEvent - События KCS
TicketEvent - События Заявки
UserEvent - События Пользователя

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

Когда срабатывает триггер, передаются данные в таком виде:

{'data': {'event_id': <ID>, 'event': <TicketEvent: TicketEvent object (<ID>)>[, <ДОП_КОНТЕКСТ>]}

Обработка данных События

Для использования данных о Cобытии необходимо обрабатывать Объект event, передаваемый в данных. Можно вывести этот Объект в отдельную переменную. Например:

event = data.get('event', None)

или

event = <EVENT_NAME>.objects.filter(id=data['event_id']).first()

где <EVENT_NAME> - соответствующее событие.

Например, сценарий должен срабатывать по Событию Заявки(TicketEvent). В таком случае код будет следующим:

event = TicketEvent.objects.filter(id=data['event_id']).first()

Далее полученную переменную event можно использовать для обработки параметров передаваемых соответствующим Событием. Структура переменной для параметров выглядит так:

event.Параметр[.Параметр[.<...>]]

Если Параметр является Объектом, содержащим собственные Параметры, то конечная структура переменной усложняется.

Например, используется сценарий по Событию TicketEvent. Событие TicketEvent - само по себе является сущностью(объектом), включающим следующие параметры:

ПараметрЧто делаетЗначения
responsibleпередает Исполнителя СобытияОбъект user
dateпередает дату События
old_valueпередает старые значения События
new_valueпередает новые значения События
ticketпередает Заявку, в которой произошло СобытиеОбъект ticket
ticket_commentПередает комментарии Заявки, в которой произошло СобытиеОбъект ticketcomment

И нам нужно произвести действие с самой Заявкой. В параметрах, как видно, передается Объект ticket. Соответственно надо обрабатывать этот самый объект и переменная будет выглядеть так:

event.ticket

Для удобства можно определить объект в отдельную переменную:

ticket = event.ticket

Например, нам нужно вывести информацию о Заявке(id) и дате её создания(created_at) в лог, тогда код может выглядеть так:

ticket = event.ticket
logger.info(f"Заявка #{ticket.id} создана {ticket.created_at}")

или так:

logger.info(f"Заявка #{event.ticket.id} создана {event.ticket.created_at}")

Обработка дополнительного контекста

Подробнее о контексте можно узнать в этой статье

Также для действия по событию можно добавить дополнительный контекст в Настройки - Действия по Событию - Действие в поле Добавить данные в контекст. Данные добавляются в формате json.

При срабатывании События доп контекст передается вместе с данными о событии. Например в доп. контекст добавлено следующее:

{
  "id": "1234"
}

Тогда данные передаваемые в скрипт будут выглядеть так:

{'data': {'event_id': <ID>, 'event': <TicketEvent: TicketEvent object (<ID>)>, 'id':'1234'}

Для работы с данными доп контекста в самом скрипте можно вывести их в отдельную переменную:

id = data.get('id', None)

Пример

Допустим есть сценарий: при повышении приоритета Заявки до "Критичный" необходимо поместить Заявку в отдельную группу.

В условиях для события устанавливаем:

Тип события=Приоритет заявки изменён
Заявка: Приоритет= Срочный

В данном сценарии используется TicketEvent(События Заявки). Для передачи в скрипт Группы, на которую нужно назначить Заявку мы будет использовать дополнительный контекст.

В дополнительный контекст добавляем UID новой группы:

{
  "new_group_uid": "ABCMWvoee35feOeA"
}

Скрипт будет выглядеть так:

# Подгружаем необходимые модули для запуска скрипта и для работы с задействованными объектами
from runtime.runners import BaseRunner             
from core.models import TicketEvent, Group, Ticket  

# модуль для логирования
import logging                                     
logger = logging.getLogger(__name__)

class Runner(BaseRunner):
    def run(self, *args, **kwargs):
        logger.info(kwargs)
        # Помещаем передаваемые в Событии данные в переменную data
        data = kwargs.get('data', {})

        # Помещаем объект TicketEvent в переменную event c помощью data['event_id'] 
        event = TicketEvent.objects.filter(id=data['event_id']).first()

        # Если Событие не передалось пишем об этом в лог
        if not event:
            logger.error(f"No event with {data['event_id']} found, exiting")
            return

        # Помещаем объект ticket из event в переменную ticket
        ticket=event.ticket

        # Далее удостоверяемся, что заявка передана в Событии
        if ticket:                                       
            ticket_id = event.ticket.id                  # помещаем id Заявки из События в переменную ticket_id
            group_uid = data.get('new_group_uid',None)   # помещаем UID группы из дополнительного контекста в переменную group_uid
            new_group = Group.objects.get(uid=group_uid) # помещаем Объект нужной группы в переменную, используя переменную group_uid
            logger.info(f"Заявка #{ticket_id} должна быть назначена на группу с UID {group_uid}")

            # Далее проверяем, что Заявка находится в другой группе и назначаем на нужную группу
            if ticket.group.uid != group_uid:
                ticket.group = new_group
                ticket.save()
                logger.info(f"ticket group changed")                
            else: # если заявка изначально была уже назначена на нужну группу пишем об этом в лог и ничего не делаем
                logger.info(f"ticket is in proper group already")               
                
        else: # если заявки нет в Событии, то пишем об этом в лог
            logger.warning(f"Ticket is not found in event {data['event_id']},exiting")
            return
Обновлена: 24 июл. 2026 г.

В Swarmica есть следующие события, используемые в качестве триггеров:

ArticleEvent - События Статьи
CustomFieldEvent - События Кастомного поля
KCSEvent - События KCS
TicketEvent - События Заявки
UserEvent - События Пользователя

Для каждого из событий передаются определенные параметры, которые можно использовать в скриптах. Ниже описаны эти параметры:

ArticleEvent

ПараметрЧто делаетЗначения
eventпередает какое Событие произошло со Статьёй"0" - "Unknown"
"1" - "Article created"
"2" - "Article user segment added"
"3" - "Article published"
"4" - "Article unpublished"
"5" - "Article deleted"
"6" - "Article undeleted"
"7" - "Article author changed"
"8" - "Article flagged"
"9" - "Article unflagged"
"10" - "Agent commented on article"
"11" - "Customer commented on article"
"12" - "Agent comment changed"
"13" - "Agent comment deleted"
"14" - "Customer comment deleted"
"15" - "Article revision added"
"16" - "Article status changed"
"17" - "Article user segment deleted"
responsibleпередает Исполнителя СобытияОбъект user
dateпередает дату События
old_valueпередает старые значения параметров События
new_valueпередает новые значения параметров События
articleпередает Статью, с которой произошло СобытиеОбъект article

CustomFieldEvent

ПараметрЧто делаетЗначения
responsibleпередает Исполнителя СобытияОбъект user
dateпередает дату События, связанного с Кастомным полем
old_valueпередает старые значения параметров События
new_valueпередает новые значения параметров События
fieldпередает Кастомное поле, с которым произошло СобытиеОбъект customfield
content_objectпередает Объект, для которого произошло СобытиеОбъект ticket|article|user

KCSEvent

ПараметрЧто делаетЗначения
typeпередает тип События"1" - "Capture"
"2" - "Link"
"3" - "Flag"
"4" - "Publish"
"5" - "Unflag"
"6" - "Unpublish"
"7" - "Unlink"
responsibleпередает Исполнителя СобытияОбъект user
dateпередает дату и время События
ticketпередает Заявку, связанную с СобытиемОбъект ticket
articleпередает Статью, связанную с СобытиемОбъект article

TicketEvent

ПараметрЧто делаетЗначения
eventпередает Событие, связанное с Заявкой"0" - "Неизвестно"
"1" - "Статья создана из заявки"
"2" - "Статья добавлена к заявке"
"20" - "Убрана связь со статьёй"
"3" - "Статья помечена к исправлению"
"4" - "Статус заявки изменён"
"5" - "Агент прокомментировал заявку"
"6" - "Клиент прокомментировал заявку"
"7" - "Заявка оценена"
"8" - "Приоритет заявки изменён"
"9" - "Заявка создана"
"10" - "Ответственный изменён"
"11" - "Заявитель изменён"
"12" - "Группа заявки изменена"
"13" - "Платформа заявки изменена"
"14" - "Продукт заявки изменён"
"15" - "Версия заявки изменена"
"16" - "Редакция заявки изменена"
"17" - "Задача добавлена к заявке"
"18" - "Задача удалена из заявки"
"19" - "Пользовательское поле изменено"
"21" - "Навык добавлен"
"22" - "Навык удалён"
"23" - "Связанная заявка добавлена"
"24" - "Связанная заявка удалена"
"25" - "Заявка объединена"
"28" - "Агент добавил внутренний комментарий"
"26" - "Чат-сессия по заявке начата"
"27" - "Чат-сессия по заявке завершена"
"29" - "Отправлено уведомление об ожидании"
"30" - "Политика SLA заявки изменена"
"31" - "Лицензия заявки изменена"
"33" - "Заявка разветвлена"
"34" - "Задача закрыта"
"35" - "Задача открыта"
"36" - "Применено правило автоназначения"
"37" - "Внутренний комментарий изменён"
"38" - "Признак «Статья не нужна» изменён"
"39" - "Система Swarmica добавила автоматический ответ"
"40" - "Оценка времени изменена"
"41" - "Задача удалена"
"42" - "Актив добавлен"
"43" - "Актив удалён"
"44" - "Актив обновлён"
"45" - "Тема изменена"
"46" - "Публичный комментарий изменён"
"47" - "Комментарий удалён"
"48" - "Пользователь добавлен в копию"
"49" - "Пользователь удалён из копии"
"50" - "Наблюдатель добавлен"
"51" - "Наблюдатель удалён"
"52" - "Внешняя заявка добавлена"
"53" - "Публичный комментарий внешней заявки добавлен"
"54" - "Заявка заблокирована"
"55" - "Заявка разблокирована"
responsibleпередает Исполнителя СобытияОбъект user
dateпередает дату События
old_valueпередает старые значения параметров События
new_valueпередает новые значения События
ticketпередает Заявку, в которой произошло СобытиеОбъект ticket
ticket_commentПередает комментарии Заявки, в которой произошло СобытиеОбъект ticketcomment

UserEvent

ПараметрЧто делаетЗначения
eventПередает События, связанные с Пользователем"0" - "Role changed"
"1" - "Password changed"
"2" - "Identity added"
"3" - "Organization changed"
"4" - "Schedule changed"
"5" - "Name changed"
"6" - "Status changed"
"7" - "Merged into"
"8" - "Merged from"
"9" - "User created"
"10" - "User logged into system"
"11" - "Notification enabled"
"12" - "Notification disabled"
"13" - "Identity deleted"
"14" - "2FA method added"
"15" - "2FA method removed"
"16" - "2FA enabled"
"17" - "2FA disabled"
"18" - "2FA bypassed (transport unavailable)"
"19" - "2FA backup code used"
responsibleпередает Исполнителя СобытияОбъект user
dateпередает дату События
old_valueпередает старые Значения События
new_valueпередает старые Значения События
userпередает Пользователя, с которым произошло СобытиеОбъект user

Когда происходит Событие, передается данные об этом Событии. Эта информация содержит информацию о Событии и Объекты, связанные с этим самым Событием. Ниже представлены списки параметров Объектов.

article

Статьи базы знаний

ПараметрЧто делаетЗначения
idпередаёт ID Статьи
statusпередаёт статус СтатьиDRAFT - черновик
UNAPPROVED - Непроверенная
APPROVED - Проверенная
PUBLISHED - Опубликованная
ARCHIVED - Архивная
published_atпередает дату публикации Статьи
visibilityпередает области доступа к СтатьеALL - для всех
AUTHORIZED - для авторизованных пользователей
SEGMENTS - для отдельных сегментов пользователей
segmentsпередает Сегменты пользователейОбъект usersegment
internalпередает является ли Статья внутренней(boolean)TRUE|FALSE
categoryпередает Категорию СтатьиОбъект articlecategory
publisherпередает Редактора СтатьиОбъект user
authorпередает Автора СтатьиОбъект user
is_flaggedпередает помечена ли Статья к исправлению(boolean)TRUE|FALSE
updated_atпередает дату последнего редактирования Статьи
created_atпередает дату создания Статьи
t_linksпередает количество связанных со Статьёй Заявок

articlecategory

Разделы статей базы знаний

ПараметрЧто делаетЗначения
uidпередает UID Раздела статей
publicпередает является ли Раздел публичным(boolean)TRUE|FALSE
orderпередает значение порядкового номера Раздела
created_atпередает дату создания Раздела
updated_atпередает дату последнего редактирования Раздела

articlecomment

Комментарии к Статье

ПараметрЧто делаетЗначения
idпередает id Комментария к статье
authorпередает Автора КомментарияОбъект user
publicпередает является ли Комментарий публичным(boolean)TRUE|FALSE
is_staffпередает является ли Автор комментария Сотрудником(boolean)TRUE|FALSE
created_atпередает дату создания Комментария
updated_atпередает дату последнего редактирования Комментария

articlerevision

Версия статьи базы знаний

ПараметрЧто делаетЗначения
uidпередает UID Версии статьи
authorпередает Автора Версии статьиОбъект user
latestпередает является ли Версия статьи самой свежей(boolean)TRUE|FALSE
restored_fromпередает из какой Версии Статья была восстановленаОбъект articlerevision

channel

Каналы связи

ПараметрЧто делаетЗначения
uidПередает UID Канала связи
channel_typeПередает тип Канала связи"EMAIL"
"TELEGRAM"
"WHATSAPP"
"MANGO_OFFICE"
"WIDGET"
"BILLMANAGER"
"VK"
"BEELINE_PBX"
"MAX"

customfield

Кастомные поля

ПараметрЧто делаетЗначения
uidпередает UID Кастомного поля
field_typeпередает тип Кастомного поля"TEXT" - текст
"TEXTAREA" - текстовое поле
"NUMBER" - целое число
"DECIMAL" - число с плавающей точкой
"CHECKBOX" - чекбокс
"DROPDOWN" - меню
"DATE" - дата
"DATETIME" - дата и время
"REGEX" - регулярное выражение
"OBJECT" - связанная сущность
"BADGE" - бейдж
"LINK" - ссылка

edition

Редакции Продукта

ПараметрЧто делаетЗначения
uidпередает UID Версии

group

Группа пользователей

ПараметрЧто делаетЗначения
uidпередает UID Группы пользователей

issue

Внешние задачи из сторонних систем(Gitlab, Jira и т.п.)

ПараметрЧто делаетЗначения
uidпередает UID Внешней задачи

license

Клиентские ключи

ПараметрЧто делаетЗначения
uidпередает UID Клиентского ключа

organization

Компании(клиенты)

ПараметрЧто делаетЗначения
uidпередает UID Компании

platform

Платформы Продукта

ПараметрЧто делаетЗначения
uidпередает UID Платформы

product

Продукты

ПараметрЧто делаетЗначения
event.product.uidпередает UID Продукта

schedule

Расписания

ПараметрЧто делаетЗначения
event.schedule.uidпередает UID Расписания
event.schedule.nameпередает название Расписания
event.schedule.defaultпередает является ли данное Расписание дефолтным(по умолчанию)(boolean)TRUE|FALSE

skill

Навыки сотрудников

ПараметрЧто делаетЗначения
uidпередает UID навыка

slapolicy

Политики SLA

ПараметрЧто делаетЗначения
uidпередает UID Политики SLA

ticket

Заявки

ПараметрЧто делаетЗначения
idпередает ID Заявки
statusпередает статус Заявки"NEW"
"OPEN"
"PENDING"
"HOLD"
"SOLVED"
"CLOSED"
"DELETED"
"MERGED"
groupпередает Группу, на которую назначена ЗаявкаОбъект group
priorityпередает приоритет Заявки"low"
"normal"
"high"
"urgent"
assigneeпередает Ответственного за ЗаявкуОбъект user
requesterпередает Заявителя ЗаявкиОбъект user
ccпередает список добавленных в CCОбъект user
watchersпередает список Наблюдателей ЗаявкиОбъект user
organizationпередает Компанию ЗаявителяОбъект organization
ticketslaпередает Политику SLA ЗаявкиОбъект ticketsla
licenseпередает пользовательский Ключ ЗаявителяОбъект license
lockedпередает заблокирована ли Заявка(boolean)TRUE|FALSE
tz_offset_minutesпередает часовой пояс Заявки
localeпередает язык(локаль) Заявки
created_atпередает дату создания Заявки
updated_atпередает дату последнего обновления Заявки
resolved_atпередает дату решения Заявки
untilпередает дату, до которой Заявка будет в статусе Ожидание
repliesпередает количество ответов в Заявке
reopensпередает количество переоткрытий Заявки
productпередает Продукт, по которому заведена ЗаявкиОбъект product
versionпередает версию ПродуктаОбъект version
editionпередает редакцию ПродуктаОбъект edition
platformпередает платформу ПродуктаОбъект platform
skillsпередает Навыки, связанные с ЗаявкойОбъект skill
is_fcrпередает решена ли Заявка первым ответом Сотрудника(boolean)TRUE|FALSE
satisfaction_scoreпередает оценку удовлетворенности Заявителя"UNOFFERED"
"OFFERED"
"GOOD"
"BAD"
"NEUTRAL"
time_estimateпередает Оценку трудозатрат Заявки
time_spentпередает фактические Трудозатраты на Заявку
article_not_neededпередает значение параметра "Статья не нужна"(boolean)TRUE|FALSE
article_linksпередает количество связанных с Заявкой Статей
channelsпередает Каналы связи ЗаявкиОбъект ticketchannel
subjectпередает тему Заявки
sourceпередает по какому Каналу связи была получена ЗаявкаОбъект channel
last_replyпередает последний ответ Агента в ЗаявкеОбъект ticketcomment
last_commentпередает последний Комментарий в ЗаявкеОбъект ticketcomment
issue_countпередает количество связанных Внешних задач
linked_issuesпередает связанные Внешние задачи
is_externalпередает является ли Заявка Внешней(boolean)TRUE|FALSE
parent_ticketпередает родительскую заявку

ticketchannel

Каналы связи Заявки

ПараметрЧто делаетЗначения
channelПередает Каналы связи ЗаявкиОбъект channel

ticketcomment

Комментарии Заявки

ПараметрЧто делаетЗначения
idпередает ID комментария
authorпередает Автора комментарияОбъект user
created_atпередает дату создания Комментария
bodyпередает содержимое комментария

ticketissue

Внешние задачи, связанные с Заявкой

ПараметрЧто делаетЗначения
issueпередает Внешнюю задачу, связанную с Заявкой
authorпередает Сотрудника, связавшего/создавшего Внешнюю задачу
ticketпередает саму Заявку

ticketsla

Политики SLA Заявки

ПараметрЧто делаетЗначения
sla_breach_idxпередает индекс превышения SLA
first_response_time_breach_idxпередает индекс превышения времени первого ответа в Заявке
full_resolution_time_breach_idxпередает индекс превышения полного времени решения Заявки
next_response_time_breach_idxпередает индекс превышения времени между ответами
agent_update_time_breach_idxпередает индекс превышения времени ответа Сотрудника
support_resolution_time_breach_idxпередает индекс превышения времени решения в поддержке
customer_wait_time_breach_idxпередает индекс превышения времени решения без ожидания

user

Пользователи

ПараметрЧто делаетЗначения
uidпередает UID пользователя
emailпередает email Пользователя
nameпередает имя Пользователя
roleпередает Роль Пользователя"ADMIN"
"MANAGER"
"AGENT"
"INTERNAL_USER"
"CUSTOMER_ADMIN"
"CUSTOMER"
"BLOCKED"
is_robotпередает является ли Пользователь Роботом(boolean)TRUE|FALSE
is_systemпередает является ли Пользователь системным пользователем(boolean)TRUE|FALSE
is_employeeпередает является ли Пользователь Сотрудником(boolean)TRUE|FALSE
kcs_roleпередает KCS роль Пользователя"NOT SET"
"CANDIDATE"
"CONTRIBUTOR"
"PUBLISHER"
started_atПередает дату начала работы Пользователя
dismissed_atПередает дату увольнения Пользователя
created_atпередает дату создания Пользователя
updated_atпередает дату редактирования Пользователя
aqi_evaluatorпередает является ли Пользователь проверяющим Качество КонтентаTRUE|FALSE
lai_evaluatorпередает является ли Пользователь проверяющим Точности СвязанностиTRUE|FALSE
qa_evaluatorпередает является ли Пользователь проверяющим Качество СервисаTRUE|FALSE
statusпередает Статус Пользователя"OFFLINE"
"ONLINE"
"IN_SESSION"
"WRAPUP"
"AWAY"
"BUSY"
email_formatпередает формат email для Пользователя"HTML"
"TEXT"
timezoneпередает таймзону Пользователя
sourceпередает источник создания Пользователя"system"
"email"
"invite"
"api"
"token"
"script"
"okdesk"
"crm"
"telegram"
"whatsapp"
"vk"
"phone"
"max"
scheduleпередает Расписание ПользователяОбъект schedule
skillsпередает Навыки ПользователяОбъект skill
organizationпередает Компанию ПользователяОбъект organization
group_membershipsпередает список Групп, в которых состоит ПользовательОбъект group

useridentity

Учетные записи Пользователя

ПараметрЧто делаетЗначения
uidпередает UID Пользователя
userпередает Пользователя, связанного с Учетной ЗаписьюОбъект user
ext_idпередает внешний ID Учетной записи
sourceпередает источник Учетной записи"EMAIL"
"TELEGRAM"
"WHATSAPP"
"VK"
"PHONE"
"ANONYMOUS",
"MAX"

usersegment

сегменты Пользователей

ПараметрЧто делаетЗначения
uidпередает UID Сегмента Пользователей
nameпередает название Сегмента Пользователей
created_atпередает дату создания Сегмента Пользователей
updated_atпередает дату последнего редактирования Сегмента Пользователей

version

версии Продукта

ПараметрЧто делаетЗначения
event.version.uidпередает UID версии продукта
Обновлена: 9 июл. 2026 г.

Симптомы

Есть потребность уведомлять агентов и менеджеров, если тикет остается без ответа определенное количество часов и SLA нарушаются

Решение

Задачу можно решить через написания скрипта-плагина , который можно настроить запускаться по определенному расписанию, и который будет проверять тикеты, находящиеся без ответа (например 48 часов с момента последнего ответа) в определенной группе, и отправлять письмо членам этой группы.

Пример скрипта.

Для использования функции скриптов-плагинов требуется лицензия тарифа уровня Премиум

Обновлена: 18 мая 2026 г.

Симптомы

Хочется отслеживать время наступления какого либо кастомного события. Например перевод в другую группу или выставление, какого-либо кастомного филда.

Решение

Рассмотрим на примере события смена группы. Для решения проблемы можно использовать макрос, который будет проставлять время в кастомное поле при смене группы.

  1. Создать в настройках новое кастомное поле типа «Дата и время».
  2. Скопировать UID нового поля из URL.
  3. В настройках зайти в «Макросы» и создать новый, где:
  • ID объекта: {{ event.ticket.id }};
  • Данные:
{
  "custom_fields": [
    {
      "uid": "UID_кастомного_поля",
      "value": "{{ event.date }}"
    }
  ]
}
  1. В настройках — «Действия по событию» создать новое, где в качестве действия выбрать макрос из шага 2 и включить триггер.
Обновлена: 18 мая 2026 г.

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

Контекст – это данные и переменные, которые доступны автоматическому действию (макросу, исходяшему письму, исходящему вебхуку или скрипту) в момент выполнения.

Структура контекста

Контекст - это хранилище ключ-значение, в котором могут храниться любые сериализуемые в JSON значения.

Триггер по событию, по умолчанию, передает в ключе event объект события, которое и запустило данный триггер.

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

При необходимости, вы можете добавить переменные в контекст, чтобы использовать их по умолчанию так же в формате ключ-значение в формате JSON:

{
  "my_custom_variable": {
    "foo": "bar"
  }
}

И затем обращаться к этим значениям в шаблонах автоматизаций, например, в вебхуке или емейле:

<p>Hello, {{ my_custom_variable.foo }}</p>
Обновлена: 18 мая 2026 г.

Симптомы

Как посчитать Handover Rate — коэффициент передач, индекс «футбола» заявки?

Решение

Вариант 1

В лоб можно смотреть сколько в среднем было Ответственных в тикете, что будет грубым индикатором того сколько раз передавался тикет. Ограничение, что когда Агент А <> Агент Б между собой передают. Но это достаточно выколотый кейс, поэтому на больших данных среднего количества Ответственных должно вполне хватать.

Вариант 2

1 - Создать в Настройках >Кастомные поля новое кастомное поля типа Целое число:

И скопировать его UID из URLа.

2 - В Настройках зайти в Макросы и создать новый, где
ID Объекта: {{ event.ticket.id }}
Данные:

{
  "custom_fields": [
    {
      "uid": "EY1pPecadgSmZnuC",
      "value": "{% set count = event.ticket.custom_fields.get_value('СЮДА ПИСАТЬ ID КАСТОМ ВИЛДА') %}{% if count is not none %}{{ count + 1 }}{% else %}0{% endif %}"
    }
  ]
}

3 - В Настройках - Действия по событию создать новое, где в качестве события выбрать Assignee Changed действия выбрать макрос из шага 2

Дальше уже по этому кастомному полю можно делать фильтры и сводные отчеты.

При большом количестве данных работу макроса возможно придется донастраивать, поэтому для более стабильного и универсального применения рекомендуется вариант 3 со скриптом. См. ниже

Вариант 3

Вместо макроса использовать скрипт.

1 - Создать в Настройках >Кастомные поля новое кастомное поля типа Целое число:

И скопировать его UID из URLа.

2 - Создать новый скрипт в Настройки> Скрипты и загрузите туда пример скрипта

3 - В Настройках - Действия по событию создать новое, где в качестве события выбрать Assignee Changed действия выбрать скрипт из шага 2

4 - В поле "Добавить данные в контекст" прописать следующее:

{
   "cf_uid": "УИД КАСТОМФИЛДА ЧИСЛО КУДА ПИСАТЬ ЗНАЧЕНИЕ"
}

Сохранить и запустить действие.

Дальше уже по этому кастомному полю можно делать фильтры и сводные отчеты.

Обновлена: 18 мая 2026 г.

Действия по расписанию и периодическое перераспределение заявок используют crontab синтаксис для формирования расписания периодических задач. В данной статье дается краткая справка о формате crontab.

Формат записи

* * * * * 
- - - - -
| | | | |
| | | | ----- день недели (0—7) (воскресенье = 0 или 7)
| | | ------- месяц (1—12)
| | --------- день месяца (1—31)
| ----------- час (0—23)
------------- минута (0—59)

Проверить синтаксис или подобрать подходящий можно так же с помощью специализированных сервисов, например crontab.guru.

Примеры

Запускать действие раз в три минуты:

*/3 * * * *

Запускать действие каждый час в XX:13:

13 * * * *

Запускать каждое воскресенье в 7:00:

0 7 * * 0

Запускать в 6:30, 12:30 и 18:30 каждый день:

30 6,12,18 * * *
Обновлена: 18 мая 2026 г.

Симптомы

Для веб-чата требуется настроить автоматические сообщения:

  1. При старте чата
  2. Если чат запущен в нерабочее время

Решение

Возможна настройка через скрипты и макросы.

  1. Возьмите пример скрипта и отредактируйте в нем тексты сообщений
  2. Убедитесь, что у вас есть созданное расписание, назначенное на компанию/группу или политику SLA
  3. Перейдите в Настройки > Скрипты и нажмите кнопку Создать. Выберите роль Администратор и введите название скрипта.
  4. В открывшемся окне в поле скрипт загрузите отредактированный скрипт из пункта 1. Нажмите Сохранить.
  5. Перейдите в Настройки > Действие по событию и нажмите Создать
  6. Заполните название, Тип события = TicketEvent, , Тип действия = Скрипт и в Действие выберите созданный скрипт. Нажмите Сохранить
  7. В открывшемся окне в поле Выполнять, если событие удовлетворяет условиям вставить
{
  "event": 9,
  "ticket__status__in": [
    "NEW",
    "OPEN"
  ],
  "ticket__source__channel_type": "WIDGET"
}

Сохранить событие и в списке действий нажмите Запустить выбранное действие

Обновлена: 18 мая 2026 г.

ВЫ ИСПОЛЬЗУЕТЕ МЕХАНИЗМ СКРИПТОВ, КОТОРЫЙ ЗАПУСКАЕТСЯ ОТ ИМЕНИ ROOT БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ,
НА ВАШЕ УСМОТРЕНИЕ. ЛИЦЕНЗИАР ЯВНО ОТКАЗЫВАЕТСЯ ОТ ВСЕХ ГАРАНТИЙ, ЯВНЫХ, ПОДРАЗУМЕВАЕМЫХ ИЛИ
УСТАНОВЛЕННЫХ ЗАКОНОДАТЕЛЬСТВОМ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ПОДРАЗУМЕВАЕМЫМИ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ.

В ПОЛНОЙ МЕРЕ, РАЗРЕШЕННОЙ ЗАКОНОМ, ЛИЦЕНЗИАР НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА КОСВЕННЫЕ, СЛУЧАЙНЫЕ,
СПЕЦИАЛЬНЫЕ, ПОСЛЕДУЮЩИЕ УБЫТКИ ИЛИ УБЫТКИ В ВИДЕ УПУЩЕННОЙ ВЫГОДЫ ИЛИ ВЫРУЧКИ, ВОЗНИКШИЕ ВСЛЕДСТВИЕ ИЛИ СВЯЗАННЫЕ С ДАННЫМ СОГЛАШЕНИЕМ ИЛИ ВАШИМ ИСПОЛЬЗОВАНИЕМ МЕХАНИЗМА.

Введение

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

Загружать скрипты и настраивать их запуск через Веб-форму, Действия по событию, Действия по расписанию могут администраторы системы в разделе Настройки > Автоматизация и маршрутизация > Скрипты

Вопросы безопасности и производительности

Скрипты выполняются внутри контейнера, поэтому у них нет доступа к аппаратному узлу / виртуальной машине,
на которой установлена Swarmica.
Однако сценарии имеют доступ к общим разделам диска и основной базе данных, используемой Swarmica,
поэтому будьте осторожны при выполнении потенциально опасных операций, таких как удаление и изменение
любых данных или файлов.

Кроме того, ресурсы памяти/процессора используются совместно со всем инсталляцией Swarmica, поэтому
настоятельно рекомендуется минимизировать импорт библиотек и модулей до только необходимого
минимального набора функций.

Например, вместо импорта всего модуля import datetime импортируйте только необходимую вам функцию:
from datetime import timedelta.

Обзор движка времени выполнения

Есть несколько способов запуска сценария:

[Триггер события] ---> +context --\
                                  \
[Расписание] --------> +context----\
                                    >----> Runner.run(kwargs={data: **params, **context})
[CLI] -------------> +params-------/
                                  /
[API/WEB] ---------> +params-----/

Итак, в основном, если сценарий времени выполнения запускается Триггером События или по Расписанию,
то данные события и пользовательские контекстные данные, настроенные в соответствующем триггере /
расписании, передаются в параметры сценария.

Допустим, сценарий запускается событием UserEvent, тогда контекст можно разобрать следующим образом:

class Runner(BaseRunner):
    def run(self, *args, **kwargs):
        data = kwargs.get('data', {})
        if not data or 'event_id' not in data:
            logger.error(f"No event_id passed, exiting")
            return
        event = UserEvent.objects.filter(id=data['event_id']).first()
        if not event:
            logger.error(f"No event with {data['event_id']} found, exiting")
            return

Если мы настроим Триггер События на передачу дополнительного контекста в скрипт, например, списка
email-адресов для получения оповещения при изменении учетной записи пользователя, то он также будет
передан в скрипт.

При условии, что пользовательский контекст Триггера События выглядит так:

{
  "recipients": [
    "user1@domain.tld",
    "user2@domain.tld"
  ]
}

Теперь вы можете получить доступ к значению переменной внутри скрипта следующим образом:

data = kwargs.get('data', None)

if data:
    recipients = data.get('recipients', None)

Вы также можете настроить скрипт так, чтобы у него была собственная веб-форма, которая может принимать,
проверять и передавать параметры в скрипт.

Допустим, мы пишем скрипт, который генерирует пользовательский отчет в Excel и отправляет его списку
email-получателей. И мы хотим, чтобы пользователи передавали даты начала и окончания отчета и список
получателей, разделенный запятыми.

В веб-интерфейсе Swarmica в настройках скрипта мы настраиваем следующие параметры веб-формы:

[
  {
    "name": "start_date",
    "type": "datetime",
    "readonly": false,
    "displayName": "Report start date"
  },
  {
    "name": "end_date",
    "type": "datetime",
    "readonly": false,
    "displayName": "Report end date"
  },
  {
    "name": "recipients",
    "type": "text",
    "displayName": "Comma-separated recipients"
  }
]

Теперь мы можем получить доступ к этим параметрам в скрипта следующим образом:

params = kwargs.get('data', {})
if params:
    if 'recipients' in params:
        recipients = params.get('recipients')
        if recipients:
            recipients = [x.strip() for x in recipients.split(',') if '@' in x]
        if not recipients:
            logger.info("Input error: empty/invalid list of 'recipients' specified")
            return
        
        start_date = params.get('start_date', None)
        if isinstance(start_date, str) and start_date.strip():
            report_start_date = parse_datetime(start_date)
            
        end_date = params.get('end_date', None)
        if isinstance(end_date, str) and end_date.strip():
            report_end_date = parse_datetime(end_date)

        if not report_end_date:
            report_end_date = now().replace(hour=23, minute=30, second=0, microsecond=0).replace(tzinfo=default_time_zone)
        if not report_start_date:
            report_start_date = report_end_date - timedelta(days=1)

Доступ к объектам Swarmica

Обычно вам нужно манипулировать моделями и наборами запросов (querysets) для объектов Swarmica в
ваших скриптах.
Поскольку Swarmica использует Django в качестве фреймворка, большинство методов моделей и наборов
запросов также работают здесь.

Смотрите полную справку по методам моделей Django и наборов запросов на официальном сайте документации:

Querysets

Models

Большинство объектов, которые вам могут понадобиться, находятся в пакете core, за исключением объектов
User - они находятся в пакете swarmica_auth.

Также вам, как правило, потребуется импортировать общие константы, используемые Swarmica,
следующим образом:


from swarmica import defs

print(defs.USER_ROLES_INTERNAL)

Давайте рассмотрим некоторые типичные операции в действии.

Работа с набором Заявок (Tickets)

Давайте выведем ID заявки, тему и имя назначенного исполнителя для всех новых и открытых заявок,
созданных между указанными датами начала и окончания:


from swarmica import defs
from core.models import Ticket

class Runner(BaseRunner):
    def run(self, *args, **kwargs):
        params = kwargs.get('data', {})
        if not params:
            return
            
        start_date = params.get('start_date', None)
        
        if isinstance(start_date, str) and start_date.strip():
            report_start_date = parse_datetime(start_date)
        end_date = params.get('end_date', None)
        
        if isinstance(end_date, str) and end_date.strip():
            report_end_date = parse_datetime(end_date)

        if not report_end_date:
            report_end_date = now().replace(hour=23, minute=30, second=0, microsecond=0).replace(tzinfo=default_time_zone)
        if not report_start_date:
            report_start_date = report_end_date - timedelta(days=1)
            
        tickets = Ticket.objects.filter(created_at__range=(report_start_date,report_end_date), 
                                        status__in=[defs.TICKET_STATUSES_NEW, defs.TICKET_STATUSES_OPEN])
        
        for ticket in ticket:
            print(f"#{ticket.id}: {ticket.subject} ({ticket.assignee.name})")

Работа с Пользователями

Давайте отключим все email-уведомления для заблокированных пользователей:

from swarmica import defs
from swarmica_auth.models import User

class Runner(BaseRunner):
    def run(self, *args, **kwargs):
        
        users = User.objects.filter(role=defs.USER_ROLES_BLOCKED)
        
        for user in users:
            user.email_notifications.clear()

Доступные сторонние библиотеки:

Ряд предустановленных библиотек доступен для импорта и использования в ваших скриптах.
Смотрите список доступных методов в документации соответствующей библиотеки:

import re               # Для работы с регулярными выражениями
import os               # Для работы с вещами ОС, такими как пути к файлам и т.д.
import bs4              # Для парсинга HTML, XML и т.д. с помощью BeautifulSoup
import csv              # Для чтения и записи CSV
import json             # Для парсинга JSON
import time             # Для работы с текущим временем, например, генерации временных меток
import pandas           # Для работы с наборами данных
import urllib           # Для парсинга и записи параметров URL, urlencode и т.д.
import dateutil         # Для работы с датами, например, парсинга даты из строки
import datetime         # Для работы с объектами datetime, например, вычисления длительностей и т.д.
import openpyxl         # Для чтения и записи Excel
import requests         # Для работы с удаленными API и вебхуками

Шаблон скрипта

Скачать шаблон sample.py

Обновлена: 18 мая 2026 г.

Автоматизация на базе runtime-scripts состоит из двух частей:

a. Непосредственно сам скрипт, который совершает необходимые действия

b. Создание и настройка триггера по событию или триггера по расписанию

I. Создание скриптов

  1. Пишем нужный скрипт на питоне
  2. Логинимся в Свормику и идем в раздел Настройки>Скрипты, нажимаем Создать и создаем сущность скрипта
  3. В поле Скрипт загружаем ранее созданный скрипт

II. Создание и настройка триггера

  1. Перейдите в раздел Настройки>Действие по событию и нажмите создать
  2. Заполните поля тип события , например TicketEvent для событий с тикетами
  3. Типа действия: Скрипт
  4. Действие - выберете из списка ранее созданный и загруженный скрипт
  5. Запустите триггер нажав
Обновлена: 18 мая 2026 г.

Пользователь: UserEvent

API Список событий с пользователем

КодНазваниеЗначение
0USER_EVENTS_ROLE_CHANGEDСмена роли
1USER_EVENTS_PASSWORD_CHANGEDСмена пароля
2USER_EVENTS_IDENTITY_ADDEDДобавлена учётная запись
3USER_EVENTS_ORGANIZATION_CHANGEDСмена компании
4USER_EVENTS_SCHEDULE_CHANGEDСмена расписания
5USER_EVENTS_NAME_CHANGEDСмена имени
6USER_EVENTS_CHAT_STATUS_CHANGEDСмена статуса в чате
7USER_EVENTS_MERGED_INTOОбъединен в пользователя
8USER_EVENTS_MERGED_FROMОбъединен из пользователя
9USER_EVENTS_USER_CREATEDПользователь создан
10USER_EVENTS_LOGINЗапрошен доступ в систему
11USER_EVENTS_NOTIFICATION_ENABLEDПочтовое уведомление включено
12USER_EVENTS_NOTIFICATION_DISABLEDПочтовое уведомление выключено

Статья: ArticleEvent

API Список событий в статье

КодНазваниеЗначение
0ARTICLE_EVENT_UNKNOWNПустое событие
1ARTICLE_EVENT_CREATEDСтатья создана
2ARTICLE_EVENT_SEGMENT_CHANGEDИзменён сегмент публикации статьи
3ARTICLE_EVENT_PUBLISHEDСтатья опубликована
4ARTICLE_EVENT_UNPUBLISHEDСтатья снята с публикации
5ARTICLE_EVENT_DELETEDСтатья заархивирована
6ARTICLE_EVENT_UNDELETEDСтатья восстановлена из архива
7ARTICLE_EVENT_AUTHOR_CHANGEDСмена автора
8ARTICLE_EVENT_FLAGGEDСтатья помечена к исправлению
9ARTICLE_EVENT_UNFLAGGEDПометка к исправлению снята
10ARTICLE_EVENT_AGENT_COMMENTСотрудник добавил комментарий
11ARTICLE_EVENT_CUSTOMER_COMMENTКлиент добавил комментарий
12ARTICLE_EVENT_AGENT_COMMENT_CHANGEDСотрудник отредактировал комментарий

Заявка: TicketEvent

API Список событий в заявке

КодНазваниеЗначение
0TICKET_EVENTS_UNKNOWNПустое событие
1TICKET_EVENTS_KCS_NEWСтатья создана из заявки
2TICKET_EVENTS_KCS_LINKСтатья добавлена к заявке
3TICKET_EVENTS_KCS_FLAGСтатья помечена к исправлению
4TICKET_EVENTS_STATUS_CHANGEСмена статуса
5TICKET_EVENTS_AGENT_COMMENTСотрудник добавил ответ
6TICKET_EVENTS_CUSTOMER_COMMENTКлиент добавил ответ
7TICKET_EVENTS_RATEDЗаполнена оценка качества сервиса
8TICKET_EVENTS_PRIORITY_CHANGEСмена приоритета
9TICKET_EVENTS_CREATEDЗаявка создана
10TICKET_EVENTS_ASSIGNEE_CHANGEСмена ответственного
11TICKET_EVENTS_REQUESTER_CHANGEСмена заявителя
12TICKET_EVENTS_GROUP_CHANGEСмена группы
13TICKET_EVENTS_PLATFORM_CHANGEСмена платформы
14TICKET_EVENTS_PRODUCT_CHANGEСмена продукта
15TICKET_EVENTS_VERSION_CHANGEСмена версии
16TICKET_EVENTS_EDITION_CHANGEСмена компоновки
17TICKET_EVENTS_ISSUE_ADDЗадача добавлена
18TICKET_EVENTS_ISSUE_DELETEЗадача удалена
19TICKET_EVENTS_CF_CHANGEИзменено значение дополнительного атрибута
20TICKET_EVENTS_KCS_UNLINKУбрана связь со статьёй
21TICKET_EVENTS_SKILL_ADDДобавлен навык
22TICKET_EVENTS_SKILL_DELETEУдалён навык
23TICKET_EVENTS_RELATED_TICKET_ADDДобавлена связанная заявка
24TICKET_EVENTS_RELATED_TICKET_DELETEУдалена связь с заявкой
25TICKET_EVENTS_MERGEDЗаявка объединена с другой
26TICKET_EVENTS_CHAT_SESSION_STARTEDНачалась сессия в чате
27TICKET_EVENTS_CHAT_SESSION_ENDEDСессия в чате завершена
28TICKET_EVENTS_AGENT_INTERNAL_COMMENTВнутренний комментарий добавлен
29TICKET_EVENTS_PENDING_NOTIFICATION_SENTОтправлено почтовое уведомление об ожидании ответа
30TICKET_EVENTS_SLA_CHANGEDИзменена политика SLA
31TICKET_EVENTS_LICENSE_CHANGEDИзменена лицензия
32TICKET_EVENTS_ISSUE_STATUS_CHANGED_DEPRECATEDНе используется
33TICKET_EVENTS_FORKEDИз заявки создана новая
34TICKET_EVENTS_ISSUE_CLOSEDСвязанная задача закрыта
35TICKET_EVENTS_ISSUE_OPENEDСвязанная задача открыта
36TICKET_EVENTS_AUTOASSIGN_RULE_APPLIEDПрименено правило автоматического назначения
37TICKET_EVENTS_INTERNAL_COMMENT_CHANGEDИзменён внутренний комметнарий
38TICKET_EVENTS_ARTICLE_NOT_NEEDEDПереключен флаг "Статья не нужна"
39TICKET_EVENTS_AUTORESPONSE_COMMENTДобавлен автоматический ответ системы
40TICKET_EVENTS_TIME_ESTIMATE_CHANGEИзменена оценка времени
41TICKET_EVENTS_ISSUE_DELETEDЗвязанная задача удалена
42TICKET_EVENTS_ASSET_ADDEDДобавлен актив
43TICKET_EVENTS_ASSET_DELETEDАктив удалён
44TICKET_EVENTS_ASSET_UPDATEDАктив изменён
45TICKET_EVENTS_SUBJECT_CHANGEDИзменение заголовка заявки
46TICKET_EVENTS_PUBLIC_COMMENT_CHANGEDПубличный ответ изменён
47TICKET_EVENTS_COMMENT_DELETEDКоментарий удалён
48TICKET_EVENTS_CC_ADDEDПользователь добавлен в CC
49TICKET_EVENTS_CC_DELETEDПользователь убран из CC
50TICKET_EVENTS_WATCHER_ADDEDПользователь добавлен в наблюдатели
51TICKET_EVENTS_WATCHER_DELETEDПользователь убран из CC

Обновлена: 18 мая 2026 г.
Всего результатов: 24
Элементов на странице
Страница
  • 1(current)
  • 2
  • 3