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

A plugin of this type is embedded into the trigger creation and editing form and passes action data on Tracker'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 Tracker's request, passes this form's data in the WebhookTriggerActionInput format.

The initiative to save always remains on Tracker's side. At the right moment, Tracker calls the registered method and receives 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

Tracker must receive the form data from the plugin. For this purpose, register a function via registerHandler that Tracker can 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/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 (
    // 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) registers a function through which Tracker receives the action data.

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 plugin won't be able to get the context and interact with Tracker:

import { TrackerPluginProvider } from '@weavix/tracker-plugin-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, Tracker will be able to call getTriggerActionData() at the right moment and get the current form data to save the trigger action.