Triggers

A Connector's Triggers define the types of events that occur in the Connector's App that can start your Consumers' Automations. For example, you may want to enable users to send data to their CRM (like Hubspot or Salesforce) each time a form is submitted in the App.

Directory Structure#

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

├── index.ts
├── my-polling-trigger
│ ├── input.ts
│ ├── payload.ts
│ ├── trigger.ts
│ └── ui.tsx
└── my-push-trigger
├── input.ts
├── payload.ts
├── trigger.ts
└── ui.tsx

Triggers are exported from the index.ts file:

import { trigger as myPollingTrigger } from "./my-polling-trigger/trigger";
import { trigger as myPushTrigger } from "./my-push-trigger/trigger";
export const triggers = {
["my-polling-trigger"]: myPollingTrigger,
["my-push-trigger"]: myPushTrigger,
};

The property names of the exported triggers object (i.e. "my-polling-trigger", "my-push-trigger") are the triggerKeys used to identify the Connector's Triggers.

The directory name for each Trigger must match its triggerKey

Defining Triggers#

Triggers are defined by making a call to one of three Trigger definition functions, each corresponding to one of the Trigger types that Rollout supports (see the next section for details).

Each of the following is passed as a property of an object which is the parameter to the relevant trigger definition function:

  1. A schema for the Trigger's inputs
  2. A schema for the Trigger's payload
  3. (For Triggers other than Polling Triggers) The logic your Trigger will use to discover events (e.g. subscribing to webhooks or polling your API). The required business logic function(s) differ by Trigger type.

Here's an example of how the my-push-trigger Trigger might be defined:

import { definePushTrigger } from "@rollout/framework";
import { inputParamsSchema } from "./input";
import { payloadSchema } from "./payload";
import { MyAppCredential } from "../../auth";
export const trigger = definePushTrigger<MyAppCredential>()({
name: "My Push Trigger",
inputParamsSchema,
payloadSchema,
// Push triggers don't require any particular business logic, but other Trigger types will require the definition of certain functions.
});

Triggers can optionally have a ui.tsx file, which defines a React component that is displayed to the user in order to enable them to configure the Trigger.

Types of Triggers#

There are three types of Triggers that you can build with Rollout:

  1. Push Triggers: Push Triggers allow Apps to send events directly to Rollout, typically through HTTP requests. Push triggers are the most flexible option and are the recommended way to build Triggers for partners who do not have a pre-existing webhook infrastructure. You can learn more about building Push Triggers here.
  2. Webhook Triggers: Webhooks are automated notifications dispatched by applications when specific events occur. If the App you are building a Connector for supports webhooks, you can leverage them when building your Triggers. You can learn more about building Webhook Triggers here.
  3. Polling Triggers: Polling Triggers are scheduled jobs that run at a given interval (configurable by environment variable for a given Project Environment) and make requests against an App's API to determine whether any new events have occurred (e.g. any new items in a list). You can learn more about building Polling Triggers here.

Defining Inputs#

A Trigger's inputParams are defined using the defineTriggerInputParamsSchema 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 { defineTriggerInputParamsSchema } from "@rollout/framework";
// To be passed as a property of the trigger definition function's param
export const inputParamsSchema = defineTriggerInputParamsSchema((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" }),
}));

Building the UI#

A Trigger'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 Trigger Inputs. The defineUIComponent function will receive a prop called b which contains references to the Trigger'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 a Trigger 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} />
</>
);
});

Defining the Payload Schema#

A Trigger's payload is the data that is contained in each Trigger Event. In order to allow users to map data from your Trigger to their Automations' Actions, it is necessary to specify the schema of the Trigger's payload.

Trigger payload schemas can be either static or dynamic. Static schemas are useful for cases when the payload body will always be exactly the same, whereas dynamic schemas are useful for cases when the payload might vary. For example, a dynamic schema would be required for a Trigger that corresponds to form submission if the user is able to customize the fields in the form.

Static Payload Definition#

The defineTriggerPayloadSchema function can be used to define a static schema. It has a single parameter, which is a function that in turn accepts a parameter called t. The t param can be used to describe the type of each field in the payload.

The return value should be passed as the payloadSchema param of the relevant trigger definition function.

Example Static Schema Definition:

import { defineTriggerPayloadSchema } from "@rollout/framework";
// To be imported and passed as a property of the trigger definition functions's param.
export const payloadSchema = defineTriggerPayloadSchema((t) => ({
id: t.string(),
name: t.string(),
}));

Dynamic Payload Definition#

An async function can be passed as a trigger definition function's payloadSchema param. This function should take an object with credential (see Auth) and t properties as a parameter and return a schema definition.

Example Dynamic Payload Schema Definition:

export const trigger = definePushTrigger<MyAppCredential>()({
name: "Dynamic Payload Schema Example",
inputParamsSchema,
payloadSchema: async ({ credential, t }) {
const fieldsRes = await fetch("https://api.example.com/fields", { method: "GET", headers: { Authorization: `Bearer: ${credential.accessToken}` } });
const fields = await fieldsRes.json().data;
const getSchemaTypeForField = (fieldType: string) => {
if (fieldType === "number") {
return t.number();
}
return t.string();
}
return Object.fromEntries((fields.map((f) => ([f.id, getSchemaTypeForField(f.type)]))));
}
});