Как создать плагин «Действие триггера» (trigger.action)

Плагин этого типа подставляется в форму создания и редактирования триггера и отдает данные действия по запросу хоста.

1. Создание проекта через CLI

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

weavix create

В ответ на вопрос Select a template: выберите trigger.action.

Остальные шаги — имя, описание, права доступа и т.д. — заполните по запросу. В результате будет сгенерирован проект с уже настроенным манифестом под слоты trigger.create.action и trigger.edit.action и заготовкой кода.

2. Что такое плагин trigger.action

Плагин trigger.action — это часть интерфейса и логики, которая встраивается в форму триггера в Трекере:

  • trigger.create.action — показывается при создании нового действия триггера;
  • trigger.edit.action — при редактировании уже существующего действия.

Плагин не сам создает или сохраняет триггер. Он только:

  1. Показывает свою форму (поля, настройки).
  2. По запросу хоста отдает данные этой формы в формате WebhookTriggerActionInput.

То есть инициатива «сохранить» всегда на стороне хоста (Трекера). Хост в нужный момент вызывает зарегистрированный метод и забирает данные.

Примечание

Так как плагин по факту создает действие типа http-запрос, то и все подстановки, которые возможны в интерфейсе Трекера для этого действия, плагин может указывать.

3. Манифест плагина

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

Пример структуры manifest.json:

{
  "id": "my-trigger-plugin",
  "version": "1.0.0",
  "name": { "ru": "Мое действие триггера", "en": "My trigger action" },
  "description": { "ru": "Описание", "en": "Description" },
  "author": "Your Name",
  "support": [{ "type": "email", "value": "support@example.com" }],
  "permissions": {
    "data": []
  },
  "slots": {
    "tracker": {
      "trigger.create.action": [
        {
          "entrypoint": "index.html",
          "title": { "ru": "Создание действия", "en": "Create action" }
        }
      ],
      "trigger.edit.action": [
        {
          "entrypoint": "index.html",
          "title": { "ru": "Редактирование действия", "en": "Edit action" }
        }
      ]
    }
  }
}

Важно

  • В slots.tracker обязательно указать оба ключа: trigger.create.action и trigger.edit.action.
  • entrypoint — обычно один и тот же, например index.html. Точка входа у слотов общая, различие только в контексте: создание или редактирование.

4. Регистрация метода для отдачи данных

Хост должен уметь «запросить» у плагина данные формы. Для этого в SDK есть registerHandler: вы регистрируете функцию, которую хост потом вызовет.

4.1. Какой метод регистрировать

Нужно зарегистрировать хендлер с именем getTriggerActionData и сигнатурой:

  • Имя метода: getTriggerActionData
  • Сигнатура: функция без аргументов, возвращающая объект типа WebhookTriggerActionInput

Тип импортируется из пакета @weavix/tracker-api-types.

4.2. Где вызывать registerHandler

registerHandler доступен из хука useTrackerPluginContext.

Пример:

import { useTrackerPluginContext } from '@weavix/sdk-react';
import type { WebhookTriggerAction } from '@weavix/tracker-api-types';

const App = () => {
  const { registerHandler, slot, slotContext } = useTrackerPluginContext();

  const getFormData = (): WebhookTriggerAction => ({
    id: 0,
    type: 'Webhook',
    method: 'POST',
    endpoint: 'https://example.com/webhook',
    contentType: 'application/json; charset=UTF-8',
    body: '{}',
    authContext: { type: 'noauth' } as WebhookTriggerAction['authContext'],
  });

  registerHandler('getTriggerActionData', getFormData);

  return (
    // ваш UI
  );
};

Здесь:

  • getFormData собирает объект из состояния формы: поля, выбранные значения и т.д. В примере значения заданы явно. В реальном плагине вы подставите значения из useState, полей ввода и т.п.
  • registerHandler('getTriggerActionData', getFormData) — сообщает хосту: «чтобы получить данные действия, вызови эту функцию».

5. Различие слотов: создание и редактирование

Плагин один и тот же, но он может открываться в двух режимах:

Слот в манифесте Назначение
trigger.create.action Форма создания действия триггера
trigger.edit.action Форма редактирования действия

В коде вы получаете текущий слот и контекст через useTrackerPluginContext:

const { slot, slotContext } = useTrackerPluginContext();
  • slot — в каком слоте открыт плагин: 'trigger.create.action' или 'trigger.edit.action'.
  • slotContext — объект с данными контекста. Тип зависит от слота:
    • Создание: только ключ очереди, например { queue: string }.
    • Редактирование: ключ очереди плюс сохраненные данные действия, например { queue: string; data: WebhookTriggerAction }.

Чтобы TypeScript правильно сужал тип slotContext, можно задать тип слота при вызове хука:

type TriggerActionSlot = 'trigger.create.action' | 'trigger.edit.action';

const { slot, slotContext } = useTrackerPluginContext<TriggerActionSlot>();

Тогда при проверке slot === 'trigger.edit.action' в slotContext будет доступно поле data с сохраненным действием — его можно использовать для подстановки в форму при открытии редактирования.

Пример: при редактировании подставить сохраненный URL в поле:

useEffect(() => {
  if (slot === 'trigger.edit.action' && slotContext && 'data' in slotContext) {
    const savedEndpoint = slotContext.data?.endpoint;
    if (savedEndpoint) setEndpoint(savedEndpoint);
  }
}, [slot, slotContext]);

6. Минимальная структура приложения

  1. Точка входа, например main.tsx: рендер в корень DOM и обертка в TrackerPluginProvider.
  2. Корневой компонент, например App.tsx:
    • использует useTrackerPluginContext и получает theme, registerHandler, slot, slotContext;
    • объявляет функцию getFormData, возвращающую объект типа WebhookTriggerAction (или другой тип действия);
    • вызывает registerHandler('getTriggerActionData', getFormData);
    • по желанию сужает тип по slot и заполняет форму из slotContext при редактировании;
    • рендерит UI формы (поля ввода, тему через ThemeProvider и т.д.).

Обертка провайдером обязательна, иначе контекст и хост не смогут связаться с плагином:

import { TrackerPluginProvider } from '@weavix/sdk-react';

root.render(
  <TrackerPluginProvider>
    <App />
  </TrackerPluginProvider>
);

7. Тип WebhookTriggerActionInput (кратко)

Объект, который возвращает getTriggerActionData, должен соответствовать типу WebhookTriggerActionInput из @weavix/tracker-api-types. Основные поля (актуальный набор смотрите в типах пакета):

  • type: 'Webhook'
  • method: HTTP-метод, например 'POST', 'GET'
  • endpoint: URL вебхука
  • contentType: тип тела запроса, например 'application/json; charset=UTF-8'
  • body: тело запроса (строка)
  • headers заголовки запроса
  • authContext: настройки авторизации (например, { type: 'noauth' })

Так как по факту вы создаете действие типа http-запрос, то можете указывать все подстановки в body, заголовки, которые доступны для этого типа.
Например, {{issue.summary}} — для заголовка задачи

8. Не забывайте про отладку

Как отлаживать плагин.

9. Чеклист перед публикацией

  • В манифесте указаны оба слота: trigger.create.action и trigger.edit.action.
  • В корневом компоненте вызывается registerHandler('getTriggerActionData', getFormData).
  • getFormData возвращает объект в формате WebhookTriggerAction, собранный из текущего состояния формы.

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