---
metadata:
  - name: generator
    content: Diplodoc Platform v5.52.0
  - property: og:type
    content: article
  - property: article:section
    content: Plugin platform
  - property: og:title
    content: How to create a trigger action plugin (trigger.action)
  - property: article:tag
    content: Technical instructions
alternate:
  - https://yandex.ru/support/tracker/en/plugins/slots/trigger-action.md
  - https://yandex.ru/support/tracker/ru/plugins/slots/trigger-action.md
  - href: en/plugins/slots/trigger-action.md
    type: text/markdown
    title: Markdown version
  - href: ../../llms.txt
    type: text/markdown
    title: llms.txt
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.ru/support/tracker/en/llms.txt


# 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 {#create-project}

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

```bash
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 {#what-is}

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**](https://yandex.ru/support/tracker/en/plugins/slots/trigger-action.md#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 info %}

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.

{% endnote %}

## 3. Plugin manifest {#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:

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

{% note alert "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.

{% endnote %}

## 4. Registering a method for returning data {#register-method}

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 {#which-method}

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 {#where-register-handler}

`registerHandler` is available from the **useTrackerPluginContext** hook.

Example:

```tsx
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 {#slots-difference}

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**:

```tsx
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:

```tsx
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:

```tsx
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 {#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:

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

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

## 7. WebhookTriggerActionInput type (briefly) {#WebhookTriggerActionInput}

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 {#debug}

[How to debug a plugin](https://yandex.ru/support/tracker/en/plugins/tools/cli.md#debug).

## 9. Pre-publication checklist {#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.