# Automation Plugin



import Image from 'next/image';

The Automation Plugin allows you to implement custom business logic, create your own Socotra API endpoints, define request and response objects, and send HTTP requests to both third-party and Socotra API endpoints. This allows implementing teams to address most automation, integration, and orchestration requirements directly within the core platform.

This plugin can be executed manually by calling the [Execute Automation Plugin](/api/configuration-and-development/automation-plugin) API endpoint. It can also be configured to execute in response to events that occur within the Socotra Insurance Suite.

The Automation Plugin must be implemented as a `Global` implementation, not a `Product` implementation. See the [Plugins Overview](/configuration/plugins/overview) guide for more information.

We strongly recommend reviewing the [Configuration SDK](/configuration/general-topics/configuration-sdk) guide before using this feature.

<Callout>
  The Automation Plugin currently supports API calls only via the [Java HttpClient ](https://docs.oracle.com/en/java/javase/21/docs/api/java.net.http/java/net/http/HttpClient.html). A Socotra API-specific client is planned for a future release to simplify the process of calling Socotra API endpoints.
</Callout>

Use Cases [#use-cases]

The Automation Plugin supports a wide variety of use cases. Some examples include:

* Bulk ingestion of data from CSV and other file formats
* Generating and attaching documents such as certificates of insurance or delinquency notices
* Updating [static data](/configuration/data-extensions/static-data)
* Monitoring, reporting, and analytics

<Callout type="warn">
  The rest of this guide is based on the config-sdk-template project used in the [Configuration SDK](/configuration/general-topics/configuration-sdk) guide.
</Callout>

Configuring the Automation Plugin [#configuring-the-automation-plugin]

The Automation Plugin can be configured in the tenant configuration using the following folder structure: `socotra-config/automations/PluginName/config.json`. You can also configure the Automation Plugin in the root-level `config.json` file within the `socotra-config` folder in the tenant configuration.

Here's an example of the folder structure:

<Image src="/images/automation_plugin/plugin_dir_structure.png" alt="Automation Plugin Directory Structure" width={200} height={1982} unoptimized />

In the example above, the `AttachDocument` and `PolicyRenewal` folders refer to the names of your Automation Plugin implementations. You can create as many implementations as you'd like. Each implementation can contain multiple actions, which correspond to method names in your Java implementation classes.

Here's an example of a `config.json` file for the `AttachDocument` implementation:

```java
{
    "actions": {
        "attachCertificateOfInsurance": {
            "timeout": 3,
            "request": {
                "contactName": {
                    "displayName": "Contact Name",
                    "type": "string"
                },
                "policyNumber": {
                    "displayName": "Policy Number",
                    "type": "string"
                }
            },
            "response": {
                "result": {
                    "displayName": "Result",
                    "type": "boolean",
                    "defaultValue" : "true"
                }
            }
        },
        "attachReport": {
            "timeout": 10,
            "request": {
                "reportType": {
                    "displayName": "Report Type",
                    "type": "string"
                },
                "reportName": {
                    "displayName": "Report Name",
                    "type": "string"
                }
            },
            "response": {
                "result": {
                    "displayName": "Result",
                    "type": "boolean",
                    "defaultValue" : "true"
                }
            }
        }
    }
}
```

In the example above, `attachCertificateOfInsurance` and `attachReport` are the names of actions available within the `AttachDocument` implementation, and each `action` specifies fields within the `request` and `response` objects. If `request` or `response` objects are not defined, they will not be included in the method signature for a given `action`.

Refer to the :Doc:`Data Extension Types</configuration/dataExtensions/dataExtensionTypes>` guide for a comprehensive list of field types for request and response objects. Request and response objects currently do not support the `scope` data type property.

Once you've finished making changes to your configuration, execute the `refreshReferenceDatamodel` Gradle task. This will generate a Java interface for each of your implementations.

<Callout>
  If your tenant configuration has never been deployed, you will first need to deploy your configuration by executing the `deployConfigToTenant` task at least once before you can begin executing the `refreshReferenceDatamodel` task.
</Callout>

Implementing the Automation Plugin [#implementing-the-automation-plugin]

Create a new Java class in the `src/main/java/com/socotra/deployment/customer` folder using the following naming convention for the class name: `PluginNameAutomationPluginImpl`. You can name your class whatever you'd like, but we suggest following this naming convention. Your Java implementation classes must be contained within this folder.

Here's an example of the `AttachDocumentAutomationPluginImpl` class for the `AttachDocument` implementation:

```java
package com.socotra.deployment.customer;

import com.socotra.deployment.plugins.PluginExecutionContext;
import com.socotra.deployment.plugins.AutomationPluginContextData;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AttachDocumentAutomationPluginImpl implements AttachDocumentAutomationPlugin {
    private static final Logger log = LoggerFactory.getLogger(AttachDocumentAutomationPluginImpl.class);

    @Override
    public AttachDocumentAttachCertificateOfInsuranceResponse attachCertificateOfInsurance(AttachDocumentAttachCertificateOfInsuranceRequest attachDocumentAttachCertificateOfInsuranceRequest) {
        PluginExecutionContext context = PluginExecutionContext.get();
        AutomationPluginContextData automationContext = context.getAutomationPluginContext().orElseThrow();
        log.info("In AttachDocumentAutomationPluginImpl.attachCertificateOfInsurance()");
        log.info("Request fields: {} {}", attachDocumentAttachCertificateOfInsuranceRequest.contactName(), attachDocumentAttachCertificateOfInsuranceRequest.policyNumber());
        log.info("Context: {} {} {} {}", context.getRequestId(), context.getTenantLocator(), context.getBusinessAccount(), automationContext.secret());
        return new AttachDocumentAttachCertificateOfInsuranceResponse().builder().result(true).build();
    }

    @Override
    public AttachDocumentAttachReportResponse attachReport(AttachDocumentAttachReportRequest attachDocumentAttachReportRequest) {
        PluginExecutionContext context = PluginExecutionContext.get();
        AutomationPluginContextData automationContext = context.getAutomationPluginContext().orElseThrow();
        log.info("In AttachDocumentAutomationPluginImpl.attachReport()");
        log.info("Request fields: {} {}", attachDocumentAttachReportRequest.reportType(), attachDocumentAttachReportRequest.reportName());
        log.info("Context: {} {} {} {}", context.getRequestId(), context.getTenantLocator(), context.getBusinessAccount(), automationContext.secret());
        return new AttachDocumentAttachReportResponse().builder().result(true).build();
    }
}
```

The example above demonstrates how to access request fields, `PluginExecutionContext` data, and `AutomationPluginContextData` data. Response objects can be created using the builder pattern.

The request and response classes are generated automatically using the following naming conventions: `PluginNameActionNameRequest` and `PluginNameActionNameResponse`.

HTTP requests can be performed using the [Java HttpClient ](https://docs.oracle.com/en/java/javase/21/docs/api/java.net.http/java/net/http/HttpClient.html). Refer to the [Plugins Overview](/configuration/plugins/overview) for more information.

Once you've finished making changes to your implementations, execute the `deployConfigToTenant` Gradle task. This will generate an API endpoint for each action defined in your implementations.

Creating an Event-Driven Automation Plugin [#creating-an-event-driven-automation-plugin]

Automation Plugin implementations can be configured to execute in response to events that occur within the Socotra Insurance Suite. Only one implementation can be configured as event-driven.

To designate an implementation as event-driven, add the following field to your Automation Plugin configuration.

For example:

```json
{
	"enableWebhooks": true
}
```

Execute the `refreshReferenceDatamodel` Gradle task to update the interface for your implementation.

Override the `handleWebhookEvent` method in your implementation.

For example:

```java
@Override
 public void handleWebhookEvent() {
     PluginExecutionContext context = PluginExecutionContext.get();
     AutomationPluginContextData automationContext = context.getAutomationPluginContext().orElseThrow();
     log.info("In AttachDocumentAutomationPluginImpl.handleWebhookEvent()");
     log.info("context: {} {} {} {}", context.getRequestId(), context.getTenantLocator(), context.getBusinessAccount(), automationContext.secret());
     log.info("context: {}", automationContext.eventData());
 }
```

Event-driven actions cannot have request and response objects. Context data can be retrieved from the `PluginExecutionContext` and `AutomationPluginContextData` classes.

Lastly, call the <ApiLink name="createWebhook">Create Webhook</ApiLink> API endpoint to create a webhook for your event-driven action. The `useAutomationPlugin` flag must be set to `true`.

Here's an example request:

```java
{
    "name": "Attach Document Webhook",
    "useAutomationPlugin": true,
    "enabled": true,
    "eventTypes": [
        "policy.account.create",
        "policy.account.update",
        "policy.account.validate",
        "policy.quote.create",
        "policy.quote.update",
        "policy.quote.validate",
        "policy.quote.price",
        "policy.quote.underwrite",
        "policy.quote.accept",
        "policy.quote.refuse",
        "policy.quote.discard",
        "policy.quote.manualunderwrite",
        "policy.quote.reset",
        "policy.quote.issue"
    ],
    "failureHandling": {
        "removeAlertEndpoint": false,
        "alertEndpoint": {
            "url": "https://webhook.develop.socotra.com/cf276a2e-f48d-449d-9279-a1faf24ba51a",
            "headers": {
                "single": 0
            }
        },
        "triggers": [
            "4xx",
            "5xx",
            "timeout"
        ],
        "retryStrategy": {
            "type": "linear",
            "interval": 1000,
            "attempts": 3
        },
        "divert": false,
        "suspend": false
    }
}
```

Unlike a regular webhook, this webhook does not send a request to an external API endpoint. It executes the `handleWebhookEvent` action instead.

Executing the Automation Plugin [#executing-the-automation-plugin]

After deploying your implementations, execute your Automation Plugin actions by sending a `GET` or `POST` request to the API endpoints generated using the following naming convention: `plugin/{tenantLocator}/automation/{pluginName}/{actionName}`.

In general, it doesn't matter whether you send a `GET` request or a `POST` request. The only difference between these request methods is that `GET` requests require a response object to be defined.

Here's an example of a JSON request object for the `attachReport` action:

```json
{
	"reportType": "Regulatory",
	"reportName": "GDPR Compliance"
}
```

Configuring Secrets [#configuring-secrets]

By default, the token that was used to authenticate a request sent to an Automation Plugin API endpoint will be available in the `accessToken` field within the `AutomationPluginContextData` class.

Additional secrets can be included in the `AutomationPluginContextData` class by adding the following field to the top level of an Automation Plugin configuration:

```json
{
	"secret": "ExternalService"
}
```

In the example above, `ExternalService` refers to the name of a `SecretRef` object that must be specified in the tenant <ApiLink name="ConfigurationRef">configuration</ApiLink>. Each Automation Plugin configuration can specify a distinct `SecretRef` object or the same `SecretRef` object if necessary.

Here's an example of a `SecretRef` object:

```json
{
	"items": {
		"url": {
			"dataType": "string"
		},
		"apiToken": {
			"dataType": "string"
		},
		"timeOutSeconds": {
			"dataType": "int"
		}
	}
}
```

Execute the `refreshReferenceDatamodel` Gradle task to generate the Java class containing your secrets.

The `url`, `apiToken`, and `timeOutSeconds` fields can now be accessed through the `AutomationPluginContextData` class.

For example:

```java
PluginExecutionContext context = PluginExecutionContext.get();
        AutomationPluginContextData automationContext = context.getAutomationPluginContext().orElseThrow();

var mapper = AbstractDeploymentFactory.defaultMapper();
ExternalService externalService = mapper.convertValue(automationContext.secret().get(), ExternalService.class);
```

The values for these fields can be set using the [Secrets API](/api/resources/secrets).

Error Handling [#error-handling]

By default, if an exception is encountered while executing an Automation Plugin implementation, an HTTP status code of `500` will be returned. You can return specific HTTP status codes and error messages by throwing an `AutomationPluginException`:

```java
throw new AutomationPluginException(500, "Error Message");
```

Refer to the Webhooks guide for information on defining error-handling strategies for webhooks.

Logging [#logging]

The Logging API can be used to view the history of Automation Plugin executions. For executions triggered via API requests, the `pluginType` will be displayed as `automationHttp`. For executions triggered via webhooks, the `pluginType` will be displayed as `automationWebhook`.

See Also [#see-also]

* [Automation Plugin API](/api/configuration-and-development/automation-plugin)
* [Plugins](/configuration/plugins/overview)
* [Configuration SDK](/configuration/general-topics/configuration-sdk)
* [Webhooks](/configuration/general-topics/webhooks)
* [Logging API](/api/configuration-and-development/logging)
