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

Отредактирована: 8 дней назад

Вопрос

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

Ответ

В 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