Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions apps/docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@
"navigation": [
{
"group": "Getting Started",
"pages": ["welcome", "getting-started", "get-help"]
"pages": [
"welcome",
"getting-started",
"get-help"
]
},
{
"group": "Examples",
Expand Down Expand Up @@ -67,11 +71,15 @@
"pages": [
{
"group": "Slack",
"pages": ["integrations/apis/slack/actions/post-message"]
"pages": [
"integrations/apis/slack/actions/post-message"
]
},
{
"group": "Resend.com",
"pages": ["integrations/apis/resend/actions/send-email"]
"pages": [
"integrations/apis/resend/actions/send-email"
]
}
]
},
Expand Down Expand Up @@ -102,7 +110,8 @@
"pages": [
"reference/trigger",
"reference/custom-event",
"reference/webhook-event"
"reference/webhook-event",
"reference/schedule-event"
]
},
{
Expand All @@ -128,4 +137,4 @@
"github": "https://github.com/triggerdotdev/trigger.dev",
"discord": "https://discord.gg/nkqV9xBYWy"
}
}
}
36 changes: 36 additions & 0 deletions apps/docs/openapi-spec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
openapi: 3.0.3
info:
title: Trigger.dev API
version: v1.0.0
description: Please see https://docs.trigger.dev for more details.
contact:
name: Eric
email: eric@trigger.dev
url: https://trigger.dev
termsOfService: https://trigger.dev/terms
servers:
- url: https://app.trigger.dev/api/v1
description: Trigger.dev
paths:
/events:
post:
summary: Send Custom Event
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/customEvent"
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/customEventResponse"
"422":
description: Unprocessable Entity
content:
application/json:
schema:
$ref: "#/components/schemas/error"
2 changes: 2 additions & 0 deletions apps/docs/reference/custom-event.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ description: "Trigger a workflow when a custom event is received."
## Usage

```ts
import { customEvent, Trigger } from "@trigger.dev/sdk";

new Trigger({
id: "user-created-notify-slack",
name: "User Created - Notify Slack",
Expand Down
68 changes: 68 additions & 0 deletions apps/docs/reference/schedule-event.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: "scheduleEvent Trigger"
sidebarTitle: "scheduleEvent"
description: "Run a workflow on a recurring schedule."
---

## Usage

```ts
import { scheduleEvent } from "@trigger.dev/sdk";

new Trigger({
id: "usage",
name: "usage",
on: scheduleEvent({ rateof: { minutes: 10 } }),
run: async (event, ctx) => {},
}).listen();
```

## Options

You must use one of the following options, but not both:

<ParamField path="rateOf" type="object" required={false}>
The rate of the schedule. This can be a number of minutes, hours,
or days. For example, `{ rateOf: { minutes: 10 } }` will run
every 10 minutes.
</ParamField>

<ParamField path="cron" type="string" required={false}>
A cron expression to run the workflow on. For example, `0 0 * * *` will run
the workflow every hour at the top of the hour. See
[crontab.guru](https://crontab.guru/) for more information.
</ParamField>

## Event Payload

<ResponseField name="scheduledTime" type="Date" required={true}>
The time the event was scheduled to run.
</ResponseField>

<ResponseField name="lastRunAt" type="Date" required={false}>
The time the event last run. This will be `undefined` if the event has never run. Use this parameter to run window queries:

```ts
import { scheduleEvent, Trigger } from "@trigger.dev/sdk";

new Trigger({
id: "usage",
name: "usage",
on: scheduleEvent({ rateof: { minutes: 10 } }),
run: async (event, ctx) => {
const { lastRunAt, scheduledTime } = event;

const query = `SELECT * FROM users WHERE created_at < ${scheduledTime}`;

if (lastRunAt) {
query += ` AND created_at > ${lastRunAt}`;
}

const latestUsers = await db.query(query);

// ...
},
}).listen();
```

</ResponseField>
11 changes: 6 additions & 5 deletions apps/docs/reference/trigger.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ description: "The Trigger class let's you define a workflow that is triggered by
### Usage

```ts
import { customEvent, Trigger } from "@trigger.dev/sdk";

const trigger = new Trigger({
id: "user-created-notify-slack",
name: "User Created - Notify Slack",
Expand Down Expand Up @@ -39,11 +41,6 @@ const trigger = new Trigger({
`TRIGGER_API_KEY` environment variable.
</ParamField>

<ParamField path="apiKey" type="string" required={false}>
Your Trigger.dev API key. If not provided, the API key will be read from the
`TRIGGER_API_KEY` environment variable.
</ParamField>

<ParamField path="endpoint" type="string" required={false}>
The URL of the Trigger.dev WebSocket server. If not provided, the endpoint
will point to the production server.
Expand Down Expand Up @@ -87,6 +84,10 @@ const trigger = new Trigger({
for more info.
</ParamField>

<ParamField path="isTest" type="boolean">
Whether or not this trigger is being run as a test.
</ParamField>

<ParamField path="sendEvent" type="function">
A function that can be used to send an event to trigger.dev. See the [Sending
Events](/functions/send-event) page for more info.
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/reference/webhook-event.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ description: "Trigger a workflow when a webhook event is received"
## Usage

```ts
import { webhookEvent, Trigger } from "@trigger.dev/sdk";

new Trigger({
id: "caldotcom-to-slack",
name: "Cal.com To Slack",
Expand Down
32 changes: 32 additions & 0 deletions apps/docs/triggers/scheduled.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ sidebarTitle: "Scheduled"
description: "Run a workflow on a recurring schedule"
---

See the [reference](/reference/schedule-event) for more details.

## Examples

### Every 5 minutes
Expand Down Expand Up @@ -51,3 +53,33 @@ new Trigger({
},
}).listen();
```

## Preventing late runs

To prevent a scheduled trigger from running late, you can set a `triggerTTL` option when creating the `Trigger`, like so:

```ts
new Trigger({
id: "scheduled-workflow",
name: "Scheduled Workflow",
apiKey: "<your_api_key>",
on: scheduleEvent({ rateOf: { minutes: 5 } }),
triggerTTL: 300,
run: async (event, ctx) => {
await ctx.logger.info("Received the scheduled event", {
event,
wallTime: new Date(),
});

return { foo: "bar" };
},
}).listen();
```

This will prevent the trigger from running if it is running more than `300` seconds behind, which can happen if the server running your `Trigger` code goes down or is otherwise unavailable.

This is especially useful for scheduled triggers that run on a very short interval, like every minute, so you don't get a backlog of runs that all run at once when the server comes back online.

<Tip>
Set your `triggerTTL` to the same time (or double) as the rateOf the trigger.
</Tip>
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ export class RegisterExternalSource {
}

if (externalSource.status === "READY") {
await this.#prismaClient.workflow.updateMany({
where: {
externalSourceId: externalSource.id,
},
data: {
status: "READY",
},
});

return true;
}

Expand Down
1 change: 1 addition & 0 deletions apps/webapp/app/services/messageBroker.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@ function createTaskQueue() {
"x-env": run.environment.slug,
"x-workflow-run-id": run.id,
"x-ttl": run.workflow.triggerTtlInSeconds,
"x-is-test": run.isTest ? "true" : "false",
},
{
eventTimestamp: run.event.timestamp.getTime(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ export class ScheduleNextEvent {

const messageId = await taskQueue.publish(
"DELIVER_SCHEDULED_EVENT",
{ externalSourceId: schedulerSource.id, payload: { scheduledTime } },
{
externalSourceId: schedulerSource.id,
payload: {
scheduledTime,
lastRunAt: fromEvent ? fromEvent.createdAt : undefined,
},
},
{},
{ deliverAt: scheduledTime.getTime() }
);
Expand Down
13 changes: 7 additions & 6 deletions apps/webapp/app/triggers/monitoring.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ import { prisma } from "~/db.server";
export const uptimeCheck = new Trigger({
id: "uptime-check",
name: "Uptime Check",
on: scheduleEvent({ rateOf: { minutes: 1 } }),
triggerTTL: 300,
on: scheduleEvent({ rateOf: { minutes: 5 } }),
logLevel: "info",
triggerTTL: 60,
run: async (event, context) => {
if (context.environment === "development" && !context.isTest) {
return;
}

// Grab counts of workflows, runs, and steps
const userCount = await prisma.user.count();
const workflowCount = await prisma.workflow.count();
const runCount = await prisma.workflowRun.count();
const stepCount = await prisma.workflowRunStep.count();

if (context.environment === "development") {
return;
}

await slack.postMessage("Uptime Notification", {
channelName: "monitoring",
text: `[${context.environment}] Uptime Check: ${userCount} users, ${workflowCount} workflows, ${runCount} runs, ${stepCount} steps.`,
Expand Down
2 changes: 2 additions & 0 deletions apps/wss/src/runController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type WorkflowRunControllerOptions = {
environment: string;
apiKey: string;
organizationId: string;
isTest: boolean;
};
};

Expand All @@ -37,6 +38,7 @@ export class WorkflowRunController {
environment: string;
apiKey: string;
organizationId: string;
isTest: boolean;
};

#logger: Logger;
Expand Down
Loading