Как создать плагин «Действие триггера» (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. Регистрация метода для отдачи данных

Трекер должен получить от плагина данные формы. Для этого зарегистрируйте через registerHandler функцию, которую Трекер сможет вызвать.

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

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

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

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

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

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

Пример:

import { useTrackerPluginContext } from '@weavix/tracker-plugin-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/tracker-plugin-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() и получить актуальные данные формы для сохранения действия триггера.