Actions

Your Connector's Actions are the operations Consumers' Automations can perform in the Connector's App when an event occurs in another App. For example, you may want to update a record in your app each time one of your users adds a lead to their CRM (like Hubspot or Salesforce).

Directory Structure#

Actions live in the actions subdirectory of a given Connector. The actions subdirectory of the example my-app Connector in the Rollout Project Template looks like this:

├── index.ts
└── my-action
├── action.ts
├── input.ts
└── ui.tsx

Actions are exported from the index.ts file:

import { action as myAction } from "./my-action/action";
export const actions = {
["my-action"]: myAction,
};

The property names of the exported actions object (in this case, just one: "my-action") are the actionKeys used to identify the Connector's Actions.

The directory name for each Action must match its actionKey.

For each Action exported by the Connector, you define:

  1. The schema for the Action's inputs in the input.ts file
  2. The UI displayed to users to allow them to provide action inputs in the ui.tsx file
  3. The logic your Action uses to perform its operation in the action.ts file

Defining Inputs#

Action Inputs are defined using the defineActionInputParamsSchema function provided by the Rollout Framework. You can specify the type of an input, whether or not it is required, and provide helper text to the user to explain a given input's purpose.

Example Input Definition:

import { defineActionInputParamsSchema } from "@rollout/framework";
export const inputParamsSchema = defineActionInputParamsSchema((t) => ({
// Optional string input.
// Title `Task Type` will be automatically inferred by title-casing the key.
taskType: t.optional(t.string()),
// Required string input with custom title and description
taskName: t.string({ title: "Name" description: "The name of the task created" }),
}));

Creating the UI#

An Action's UI is defined by a call to to the defineUIComponent function in the ui.tsx file. You can leverage the Rollout Input Components to enable users to provide values for Action Inputs. The defineUIComponent function will receive a prop called b which contains references to the Actions's inputParams. Input components have a bind prop, to which a reference to the relevant input param should be passed.

Here is a simple example UI for an Action with a single string input called name:

import React from "react";
import { defineUIComponent, RichTextInput } from "@rollout/framework/ui";
import type { inputParamsSchema } from "./input";
export const UI = defineUIComponent<typeof inputParamsSchema>((props) => {
const { b } = props;
return (
<>
<RichTextInput bind={b.name} />
</>
);
});

Action Execution Logic#

The logic for performing your Action's operation lives in the action.ts file. See the defineAction function for more details.

This is an example action that takes an inputParam called "message" and makes a POST request to a hello-world endpoint:

export const action = defineAction<MyAppCredential>()({
name: "My Action",
inputParamsSchema,
async execute({ credential, resolvedInputParams }) {
const { accessToken } = credential;
const { message } = resolvedInputParams;
const baseUrl = process.env.BASE_URL;
const res = await fetch(`${BASE_URL}/hello-world`, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ message }),
});
if (res.status !== 200) {
throw new Error(`Action failed. Response status: ${res.status}`);
}
return await res.json();
},
});