# Custom action plugins

A custom action plugin is a [plugin](https://developer.mediarithmics.io/advanced-usages/plugins) that can be associated to a custom action node in an automation, allowing you to trigger a custom action in an automation.

This feature is useful for triggering actions not available in the current list of actions in automations.

{% hint style="success" %}
If you don't know what a plugin is, you can find [complete documentation in the specific section.](https://developer.mediarithmics.io/advanced-usages/plugins)
{% endhint %}

## Endpoints to implement

Custom action plugins have only one predefined endpoint to implement.

## Trigger a custom action

<mark style="color:green;">`POST`</mark> `myworker/v1/scenario_custom_actions`

This entry point is called any time a UserPoint goes through a custom action node in an automation.

#### Request Body

| Name               | Type   | Description                                                                                |
| ------------------ | ------ | ------------------------------------------------------------------------------------------ |
| user\_point\_id    | string | The ID of the UserPoint.                                                                   |
| custom\_action\_id | string | The ID of the custom action plugin instance. **Used to retrieve the instance properties.** |

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "status": "ok"
}
```

{% endtab %}

{% tab title="500 Here is what the plugin should respond if it encounters an unexpected error." %}

```javascript
{
  "status": "error",
  "message": "..."
}
```

{% endtab %}
{% endtabs %}

See [Plugin Instances ](https://developer.mediarithmics.io/plugins#instances)to learn why you should use the `custom_action_id` parameter to retrieve the instance properties.

## Available outbound services

The code of the custom action plugin can call the following API endpoints to retrieve[ its instance context](https://developer.mediarithmics.io/plugins#instances).

## Retrieve the instance

<mark style="color:blue;">`GET`</mark> `https://api.mediarithmics.com/v1/scenario_custom_actions/:id`

Use the custom\_action\_id from the incoming request to retrieve the custom action plugin instance that has been called.

#### Path Parameters

| Name | Type   | Description                                                                                          |
| ---- | ------ | ---------------------------------------------------------------------------------------------------- |
| id   | string | ID of the custom action plugin instance, typically the `custom_action_id` from the incoming request. |

{% tabs %}
{% tab title="200 " %}

```javascript
{
  "status": "ok",
  "data": {
    "id": "1000",
    "name": "Custom action plugin example",
    "organisation_id": "1000",
    "group_id": "com.example-organisation.scenario-custom-action",
    "artifact_id": "example-organisation-example-custom-action"
    "creation_ts": 1617100419508,
    "created_by": "28453014",
    "version_id": "1001",
    "version_value": "1.0.0"
  }
}
```

{% endtab %}
{% endtabs %}

## Retrieve the instance properties

<mark style="color:blue;">`GET`</mark> `https://api.mediarithmics.com/v1/scenario_custom_actions/:id/properties`

Get the properties associated with the custom action plugin instance.

#### Path Parameters

| Name | Type   | Description                                                                                        |
| ---- | ------ | -------------------------------------------------------------------------------------------------- |
| id   | string | ID of the custom action plugin instance, typically the`custom_action_id` from the incoming request |

{% tabs %}
{% tab title="200 " %}

```javascript
{
  "status": "ok",
  "data": [
    {
      "technical_name": "provider",
      "value": { "value": "mediarithmics" },
      "property_type": "STRING",
      "origin": "PLUGIN_STATIC",
      "writable": true,
      "deletable": false
    },
    {
      "technical_name": "name",
      "value": { "value": "Custom action example" },
      "property_type": "STRING",
      "origin": "PLUGIN_STATIC",
      "writable": false,
      "deletable": false
    }
  ]
}
```

{% endtab %}
{% endtabs %}

## Creating a custom action plugin

See the [plugins](https://developer.mediarithmics.io/advanced-usages/plugins) documentation to see [how plugins are created and deployed](https://developer.mediarithmics.io/advanced-usages/plugins).

{% hint style="success" %}
A custom action plugin has the `SCENARIO_CUSTOM_ACTION` plugin type. Its group id should be `{domain.organisation.scenario-custom-action}` (for example `com.mediarithmics.scenario-custom-action`).

Its artifact id should be the name of the custom action plugin, i.e. `example-custom-action`.
{% endhint %}

Use our [Plugin SDK](https://developer.mediarithmics.io/resources/tools-and-libraries/plugin-sdk) to create your custom action plugin in `Node.js`: the required routes are already defined and you only have to override specific functions.

{% hint style="info" %}
You can find a sample custom action plugin [in the examples folder of the plugin SDK](https://github.com/MEDIARITHMICS/plugins-nodejs-sdk/tree/master/examples/activity-analyzer).
{% endhint %}

We can provide you with a *Hello World* project using our SDK. Please contact your support to gain access to it.

The project structure and files work as [with every other plugin](https://developer.mediarithmics.io/advanced-usages/plugins/creation).

### Interfaces to implement

You should extend `CustomActionBasePlugin` class and implement the `onCustomActionCall` function from the plugin SDK.

The `onCustomActionCall` function is called every time a UserPoint runs through a custom action node in an automation. It is responsible for implementing the custom action.

{% hint style="warning" %}
Don't forget to catch your errors. You should log / respond with the appropriate message to facilitate debugging.
{% endhint %}

```javascript
import { core } from '@mediarithmics/plugins-nodejs-sdk';

export class MyCustomActionPlugin extends core.CustomActionBasePlugin {
  protected onCustomActionCall(
    request: core.CustomActionRequest,
    instanceContext: core.CustomActionBaseInstanceContext
  ): Promise<core.CustomActionPluginResponse> {

    // do stuff here

    const response: core.CustomActionPluginResponse = {
      status: 'ok',
    };

    return Promise.resolve(response);
  }
}
```

## Create a custom action plugin instance

<mark style="color:green;">`POST`</mark> `https://api.mediarithmics.com/v1/scenario_custom_actions`

Use this method to create a custom action plugin instance attached to an organisation. This will display the custom action as a choice in the custom action automation node.

#### Request Body

| Name             | Type   | Description                                                                                      |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------ |
| organisation\_id | string | The ID of the organisation you want to attach this instance to.                                  |
| name             | string | The name for this instance. If not given, the instance ID will be used in the interface instead. |
| artifact\_id     | string | The artifact ID of the plugin.                                                                   |
| group\_id        | string | The group ID of the plugin.                                                                      |

{% tabs %}
{% tab title="200 " %}

```
{
    "status": "ok",
    "data": {
        "id": "string",
        "name": "string",
        "organisation_id": "string",
        "group_id": "string",
        "artifact_id": "string",
        "creation_ts": 1618842498220,
        "created_by": "string",
        "version_id": "string",
        "version_value": "string"
    }
}
```

{% endtab %}
{% endtabs %}

## Update a custom action plugin instance property

<mark style="color:orange;">`PUT`</mark> `https://api.mediarithmics.com/v1/scenario_custom_actions/:id/properties/technical_name=:name`

Use this method to update a property for the custom action plugin instance.

#### Path Parameters

| Name | Type   | Description                                   |
| ---- | ------ | --------------------------------------------- |
| name | string | The technical name of the property to update. |
| id   | string | The ID for the custom action plugin instance. |

#### Request Body

| Name            | Type    | Description                                                                                                                                                                       |
| --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| deletable       | boolean |                                                                                                                                                                                   |
| writable        | boolean |                                                                                                                                                                                   |
| origin          | string  | One of `PLUGIN_STATIC`, `PLUGIN`, `INSTANCE`.                                                                                                                                     |
| property\_type  | string  | One of `DOUBLE`, `INT`, `BOOLEAN`, `ASSET`, `DATA_FILE`,  `URL`, `STRING`, `AD_LAYOUT`, `STYLE_SHEET`, `PIXEL_TAG`, `RECOMMENDER`, `NATIVE_IMAGE`, `NATIVE_TITLE`, `NATIVE_DATA`. |
| technical\_name | string  | The technical name of the property to update.                                                                                                                                     |
| value           | object  | Value format depends on property type. If property type is `STRING`,  value will be an object `{"value": "string"}`.                                                              |

{% tabs %}
{% tab title="200 " %}

```
{
    "status": "ok",
    "data": {
        "technical_name": "string",
        "value": {
            "value": "string"
        },
        "property_type": "STRING",
        "origin": "PLUGIN",
        "writable": true,
        "deletable": false
    }
}
```

{% endtab %}
{% endtabs %}

## Debugging

### Plugin logs and metrics

You can monitor custom action plugins[ as you do with all plugins](https://developer.mediarithmics.io/advanced-usages/plugins/monitoring).
