Added lastRunAt to the scheduleEvent payload
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@trigger.dev/sdk": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Added lastRunAt to the scheduleEvent payload
|
||||||
+14
-5
@@ -39,7 +39,11 @@
|
|||||||
"navigation": [
|
"navigation": [
|
||||||
{
|
{
|
||||||
"group": "Getting Started",
|
"group": "Getting Started",
|
||||||
"pages": ["welcome", "getting-started", "get-help"]
|
"pages": [
|
||||||
|
"welcome",
|
||||||
|
"getting-started",
|
||||||
|
"get-help"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Examples",
|
"group": "Examples",
|
||||||
@@ -67,11 +71,15 @@
|
|||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
"group": "Slack",
|
"group": "Slack",
|
||||||
"pages": ["integrations/apis/slack/actions/post-message"]
|
"pages": [
|
||||||
|
"integrations/apis/slack/actions/post-message"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Resend.com",
|
"group": "Resend.com",
|
||||||
"pages": ["integrations/apis/resend/actions/send-email"]
|
"pages": [
|
||||||
|
"integrations/apis/resend/actions/send-email"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -102,7 +110,8 @@
|
|||||||
"pages": [
|
"pages": [
|
||||||
"reference/trigger",
|
"reference/trigger",
|
||||||
"reference/custom-event",
|
"reference/custom-event",
|
||||||
"reference/webhook-event"
|
"reference/webhook-event",
|
||||||
|
"reference/schedule-event"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -128,4 +137,4 @@
|
|||||||
"github": "https://github.com/triggerdotdev/trigger.dev",
|
"github": "https://github.com/triggerdotdev/trigger.dev",
|
||||||
"discord": "https://discord.gg/nkqV9xBYWy"
|
"discord": "https://discord.gg/nkqV9xBYWy"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,8 @@ description: "Trigger a workflow when a custom event is received."
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { customEvent, Trigger } from "@trigger.dev/sdk";
|
||||||
|
|
||||||
new Trigger({
|
new Trigger({
|
||||||
id: "user-created-notify-slack",
|
id: "user-created-notify-slack",
|
||||||
name: "User Created - Notify Slack",
|
name: "User Created - Notify Slack",
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -9,6 +9,8 @@ description: "The Trigger class let's you define a workflow that is triggered by
|
|||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { customEvent, Trigger } from "@trigger.dev/sdk";
|
||||||
|
|
||||||
const trigger = new Trigger({
|
const trigger = new Trigger({
|
||||||
id: "user-created-notify-slack",
|
id: "user-created-notify-slack",
|
||||||
name: "User Created - Notify Slack",
|
name: "User Created - Notify Slack",
|
||||||
@@ -39,11 +41,6 @@ const trigger = new Trigger({
|
|||||||
`TRIGGER_API_KEY` environment variable.
|
`TRIGGER_API_KEY` environment variable.
|
||||||
</ParamField>
|
</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}>
|
<ParamField path="endpoint" type="string" required={false}>
|
||||||
The URL of the Trigger.dev WebSocket server. If not provided, the endpoint
|
The URL of the Trigger.dev WebSocket server. If not provided, the endpoint
|
||||||
will point to the production server.
|
will point to the production server.
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ description: "Trigger a workflow when a webhook event is received"
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { webhookEvent, Trigger } from "@trigger.dev/sdk";
|
||||||
|
|
||||||
new Trigger({
|
new Trigger({
|
||||||
id: "caldotcom-to-slack",
|
id: "caldotcom-to-slack",
|
||||||
name: "Cal.com To Slack",
|
name: "Cal.com To Slack",
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ sidebarTitle: "Scheduled"
|
|||||||
description: "Run a workflow on a recurring schedule"
|
description: "Run a workflow on a recurring schedule"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
See the [reference](/reference/schedule-event) for more details.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
### Every 5 minutes
|
### Every 5 minutes
|
||||||
@@ -51,3 +53,33 @@ new Trigger({
|
|||||||
},
|
},
|
||||||
}).listen();
|
}).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>
|
||||||
|
|||||||
@@ -29,7 +29,13 @@ export class ScheduleNextEvent {
|
|||||||
|
|
||||||
const messageId = await taskQueue.publish(
|
const messageId = await taskQueue.publish(
|
||||||
"DELIVER_SCHEDULED_EVENT",
|
"DELIVER_SCHEDULED_EVENT",
|
||||||
{ externalSourceId: schedulerSource.id, payload: { scheduledTime } },
|
{
|
||||||
|
externalSourceId: schedulerSource.id,
|
||||||
|
payload: {
|
||||||
|
scheduledTime,
|
||||||
|
lastRunAt: fromEvent ? fromEvent.createdAt : undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
{},
|
{},
|
||||||
{ deliverAt: scheduledTime.getTime() }
|
{ deliverAt: scheduledTime.getTime() }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,19 +5,20 @@ import { prisma } from "~/db.server";
|
|||||||
export const uptimeCheck = new Trigger({
|
export const uptimeCheck = new Trigger({
|
||||||
id: "uptime-check",
|
id: "uptime-check",
|
||||||
name: "Uptime Check",
|
name: "Uptime Check",
|
||||||
on: scheduleEvent({ rateOf: { minutes: 1 } }),
|
on: scheduleEvent({ rateOf: { minutes: 5 } }),
|
||||||
triggerTTL: 300,
|
logLevel: "info",
|
||||||
|
triggerTTL: 60,
|
||||||
run: async (event, context) => {
|
run: async (event, context) => {
|
||||||
|
if (context.environment === "development" && !context.isTest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Grab counts of workflows, runs, and steps
|
// Grab counts of workflows, runs, and steps
|
||||||
const userCount = await prisma.user.count();
|
const userCount = await prisma.user.count();
|
||||||
const workflowCount = await prisma.workflow.count();
|
const workflowCount = await prisma.workflow.count();
|
||||||
const runCount = await prisma.workflowRun.count();
|
const runCount = await prisma.workflowRun.count();
|
||||||
const stepCount = await prisma.workflowRunStep.count();
|
const stepCount = await prisma.workflowRunStep.count();
|
||||||
|
|
||||||
if (context.environment === "development") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await slack.postMessage("Uptime Notification", {
|
await slack.postMessage("Uptime Notification", {
|
||||||
channelName: "monitoring",
|
channelName: "monitoring",
|
||||||
text: `[${context.environment}] Uptime Check: ${userCount} users, ${workflowCount} workflows, ${runCount} runs, ${stepCount} steps.`,
|
text: `[${context.environment}] Uptime Check: ${userCount} users, ${workflowCount} workflows, ${runCount} runs, ${stepCount} steps.`,
|
||||||
|
|||||||
@@ -2,20 +2,21 @@ import { Trigger, scheduleEvent } from "@trigger.dev/sdk";
|
|||||||
import { slack } from "@trigger.dev/integrations";
|
import { slack } from "@trigger.dev/integrations";
|
||||||
|
|
||||||
const trigger = new Trigger({
|
const trigger = new Trigger({
|
||||||
id: "schedule-to-slack",
|
id: "schedule-to-slack-2",
|
||||||
name: "Send to Slack every minute",
|
name: "Send to Slack every minute",
|
||||||
apiKey: "trigger_development_vzNnO2DGBGcG",
|
apiKey: "trigger_dev_zC25mKNn6c0q",
|
||||||
|
endpoint: "ws://localhost:8889/ws",
|
||||||
logLevel: "debug",
|
logLevel: "debug",
|
||||||
on: scheduleEvent({ rateOf: { minutes: 1 } }),
|
on: scheduleEvent({ rateOf: { minutes: 1 } }),
|
||||||
run: async (event, ctx) => {
|
run: async (event, ctx) => {
|
||||||
await ctx.logger.info("It's me, the annoying slack bot!");
|
await ctx.logger.info("It's me, the annoying slack bot!");
|
||||||
|
|
||||||
const response = await slack.postMessage("slaaaaaack", {
|
// const response = await slack.postMessage("slaaaaaack", {
|
||||||
channel: "test-integrations",
|
// channelName: "test-integrations",
|
||||||
text: `Hello, the time is ${event.scheduledTime}`,
|
// text: `Hello, the time is ${event.scheduledTime}, and I was last run at ${event.lastRunAt}!`,
|
||||||
});
|
// });
|
||||||
|
|
||||||
return response.message;
|
return event;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export const EventFilterSchema: z.ZodType<EventFilter> = z.lazy(() =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const ScheduledEventPayloadSchema = z.object({
|
export const ScheduledEventPayloadSchema = z.object({
|
||||||
|
lastRunAt: z.coerce.date().optional(),
|
||||||
scheduledTime: z.coerce.date(),
|
scheduledTime: z.coerce.date(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user