1. Triggers
  2. Custom event triggers

Send an event and any workflows that subscribe to that custom event will get triggered.

Name and Schemas

Name

Custom event triggers have a name. They will only get triggered when a custom event with that name are sent.

Schema

Custom event triggers take a Zod schema. This is used to validate the data that is sent with the event. If the data does not match the schema, the workflow will not run.

It also means that inside your run function the event param will be typed correctly. We use Zod for our schemas – it’s a fantastic library that allows you to define schemas in a very simple way.

You can always start out by using z.any() as your schema, and then later on you can add more strict validation. See our Zod guide for more information.

Filters

You can also add filters to your custom event triggers. This allows you to filter out events that you don’t want to run your workflow for.

new Trigger({
  id: "new-user-slack",
  name: "New user slack message",
  on: customEvent({
    name: "user.created",
    schema: z.object({
      name: z.string(),
      email: z.string(),
      paidPlan: z.boolean(),
    }),
    filter: {
      //only run the workflow if the user is paying
      paidPlan: [true],
    },
  }),
  //this function is run when the custom event is received
  run: async (event, ctx) => {
    //send a message to the #new-users Slack channel with user details
    const response = await slack.postMessage("send-to-slack", {
      channel: "new-users",
      text: `New user: ${event.name} (${event.email}) signed up. ${
        event.paidPlan ? "They are paying" : "They are on the free plan"
      }.`,
    });

    return response.message;
  },
}).listen();

Please see the Event filters guide for more information.

Example

import { Trigger, customEvent } from "@trigger.dev/sdk";
import * as slack from "@trigger.dev/slack";
import { z } from "zod";

//this workflow will run when a "user.created" event is sent
new Trigger({
  id: "new-user-slack",
  name: "New user slack message",
  apiKey: "<your_api_key>",
  //this is the custom event subscription
  on: customEvent({
    name: "user.created",
    schema: z.object({
      name: z.string(),
      email: z.string(),
      paidPlan: z.boolean(),
    }),
  }),
  //this function is run when the custom event is received
  run: async (event, ctx) => {
    //send a message to the #new-users Slack channel with user details
    const response = await slack.postMessage("send-to-slack", {
      channel: "new-users",
      text: `New user: ${event.name} (${event.email}) signed up. ${
        event.paidPlan ? "They are paying" : "They are on the free plan"
      }.`,
    });

    return response.message;
  },
}).listen();

That workflow will never run, unless an event is sent from your code somewhere – it can be sent from a completely different server.

Sending an event

There is a full guide on sending events but here is a quick example:

import { sendEvent } from "@trigger.dev/sdk";
import { randomUUID } from "node:crypto";

// send an event with the name "user.created"
// The first param should be a unique ID for this event
await sendEvent(randomUUID(), {
  name: "user.created",
  payload: { name: "John Doe", email: "john@doe.com", paidPlan: true },
});

If you are calling this from inside a workflow, ensure that the first parameter is unique inside your workflow.

You can subscribe to the same event from multiple different workflows. This is useful if you want to send an event to multiple different services or if you want to keep each workflow small and simple.