How to create a trigger action plugin (trigger.action)

A plugin of this type is embedded into the trigger creation and editing form and returns action data on the host's request.

1. Creating a project via CLI

To create a new plugin of this type, use the app creation command and select the required template in the dialog:

weavix create

In response to Select a template, select trigger.action.

Fill in the remaining steps, such as name, description, access permissions, and so on, as prompted. This will generate a project with a pre-configured manifest for the trigger.create.action and trigger.edit.action slots, along with a code stub.

2. What is a trigger.action plugin

The trigger.action plugin is a piece of interface and logic embedded into the trigger form in Tracker:

  • trigger.create.action: shown when creating a new trigger action.
  • trigger.edit.action: shown when editing an existing action.

The plugin does not create or save the trigger itself. It only:

  1. Shows its form (fields, settings).
  2. On the host's request, returns this form's data in the WebhookTriggerActionInput format.

This means that the initiative to save is always on the host's (Tracker's) side. At the right moment, the host calls the registered method and retrieves the data.

Note

Since the plugin actually creates an http request action, it can specify all the substitutions that are available for this action in the Tracker interface.

3. Plugin manifest

In the manifest, you need to declare both slots so that the plugin is embedded both when creating and editing an action.

Example of a manifest.json structure:

{
  "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" }
        }
      ]
    }
  }
}

Important

  • In slots.tracker, make sure to specify both keys: trigger.create.action and trigger.edit.action.
  • entrypoint is usually the same, for example, index.html. The entry point is shared between the slots; the only difference is the context: creation or editing.

4. Registering a method for returning data

The host must be able to request form data from the plugin. For this purpose, the SDK provides registerHandler: you register a function that the host will then call.

4.1. Which method to register

You need to register a handler named getTriggerActionData with the following signature:

  • Method name: getTriggerActionData
  • Signature: A function with no arguments that returns an object of the WebhookTriggerActionInput type

The type is imported from the @weavix/tracker-api-types package.

4.2. Where to call registerHandler

registerHandler is available from the useTrackerPluginContext hook.

Example:

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 (
    // your UI
  );
};

Here:

  • getFormData assembles an object from the form state: fields, selected values, and so on. In the example, the values are set explicitly. In a real plugin, you will substitute values from useState, input fields, and similar sources.
  • registerHandler('getTriggerActionData', getFormData) tells the host: "To get the action data, call this function".

5. Slot differences: creation and editing

The plugin is the same, but it can open in two modes:

Slot in the manifest Purpose
trigger.create.action Form for creating a trigger action
trigger.edit.action Form for editing an action

In the code, you get the current slot and context via useTrackerPluginContext:

const { slot, slotContext } = useTrackerPluginContext();
  • slot: The slot in which the plugin is open: 'trigger.create.action' or 'trigger.edit.action'.
  • slotContext: An object with context data. The type depends on the slot:
    • Creation: Only the queue key, for example, { queue: string }.
    • Editing: The queue key plus the saved action data, for example, { queue: string; data: WebhookTriggerAction }.

To make TypeScript narrow down the slotContext type correctly, you can specify the slot type when calling the hook:

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

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

Then, when checking slot === 'trigger.edit.action', the data field with the saved action will be available in slotContext. You can use it to populate the form when opening the editing mode.

Example: substituting the saved URL into the field during editing:

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

6. Minimal app structure

  1. Entry point, for example, main.tsx: rendering into the DOM root and wrapping in TrackerPluginProvider.
  2. Root component, for example, App.tsx:
    • Uses useTrackerPluginContext and gets theme, registerHandler, slot, slotContext.
    • Declares the getFormData function that returns an object of the WebhookTriggerAction type (or another action type).
    • Calls registerHandler('getTriggerActionData', getFormData).
    • Optionally narrows the type based on slot and populates the form from slotContext during editing.
    • Renders the form UI (input fields, theme via ThemeProvider, and so on).

Wrapping with the provider is required, otherwise the context and the host won't be able to communicate with the plugin:

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

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

7. WebhookTriggerActionInput type (briefly)

The object returned by getTriggerActionData must match the WebhookTriggerActionInput type from @weavix/tracker-api-types. Key fields (see the package types for the actual set):

  • type: 'Webhook'
  • method: HTTP method, such as 'POST' or 'GET'
  • endpoint: Webhook URL
  • contentType: Request body type, such as 'application/json; charset=UTF-8'
  • body: Request body (string)
  • headers: Request headers
  • authContext: Authorization settings (for example, { type: 'noauth' })

Since you're actually creating an HTTP request action, you can specify all the substitutions in the body and headers that are available for this type.
For example, {{issue.summary}} for the issue summary

8. Don't forget about debugging

How to debug a plugin.

9. Pre-publication checklist

  • The manifest specifies both slots: trigger.create.action and trigger.edit.action.
  • The root component calls registerHandler('getTriggerActionData', getFormData).
  • getFormData returns an object in the WebhookTriggerAction format assembled from the current form state.

After this, the host will be able to call getTriggerActionData() at the right moment and get the current data of your form to save the trigger action.