Adding docs back into this repo
@@ -0,0 +1 @@
|
||||
.DS_Store
|
||||
@@ -0,0 +1,14 @@
|
||||
# Development
|
||||
|
||||
## Install and initial setup
|
||||
|
||||
`npm install`
|
||||
|
||||
## Running the app
|
||||
|
||||
`npm run dev`
|
||||
|
||||
## View the app locally
|
||||
|
||||
It runs locally here:
|
||||
`http://localhost:3050`
|
||||
@@ -0,0 +1,18 @@
|
||||
```typescript Wait example
|
||||
new Job(client, {
|
||||
id: "delay-job",
|
||||
name: "Delay Job",
|
||||
version: "0.0.1",
|
||||
trigger: eventTrigger({
|
||||
name: "example.event",
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
await io.logger.info("Hi");
|
||||
|
||||
// the second parameter is the number of seconds to wait
|
||||
await io.wait("wait 30 days", 30 * 24 * 60 * 60);
|
||||
|
||||
await io.logger.info("Sorry for the slow reply!");
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
```typescript
|
||||
new Job(client, {
|
||||
//... other options
|
||||
integrations: {
|
||||
slack,
|
||||
gh: github,
|
||||
},
|
||||
run: async (payload, io, ctx) => {
|
||||
//slack is available on io.slack
|
||||
io.slack.postMessage(...);
|
||||
//github is available on io.gh
|
||||
io.gh.addIssueLabels(...);
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
## Getting started
|
||||
|
||||
If you have not yet set up Trigger.dev in your Next.js project, go to the [quick start guide](/documentation/quickstart).
|
||||
@@ -0,0 +1,6 @@
|
||||

|
||||
|
||||
The "Integrations" page shows
|
||||
|
||||
1. Some of the APIs that you can use with Trigger.dev (you can use any API). Selecting one of these will give you instructions on how to use it.
|
||||
2. Your connected integrations. Clicking these will give you more details on that connection.
|
||||
@@ -0,0 +1,6 @@
|
||||
<Warning>
|
||||
Scheduled Triggers **do not** trigger Jobs in the DEV
|
||||
[Environment](/documentation/concepts/environments-endpoints). When you're
|
||||
working locally you should use [the Test
|
||||
feature](/documentation/guides/testing-jobs) to trigger any scheduled Jobs.
|
||||
</Warning>
|
||||
@@ -0,0 +1,4 @@
|
||||
There are two way to send an event that will trigger `eventTrigger()`:
|
||||
|
||||
1. Use [client.sendEvent()](/sdk/triggerclient/instancemethods/sendevent) from anywhere in your codebase.
|
||||
2. Use [io.sendEvent()](/sdk/io/sendevent) from inside a Job's `run()` function.
|
||||
@@ -0,0 +1,52 @@
|
||||
<ParamField body="event" type="object" required>
|
||||
<Expandable title="properties" defaultOpen>
|
||||
<ParamField body="name" type="string" required>
|
||||
The `name` property must exactly match any subscriptions you want to
|
||||
trigger.
|
||||
</ParamField>
|
||||
<ParamField body="payload" type="any">
|
||||
The `payload` property will be sent to any matching Jobs and will appear
|
||||
as the `payload` param of the `run()` function. You can leave this
|
||||
parameter out if you just want to trigger a Job without any input data.
|
||||
</ParamField>
|
||||
<ParamField body="context" type="any">
|
||||
The optional `context` property will be sent to any matching Jobs and will
|
||||
be passed through as the `context.event.context` param of the `run()`
|
||||
function. This is optional but can be useful if you want to pass through
|
||||
some additional context to the Job.
|
||||
</ParamField>
|
||||
<ParamField body="id" type="string">
|
||||
The `id` property uniquely identify this particular event. If unset it
|
||||
will be set automatically using `ulid`.
|
||||
</ParamField>
|
||||
<ParamField body="timestamp" type="Date">
|
||||
This is optional, it defaults to the current timestamp. Usually you would
|
||||
only set this if you have a timestamp that you wish to pass through, e.g.
|
||||
you receive a timestamp from a service and you want the same timestamp to
|
||||
be used in your Job.
|
||||
</ParamField>
|
||||
<ParamField body="source" type="string">
|
||||
This is optional, it defaults to "trigger.dev". It can be useful to set
|
||||
this as you can filter events using this in the `eventTrigger()`.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="options" type="object">
|
||||
<Expandable title="properties" defaultOpen>
|
||||
<ParamField body="deliverAt" type="Date">
|
||||
An optional Date when you want the event to Trigger Jobs. The event will
|
||||
be sent to the platform immediately but won't be acted upon until the
|
||||
specified time.
|
||||
</ParamField>
|
||||
<ParamField body="deliverAfter" type="number">
|
||||
An optional number of seconds you want to wait for the event to Trigger
|
||||
any relevant Jobs. The event will be sent to the platform immediately but
|
||||
won't be acted upon until the specified time.
|
||||
</ParamField>
|
||||
<ParamField body="accountId" type="string">
|
||||
This optional param will be used by the Trigger.dev Connect feature, which
|
||||
is coming soon.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
@@ -0,0 +1,29 @@
|
||||
<ResponseField type="object">
|
||||
<Expandable title="properties" defaultOpen>
|
||||
<ResponseField name="id" type="string" required>
|
||||
The `id` of the event that was sent.
|
||||
</ResponseField>
|
||||
<ResponseField name="name" type="string" required>
|
||||
The `name` of the event that was sent.
|
||||
</ResponseField>
|
||||
<ResponseField name="payload" type="any" required>
|
||||
The `payload` of the event that was sent
|
||||
</ResponseField>
|
||||
<ResponseField name="timestamp" type="Date" required>
|
||||
The `timestamp` of the event that was sent
|
||||
</ResponseField>
|
||||
<ResponseField name="context" type="any">
|
||||
The `context` of the event that was sent. Is `undefined` if no context was
|
||||
set when sending the event.
|
||||
</ResponseField>
|
||||
<ResponseField name="deliverAt" type="Date">
|
||||
The timestamp when the event will be delivered to any matching Jobs. Is
|
||||
`undefined` if `deliverAt` or `deliverAfter` wasn't set when sending the
|
||||
event.
|
||||
</ResponseField>
|
||||
<ResponseField name="deliveredAt" type="Date">
|
||||
The timestamp when the event was delivered. Is `undefined` if `deliverAt`
|
||||
or `deliverAfter` were set when sending the event.
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
@@ -0,0 +1,4 @@
|
||||
<ResponseField name="key" type="string" required>
|
||||
Should be a stable and unique key inside the `run()`. See
|
||||
[resumability](/documentation/concepts/resumability) for more information.
|
||||
</ResponseField>
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: "Changelog"
|
||||
description: "We release features and fixes weekly! See some of the changes we have made."
|
||||
---
|
||||
|
||||
## June 28 2023 Release
|
||||
|
||||
The first release of Trigger.dev v2, a major overhaul.
|
||||
|
||||
- Works well on serverless and long-running servers
|
||||
- Adaptors for Next.js
|
||||
- Simpler architecture utilizing Postgres
|
||||
- Integrations are now just Node.js packages
|
||||
- New UI
|
||||
- Easy self-hosting
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: "Client & Adaptors"
|
||||
description: "The Client is how you interact with the API, through an Adaptor."
|
||||
---
|
||||
|
||||
## Client
|
||||
|
||||
A Client is used to connect to a specific [Project](/documentation/concepts/projects) by using an [API Key](/documentation/concepts/environments-apikeys).
|
||||
|
||||
Clients are created using the `TriggerClient` class.
|
||||
|
||||
```ts
|
||||
export const client = new TriggerClient({
|
||||
id: "my-webapp",
|
||||
apiKey: process.env.TRIGGER_API_KEY!,
|
||||
});
|
||||
```
|
||||
|
||||
View the [Client API Reference](//sdk/triggerclient) for more information.
|
||||
|
||||
## Adaptors
|
||||
|
||||
Adaptors allows Clients to receive data from the Trigger API. They do this by creating an API endpoint that data can be received at and transforming data into the expected format.
|
||||
|
||||
Each platform has one or more adaptors, see the guides below:
|
||||
|
||||
| Platform | Adaptor |
|
||||
| ------------------------------------------------- | -------------------- |
|
||||
| [Next.js](/documentation/guides/platforms/nextjs) | `createPagesRoute()` |
|
||||
| [Next.js](/documentation/guides/platforms/nextjs) | `createAppRoute()` |
|
||||
| Express | Coming soon |
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: Trigger.dev Connect
|
||||
description: "Authenticate your users with an Integration using Trigger.dev Connect."
|
||||
---
|
||||
|
||||
<Note>Trigger.dev Connect will be released soon, during the beta period</Note>
|
||||
|
||||
## What is it?
|
||||
|
||||
It allows you to easily add Integrations for your users, such as:
|
||||
|
||||
- Add contacts to their Hubspot.
|
||||
- Sync data to their Airtable.
|
||||
- Post videos to their YouTube.
|
||||
- Add issues to their Linear.
|
||||
|
||||
## How does it work?
|
||||
|
||||
1. Create an [Integration in the Dashboard](/documentation/guides/integrations).
|
||||
2. Use our provided React components in your web app to authenticate your users.
|
||||
3. Trigger a Job as one of your users.
|
||||
4. Inside the Run function the relevant Integrations will be authenticated with your user's credentials.
|
||||
5. Profit.
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: Delays
|
||||
description: "Delays can be used to wait for a certain amount of time before continuing a Run."
|
||||
---
|
||||
|
||||
[Runs](/documentation/concepts/runs) can be paused using delays. They can be very long.
|
||||
|
||||
Delays works even if you're on a serverless platform with timeouts, or if your server goes down. They utilize [resumability](/documentation/concepts/resumability) to ensure that the Run can be resumed after the delay.
|
||||
|
||||
## Usage
|
||||
|
||||
<Snippet file="delay-example.mdx" />
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: "Environments & Endpoints"
|
||||
description: "Environments and Endpoints are used to connect your server to the Trigger.dev platform."
|
||||
---
|
||||
|
||||

|
||||
When you login to your Project there's a section called "Environments & API Keys".
|
||||
|
||||
## Environments
|
||||
|
||||
Each environment has an API Key associated with it. This API Key is used to authenticate your Jobs with the Trigger.dev platform.
|
||||
|
||||
The API Key you use for your [Client](/documentation/concepts/client-adaptors) is how we know which environment to run your code against:
|
||||
|
||||
```ts
|
||||
export const client = new TriggerClient({
|
||||
id: "nextjs-example",
|
||||
//this environment variable should be set to your DEV API Key locally,
|
||||
//and your PROD API Key in production
|
||||
apiKey: process.env.TRIGGER_API_KEY!,
|
||||
});
|
||||
```
|
||||
|
||||
### Development
|
||||
|
||||
The `DEV` environment should only be used for local development. It's where you can test your Jobs before deploying them to servers.
|
||||
|
||||
<Snippet file="scheduled-dev-warning.mdx" />
|
||||
|
||||
### Production
|
||||
|
||||
The `PROD` environment is where your Jobs will run in production. It's where you can run your Jobs against real data.
|
||||
|
||||
## Endpoints
|
||||
|
||||
An Endpoint is a URL on your server that Trigger.dev can connect to. This URL is used to register Jobs, start them and orchestrate runs and retries.
|
||||
|
||||
`DEV` has multiple endpoints associated with it – one for each team member. This allows each team member to run their own Jobs, without interfering with each other.
|
||||
|
||||
All other environments have just a single endpoint (with a single URL) associated with them.
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: Integrations
|
||||
description: "Integrations make it easy to use APIs in your Jobs"
|
||||
---
|
||||
|
||||
<Note>
|
||||
You can use any API in your Jobs by using existing Node.js SDKs or HTTP
|
||||
requests. Integrations just make it much easier especially when you want to
|
||||
use OAuth. And you get great logging.
|
||||
</Note>
|
||||
|
||||
An Integration is a package you install that makes it easy to work with a specific API. They:
|
||||
|
||||
- Create a connection to the API (using OAuth, API keys or tokens)
|
||||
- Provide a set of [Tasks](/documentation/concepts/tasks) to work with the API
|
||||
- Provide a set of [Triggers](/documentation/concepts/triggers) to listen for events from the API
|
||||
- Allow you to use the **full underlying authenticated SDK client** directly
|
||||
|
||||
## An example
|
||||
|
||||
This job sends Slack messages when a new GitHub issue is opened on the `triggerdotdev/trigger.dev` repo.
|
||||
|
||||
```ts
|
||||
import { Github } from "@trigger.dev/github";
|
||||
import { Slack } from "@trigger.dev/slack";
|
||||
|
||||
//1. create GitHub client using a token
|
||||
const github = new Github({
|
||||
id: "github",
|
||||
token: process.env.GITHUB_TOKEN!,
|
||||
});
|
||||
|
||||
//2. create Slack client using OAuth
|
||||
const slack = new Slack({
|
||||
id: "slack",
|
||||
});
|
||||
|
||||
new Job(client, {
|
||||
id: "alert-on-new-github-issues",
|
||||
name: "Alert on new GitHub issues",
|
||||
version: "0.1.1",
|
||||
integrations: {
|
||||
//3. include the slack integration
|
||||
slack,
|
||||
},
|
||||
//4. use the github integration to listen for new issues
|
||||
trigger: github.triggers.repo({
|
||||
event: events.onIssueOpened,
|
||||
owner: "triggerdotdev",
|
||||
repo: "trigger.dev",
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
//5. send a message to slack
|
||||
const response = await io.slack.postMessage("Slack alert", {
|
||||
text: `New Issue opened: ${payload.issue.html_url}`,
|
||||
channel: "C04GWBTDQ7W",
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
There are some things worth highlighting here:
|
||||
|
||||
1. Integration clients can use API keys or tokens.
|
||||
2. Integration clients can use OAuth.
|
||||
3. Integrations are added to a Job by adding them to the `integrations`.
|
||||
4. The Job Trigger can use an Integration to listen for events from the API.
|
||||
5. You can use the Integration to make API calls inside the `run` function.
|
||||
|
||||
## Authentication
|
||||
|
||||
### API Keys and Tokens
|
||||
|
||||
You the value in when creating your Integration client. They are never sent from your server by the Trigger.dev service, they are local to your servers. We recommend you use a secure method of storing these values and passing them to your code, like environment variables.
|
||||
|
||||
### OAuth
|
||||
|
||||
You can use the [Integrations Dashboard](/documentation/guides/using-integrations) to setup OAuth for an Integration. We make it easy to use OAuth by dealing with the OAuth flow, token refreshing and storage for you.
|
||||
|
||||
You can use OAuth to authenticate your internal team with an Integration or to allow your users to authenticate with an Integration – we call user authentication [Trigger.dev Connect](/documentation/guides/connect).
|
||||
|
||||
## References
|
||||
|
||||
<CardGroup>
|
||||
<Card
|
||||
title="Integrations Dashboard"
|
||||
icon="sidebar"
|
||||
href="documentation/guides/integrations"
|
||||
>
|
||||
The Integrations Dashboard allows you to manage your Integrations and setup
|
||||
OAuth.
|
||||
</Card>
|
||||
<Card
|
||||
title="Trigger.dev Connect"
|
||||
icon="user-plus"
|
||||
href="/documentation/concepts/connect"
|
||||
>
|
||||
Authenticate your users with an Integration using Trigger.dev Connect.
|
||||
</Card>
|
||||
<Card title="View Integrations" icon="grid-2" href="/integrations">
|
||||
Trigger.dev integrates with a wide range of services.
|
||||
</Card>
|
||||
<Card
|
||||
title="Create an Integration"
|
||||
icon="square-plus"
|
||||
href="/integrations/create"
|
||||
>
|
||||
Create an Integration for your own use or as a public package.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
title: "Jobs"
|
||||
description: "When this happens, do this."
|
||||
---
|
||||
|
||||
> A Job defines what event triggers it and what should happen when it is run.
|
||||
|
||||
For example, you can create a Job that will send an email to a user when they sign up for your app.
|
||||
|
||||
## Anatomy of a Job
|
||||
|
||||
A Job is made up of a few things:
|
||||
|
||||
1. Metadata
|
||||
2. A Trigger (what event should cause this job to run)
|
||||
3. The Run function (what should happen when this job runs)
|
||||
|
||||
```ts
|
||||
//Job definition – uses the client
|
||||
new Job(client, {
|
||||
// 1. Metadata
|
||||
id: "event-1",
|
||||
name: "Run when the foo.bar event happens",
|
||||
version: "0.0.1",
|
||||
// 2. Trigger
|
||||
trigger: eventTrigger({
|
||||
name: "foo.bar",
|
||||
}),
|
||||
// 3. Run function
|
||||
run: async (payload, io, ctx) => {
|
||||
// do something
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Jobs, Triggers, Runs and Tasks
|
||||
|
||||
A more complicated Job
|
||||
|
||||
> When a GitHub issue is modified: If the issue has been labelled "critical" send a Slack message and sync the issue to Linear.
|
||||
|
||||
This can be visualized like this:
|
||||
|
||||

|
||||
|
||||
Events [trigger](/documentation/concepts/triggers) Jobs. Jobs generate a [Run](/documentation/concepts/runs) for every event. A Run is a single execution of a Job. A Run can have multiple [Tasks](/documentation/concepts/tasks) which are the individual steps of a Run.
|
||||
|
||||
## References
|
||||
|
||||
<CardGroup>
|
||||
<Card title="Job SDK reference" icon="wrench" href="/sdk/job">
|
||||
Detailed SDK reference for Jobs.
|
||||
</Card>
|
||||
<Card
|
||||
title="Managing Jobs Dashboard"
|
||||
icon="globe"
|
||||
href="/documentation/guides/managing-jobs"
|
||||
>
|
||||
Viewing and managing your Jobs in the Dashboard.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: "Limitations"
|
||||
---
|
||||
|
||||
There are a few limitations that are important to understand.
|
||||
|
||||
In the current beta:
|
||||
|
||||
- Runs on localhost are limited to 5 minutes.
|
||||
- On long-running servers (not serverless) Runs can be retried erroneously.
|
||||
- Compute intensive jobs are not well supported.
|
||||
|
||||
## Runs on localhost are limited to 5 minutes
|
||||
|
||||
When developing locally the [CLI dev command](/documentation/guides/cli#dev-command) uses [ngrok](https://ngrok.com/) so messages can be sent to your machine.
|
||||
|
||||
Ngrok has a timeout of 5 minutes on a Request/Response cycle. so, if a localhost Run takes longer than 5 minutes to complete, the Run will fail.
|
||||
|
||||
This limitation will be removed in the future by adding an alternative run strategy that works well on localhost and long-running servers. This won't use the request/response cycle.
|
||||
|
||||
## On long-running servers (not serverless) Runs can be retried erroneously
|
||||
|
||||
Currently the only way that Runs are performed is by a Request/Response cycle when `run` is called on a Job. This is optimized for serverless functions (where you have to use a Request/Response cycle), but not for long-running servers.
|
||||
|
||||
This limitation will be removed in the future by adding an alternative mode so Jobs works well on localhost and long-running servers. This won't use the request/response cycle.
|
||||
|
||||
## Compute intensive jobs are not well supported
|
||||
|
||||
Currently the only way that Runs are performed is inside a Request/Response cycle when `run` is called on a Job. This is not a good way to perform compute intensive jobs.
|
||||
|
||||
In the future we will add good support for compute intensive jobs.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "Projects"
|
||||
description: "Projects are a group of [Jobs](/documentation/concepts/jobs-runs-tasks) with [Environments](/documentation/concepts/environments-apikeys)"
|
||||
---
|
||||
|
||||
User's are members of one or more Organizations. Each Organization can have many Projects.
|
||||
|
||||
Jobs are scoped to a specific Project. This means they can only be run in the context of a Project. Jobs are associated with a Project by using a Project API key.
|
||||
|
||||
Currently all members of an Organization have access to all Projects. More granular access control will be added in the future.
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: Resumability
|
||||
description: "Runs are resumable by returning Task stored data"
|
||||
---
|
||||
|
||||
[Runs](/documentation/concepts/runs) can exceed the maximum timeout on serverless platforms and can survive server restarts.
|
||||
|
||||
## How does this work?
|
||||
|
||||
1. When a Run is created, it is given a unique ID. This ID is used to identify the Run.
|
||||
2. [Tasks](/documentation/concepts/tasks) have a `key` which is a string and is the first parameter. This should be stable and unique inside that `run` function.
|
||||
3. When a Task is completed, its output is stored.
|
||||
4. If a Run exceeds the timeout, or your server restarts, the Run will be "replayed".
|
||||
5. The second+ time it is run, Tasks that have already successfully completed will immediately return their first output. The code inside them won't re-run.
|
||||
|
||||
## How to use keys
|
||||
|
||||
Like we mentioned above, we use Task keys to determine which Tasks have already been executed. They are defined by you inside your `run` function, for example when you call `io.slack.postMessage`:
|
||||
|
||||
```ts
|
||||
await io.slack.postMessage("⭐️ New Star", {
|
||||
channel: "C04GWUTDC3W",
|
||||
text: `@${starredBy} just starred ${repoName}!`,
|
||||
});
|
||||
```
|
||||
|
||||
In this example, the key is the string `"⭐️ New Star"`. This means that if the Job is interrupted and then resumed, the `slack.postMessage` Task will be skipped because it has already been executed.
|
||||
|
||||
If you make multiple calls to `slack.postMessage`, you should use different keys for each call. For example:
|
||||
|
||||
```ts
|
||||
await io.slack.postMessage("⭐️ New Star", {
|
||||
channel: "C04GWUTDC3W",
|
||||
text: `@${starredBy} just starred ${repoName}!`,
|
||||
});
|
||||
|
||||
await io.slack.postMessage("🚨 Critical Issue", {
|
||||
channel: "C04GWUTDC3W",
|
||||
text: `@${assignee} just opened a critical issue in ${repoName}!`,
|
||||
});
|
||||
```
|
||||
|
||||
If you are calling a Task multiple times with the same key, it will only be executed once. For example, if you call `slack.postMessage` with the key `"⭐️ New Star"` twice, it will only be executed once.
|
||||
|
||||
## How to use keys with loops
|
||||
|
||||
If you are using a loop, you should use the loop index as the key. For example:
|
||||
|
||||
```ts
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await ctx.waitFor(`Wait ${i}`, { seconds: 30 });
|
||||
|
||||
await slack.postMessage(`⭐️ New Star ${i}`, {
|
||||
channelName: "github-stars",
|
||||
text: `@${starredBy} just starred ${repoName}!`,
|
||||
});
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: "Runs"
|
||||
description: "When a [Job](/documentation/concepts/jobs) is [Triggered](/documentation/concepts/triggers), the Run function is called."
|
||||
---
|
||||
|
||||
> Everytime a Job is triggered, a Run is created with a payload of data.
|
||||
|
||||
## Anatomy of a Run
|
||||
|
||||
A Run is a record of the execution of a Job. It is created from `run()` function of a Job.
|
||||
|
||||
```ts
|
||||
new Job(client, {
|
||||
id: "event-1",
|
||||
name: "Run when the foo.bar event happens",
|
||||
version: "0.0.1",
|
||||
trigger: eventTrigger({
|
||||
name: "foo.bar",
|
||||
schema: z.object({
|
||||
url: z.string(),
|
||||
}),
|
||||
}),
|
||||
// 1. Run function with params
|
||||
run: async (payload, io, ctx) => {
|
||||
// 2. Regular code and Tasks
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
1. The `run()` function is called with some useful parameters. More on that in a second.
|
||||
2. Inside the run function you can write regular code and use [Tasks](/documentation/concepts/tasks).
|
||||
|
||||
## Resumability
|
||||
|
||||
Runs can exceed the maximum timeout on serverless platforms. If a Run exceeds this limit, it will be re-run. When it is re-run, any completed Tasks return their original output and they aren't re-run. Read more about [Resumability](/documentation/concepts/resumability).
|
||||
|
||||
## Run function parameters
|
||||
|
||||
### payload
|
||||
|
||||
The payload is the data that triggered the Job. It is the same data that was sent to the [Trigger](/documentation/concepts/triggers) that triggered the Job.
|
||||
|
||||
- For [Webhooks](/documentation/concepts/triggers/webhooks) the payload is the data from the webhook.
|
||||
- For [Events](/documentation/concepts/triggers/events) the payload is the data from the event, in the example above that's `{ url: "https://..." }`.
|
||||
- For [Scheduled](/documentation/concepts/triggers/scheduled) the payload is an object with the timestamp and the last timestamp (previous run).
|
||||
|
||||
### io
|
||||
|
||||
The `io` object gives you access to [Integrations](/documentation/concepts/integrations) and other useful functions. [View the full reference](/sdk/io) for `io`.
|
||||
|
||||
A few things you can do with `io`:
|
||||
|
||||
- Use [Integrations](/documentation/concepts/integrations).
|
||||
- Add [delays](/documentation/concepts/delays) (that can be longer than your server timeout).
|
||||
- Log messages to the [Run log](/documentation/guides/viewing-runs).
|
||||
- Perform [background fetch requests](/documentation/sdk/io) (that can be longer than your server timeout).
|
||||
- [Send events](/documentation/concepts/triggers/events) to Trigger other Jobs.
|
||||
- Create a [Task](/documentation/concepts/tasks) manually by wrapping code in `io.runTask`.
|
||||
|
||||
### context
|
||||
|
||||
The `context` object gives you access to information about the current Run, Job, Environment, Organization and Event. [View the full reference](/sdk/context) for `context`.
|
||||
|
||||
## References
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Viewing Runs Dashboard"
|
||||
icon="globe"
|
||||
href="/documentation/guides/viewing-runs"
|
||||
>
|
||||
View all Runs for a Job, all the way down to individual Tasks.
|
||||
</Card>
|
||||
<Card title="`io` SDK Reference" icon="wrench" href="/sdk/io">
|
||||
The `io` object gives you access to Integrations and other useful functions.
|
||||
</Card>
|
||||
<Card title="`context` SDK Reference" icon="wrench" href="/sdk/context">
|
||||
The `context` object gives you access to the current Run's context.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: "Tasks"
|
||||
description: "Tasks are individual building blocks of a Run."
|
||||
---
|
||||
|
||||
> A Task is a resumable unit of a Run that can be retried, resumed and is logged.
|
||||
|
||||
## Tasks vs regular code
|
||||
|
||||
In the `run()` function you can use regular code and you can use Tasks.
|
||||
|
||||
```ts
|
||||
new Job(client, {
|
||||
id: "new-user",
|
||||
name: "Run when a new user signs up",
|
||||
version: "0.0.1",
|
||||
trigger: eventTrigger({
|
||||
name: "new.user",
|
||||
schema: z.object({
|
||||
userId: z.string(),
|
||||
}),
|
||||
}),
|
||||
integrations: {
|
||||
resend,
|
||||
},
|
||||
run: async (payload, io, ctx) => {
|
||||
// regular code, not a Task
|
||||
// the inputs/outputs of this function are not sent to the Trigger.dev platform
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: payload.userId },
|
||||
select: { email: true, name: true },
|
||||
});
|
||||
if (!user) throw new Error(`User not found: ${payload.userId}`);
|
||||
|
||||
// Integration functions are Tasks
|
||||
await io.resend.sendEmail("Welcome email", {
|
||||
to: user.email,
|
||||
from: "jane@acme.inc",
|
||||
subject: "Welcome!",
|
||||
html: welcomeEmail(user.name),
|
||||
});
|
||||
|
||||
// built-in io functions are Tasks
|
||||
await io.wait("wait", 60 * 60 * 3); // wait for 3 hours
|
||||
|
||||
// You can wrap your own code in a Task, for retrying, resumability and logging
|
||||
const response = await io.runTask(
|
||||
"my-task",
|
||||
{ name: "My Task" },
|
||||
async () => {
|
||||
return await longRunningCode(payload.userId);
|
||||
}
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## The benefits of Tasks
|
||||
|
||||
Tasks are a powerful concept that gives you a lot of benefits:
|
||||
|
||||
- **Resumability** – Runs can exceed the maximum timeout on serverless platforms. If a Run exceeds this limit, it will be re-run. When it is re-run, any completed Tasks return their original output and they aren't re-run. Read more about [Resumability](/documentation/concepts/resumability).
|
||||
- **Retryable** – If a Task fails, it will be retried. You can configure how (or if) a Task is retried. Full details in the [io SDK reference](/sdk/io).
|
||||
- **Logging** – Tasks are logged, so you can see what happened in a Run. Find out more about [viewing runs](/documentation/guides/viewing-runs).
|
||||
|
||||
## Subtasks
|
||||
|
||||
A Task can have multiple subtasks, and so on. This is useful for breaking down a large Task into smaller Tasks. We currently support nesting 5 levels deep.
|
||||
|
||||
## Task Keys
|
||||
|
||||
The first param of all Tasks is a `key`. This is a unique identifier for the Task inside that Run. It is used for resumability and logging. It is also used to identify the Task in the [Viewing Runs Dashboard](/documentation/guides/viewing-runs).
|
||||
|
||||
## References
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Resumability"
|
||||
icon="clock"
|
||||
href="/documentation/concepts/resumability"
|
||||
>
|
||||
Runs can be very long-running. Learn how we handle this.
|
||||
</Card>
|
||||
<Card
|
||||
title="Integrations"
|
||||
icon="grid-2"
|
||||
href="/documentation/concepts/integrations"
|
||||
>
|
||||
Integrations utilize Tasks.
|
||||
</Card>
|
||||
<Card title="`io` SDK Reference" icon="wrench" href="/sdk/io">
|
||||
The `io` object allows you to easily run a Task yourself.
|
||||
</Card>
|
||||
<Card
|
||||
title="Viewing Runs Dashboard"
|
||||
icon="globe"
|
||||
href="/documentation/guides/viewing-runs"
|
||||
>
|
||||
View all Runs for a Job, all the way down to individual Tasks.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,130 @@
|
||||
---
|
||||
title: "DynamicTrigger & DynamicSchedule"
|
||||
sidebarTitle: "Dynamic"
|
||||
description: "These are advanced features that allows you to attach dynamic triggers to a Job."
|
||||
---
|
||||
|
||||
Sometimes you don't know when you write the code what the trigger or schedule will be.
|
||||
|
||||
[DynamicTrigger](/sdk/dynamictrigger) and [DynamicSchedule](/sdk/dynamicschedule) allow you to configure triggers and schedules at runtime.
|
||||
|
||||
## DynamicSchedule
|
||||
|
||||
```typescript
|
||||
//1. create a DynamicSchedule
|
||||
const dynamicSchedule = new DynamicSchedule(client, {
|
||||
id: "dynamicinterval",
|
||||
});
|
||||
|
||||
//2. create a Job that is attached to the dynamic schedule
|
||||
new Job(client, {
|
||||
id: "user-dynamicinterval",
|
||||
name: "User Dynamic Interval",
|
||||
version: "0.1.1",
|
||||
//3. set the DynamicSchedule as the Trigger
|
||||
trigger: dynamicSchedule,
|
||||
run: async (payload, io, ctx) => {
|
||||
await io.logger.info("The userId is ", ctx.source.id);
|
||||
},
|
||||
});
|
||||
|
||||
//4. Register the DynamicSchedule anywhere in your app
|
||||
async function registerUserCronJob(userId: string, userSchedule: string) {
|
||||
//use the userId as the id for the DynamicSchedule
|
||||
//so it comes through to run() in the context source.id
|
||||
await dynamicSchedule.register(userId, {
|
||||
type: "cron",
|
||||
options: {
|
||||
cron: userSchedule,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
//5. Register inside other Jobs
|
||||
new Job(client, {
|
||||
id: "register-dynamicinterval",
|
||||
name: "Register Dynamic Interval",
|
||||
version: "0.1.1",
|
||||
trigger: eventTrigger({
|
||||
name: "dynamic.interval",
|
||||
schema: z.object({
|
||||
userId: z.string(),
|
||||
seconds: z.number().int().positive(),
|
||||
}),
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
//6. Register the DynamicSchedule
|
||||
await io.registerInterval("📆", dynamicSchedule, payload.userId, {
|
||||
seconds: payload.seconds,
|
||||
});
|
||||
|
||||
await io.wait("wait", 60);
|
||||
|
||||
//7. Unregister the DynamicSchedule if you want
|
||||
await io.unregisterInterval("❌📆", dynamicSchedule, payload.id);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## DynamicTrigger
|
||||
|
||||
```typescript
|
||||
//1. create a DynamicTrigger
|
||||
const dynamicOnIssueOpenedTrigger = new DynamicTrigger(client, {
|
||||
id: "github-issue-opened",
|
||||
event: events.onIssueOpened,
|
||||
source: github.sources.repo,
|
||||
});
|
||||
|
||||
//2. create a Job that is attached to the dynamic trigger
|
||||
new Job(client, {
|
||||
id: "listen-for-dynamic-trigger",
|
||||
name: "Listen for dynamic trigger",
|
||||
version: "0.1.1",
|
||||
trigger: dynamicOnIssueOpenedTrigger,
|
||||
integrations: {
|
||||
slack,
|
||||
},
|
||||
run: async (payload, io, ctx) => {
|
||||
await io.slack.postMessage("Slack 📝", {
|
||||
text: `New Issue opened on repo: ${
|
||||
payload.issue.html_url
|
||||
}. \n\n${JSON.stringify(ctx)}`,
|
||||
channel: "C04GWUTDC3W",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
//3. Register the DynamicTrigger anywhere in your app
|
||||
async function registerRepo(owner: string, repo: string) {
|
||||
//the first param (key) should be unique
|
||||
await dynamicOnIssueOpenedTrigger.register(`${owner}/${repo}`, {
|
||||
owner,
|
||||
repo,
|
||||
});
|
||||
}
|
||||
|
||||
//4. Register inside other Jobs
|
||||
new Job(client, {
|
||||
id: "new-repo",
|
||||
name: "New repo",
|
||||
version: "0.1.1",
|
||||
//5. when a new repo is created in your org
|
||||
trigger: github.triggers.org({
|
||||
event: events.onNewRepository,
|
||||
org: "triggerdotdev",
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
//6. Register the dynamic trigger so you get notified when an issue is opened
|
||||
return await io.registerTrigger(
|
||||
"register-repo",
|
||||
dynamicOnIssueOpenedTrigger,
|
||||
payload.repository.name,
|
||||
{
|
||||
owner: payload.repository.owner.login,
|
||||
repo: payload.repository.name,
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,151 @@
|
||||
---
|
||||
title: "Event triggers"
|
||||
sidebarTitle: "Events"
|
||||
description: "Event triggers allow you to run Jobs from your own code (or your other Jobs)"
|
||||
---
|
||||
|
||||
> Send an event and any Jobs that subscribe to that event will get triggered.
|
||||
|
||||
## Name and Schemas
|
||||
|
||||
### Name
|
||||
|
||||
Event triggers have a `name`. They will only get triggered when an event with that name are sent.
|
||||
|
||||
### Schema
|
||||
|
||||
Event triggers take a [Zod](https://github.com/colinhacks/zod) schema. This is used to validate the data that is sent with the event. If the data does not match the schema, the Job will not run.
|
||||
|
||||
It also means that inside your run function the payload will be typed correctly. We use [Zod](https://github.com/colinhacks/zod#installation) 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](/guides/zod) for more information.
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
new Job(client, {
|
||||
id: "new-user-slack",
|
||||
name: "New user slack message",
|
||||
version: "0.1.0",
|
||||
trigger: eventTrigger({
|
||||
name: "user.created",
|
||||
schema: z.object({
|
||||
name: z.string(),
|
||||
email: z.string(),
|
||||
paidPlan: z.boolean(),
|
||||
}),
|
||||
filter: {
|
||||
//only run the Job if the user is paying
|
||||
paidPlan: [true],
|
||||
},
|
||||
}),
|
||||
integrations: {
|
||||
slack,
|
||||
},
|
||||
//this function is run when the custom event is received
|
||||
run: async (payload, io, ctx) => {
|
||||
//send a message to the #new-users Slack channel with user details
|
||||
const response = await io.slack.postMessage("send-to-slack", {
|
||||
channel: "CUKJXJZ3Z",
|
||||
text: `New user: ${payload.name} (${payload.email}) signed up. ${
|
||||
payload.paidPlan ? "They are paying" : "They are on the free plan"
|
||||
}.`,
|
||||
});
|
||||
|
||||
return response.message;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
<Note>
|
||||
You can subscribe to the same event from multiple different Jobs. This is
|
||||
useful if you want to send an event to multiple different services or if you
|
||||
want to keep each Job small and simple.
|
||||
</Note>
|
||||
|
||||
## Sending events
|
||||
|
||||
There are two ways of sending an event that will Trigger a Job.
|
||||
|
||||
### 1. From your own code
|
||||
|
||||
You can use `client.sendEvent()` to send an event from your own code. [View the SDK reference](/sdk/triggerclient/instancemethods/sendevent).
|
||||
|
||||
```ts
|
||||
//somewhere in your code, can even be on another server
|
||||
await client.sendEvent({
|
||||
name: "user.created",
|
||||
payload: { name: "John Doe", email: "john@doe.com", paidPlan: true },
|
||||
});
|
||||
```
|
||||
|
||||
### 2. From another Job
|
||||
|
||||
You can use `io.sendEvent()` to send events from inside a Job run, to trigger another. [View the SDK reference](/sdk/io/sendevent).
|
||||
|
||||
```ts
|
||||
new Job(client, {
|
||||
id: "event-1",
|
||||
name: "Run when the foo.bar event happens",
|
||||
version: "0.0.1",
|
||||
trigger: eventTrigger({
|
||||
name: "foo.bar",
|
||||
schema: z.object({
|
||||
url: z.string(),
|
||||
}),
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
//send an event using `io`
|
||||
await io.sendEvent("send event", {
|
||||
name: "user.created",
|
||||
payload: { name: "Rick Astley", email: "rick.astley@gmail.com" },
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Event filters
|
||||
|
||||
They are declarative pattern-matching rules, modeled after [AWS EventBridge patterns](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html).
|
||||
|
||||
Given the following custom event payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"uid": "jexAgaeJFJsrGfans1pxqm",
|
||||
"type": "15 Min Meeting",
|
||||
"price": 0,
|
||||
"title": "15 Min Meeting between Eric Allam and John Doe",
|
||||
"length": 15,
|
||||
"status": "ACCEPTED",
|
||||
"endTime": "2023-01-25T16:00:00Z",
|
||||
"bookingId": 198052,
|
||||
"organizer": {
|
||||
"id": 32794,
|
||||
"name": "Eric Allam",
|
||||
"email": "eric@trigger.dev",
|
||||
"language": { "locale": "en" },
|
||||
"timeZone": "Europe/London"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The following event filter would match the event:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": ["15 Min Meeting"],
|
||||
"status": ["ACCEPTED", "REJECTED"],
|
||||
"organizer": {
|
||||
"name": ["Eric Allam"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For an event pattern to match an event, the event must contain all the field names listed in the event pattern. The field names must also appear in the event with the same nesting structure.
|
||||
|
||||
The value of each field name in the event pattern must be an array of strings, numbers, or booleans. The event pattern matches the event if the value of the field name in the event is equal to any of the values in the array.
|
||||
|
||||
Effectively, each array is an OR condition, and the entire event pattern is an AND condition.
|
||||
|
||||
So the above event filter will match because `status == "ACCEPTED"`, and it would also match if `status == "REJECTED"`.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: "A Trigger is what starts a Job Run. It can be a webhook, a schedule, or an event."
|
||||
---
|
||||
|
||||
We currently support three types of Triggers: Webhooks, Scheduled, and Events. You can use any of these to start a Job Run.
|
||||
|
||||
<CardGroup>
|
||||
<Card
|
||||
title="Webhooks"
|
||||
icon="webhook"
|
||||
href="/documentation/concepts/triggers/webhooks"
|
||||
>
|
||||
Start your Jobs in realtime when events happen in APIs
|
||||
</Card>
|
||||
<Card
|
||||
title="Scheduled"
|
||||
icon="calendar"
|
||||
href="/documentation/concepts/triggers/scheduled"
|
||||
>
|
||||
Run a Job on a repeating schedule
|
||||
</Card>
|
||||
<Card
|
||||
title="Event"
|
||||
icon="brackets-curly"
|
||||
href="/documentation/concepts/triggers/events"
|
||||
>
|
||||
Run your Job when you send events with data
|
||||
</Card>
|
||||
<Card
|
||||
title="DynamicTrigger & DynamicSchedule"
|
||||
icon="code"
|
||||
href="/documentation/concepts/triggers/dynamic"
|
||||
>
|
||||
Create Triggers and Schedules with dynamic settings
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
title: "Scheduled triggers"
|
||||
sidebarTitle: "Scheduled"
|
||||
description: "Run a Job on a recurring schedule"
|
||||
---
|
||||
|
||||
A Scheduled Trigger runs a Job on a repeated schedule. You can set the schedule using a CRON expression or an interval.
|
||||
|
||||
<Snippet file="scheduled-dev-warning.mdx" />
|
||||
|
||||
## Interval
|
||||
|
||||
This job will run every 60 seconds, starting 60 seconds after this Job is first indexed. Note that it does not run at the top of every minute, but rather 60 seconds after the Job is first indexed.
|
||||
|
||||
```ts
|
||||
import { Job, intervalTrigger } from "@trigger.dev/sdk";
|
||||
|
||||
new Job(client, {
|
||||
id: "scheduled-job-1",
|
||||
name: "Scheduled Job 1",
|
||||
version: "0.1.1",
|
||||
trigger: intervalTrigger({
|
||||
seconds: 60,
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
await io.logger.info("Received the scheduled event", {
|
||||
payload,
|
||||
});
|
||||
|
||||
return { foo: "bar" };
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Using CRON syntax
|
||||
|
||||
If you want a Job to run at a specific time or on a specific day of the week, you can use a CRON expression.
|
||||
|
||||
This job will run at 2:30pm every Monday. You can get help with [CRON syntax](https://crontab.guru/#30_14_*_*_1).
|
||||
|
||||
<Note>These are not in local time, they are UTC.</Note>
|
||||
|
||||
```ts
|
||||
import { Job, cronTrigger } from "@trigger.dev/sdk";
|
||||
|
||||
new Job(client, {
|
||||
id: "scheduled-job-2",
|
||||
name: "Scheduled Job 2",
|
||||
version: "0.1.1",
|
||||
trigger: cronTrigger({
|
||||
cron: "30 14 * * 1",
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
await io.logger.info("Received the scheduled event", {
|
||||
payload,
|
||||
});
|
||||
|
||||
return { foo: "bar" };
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
title: "Webhooks"
|
||||
sidebarTitle: "Webhooks"
|
||||
description: "Webhooks allow you to subscribe to events from APIs you use."
|
||||
---
|
||||
|
||||
Webhooks are a crucial part of API development, allowing for real-time reactions to various events across different systems, such as when a Stripe Payment is made, or when a GitHub issue is created.
|
||||
|
||||
## Advantages of using Trigger.dev for webhooks
|
||||
|
||||
Webhooks can be difficult to work with, especially when developing locally. We make them far easier to use with our [Integrations](/integrations).
|
||||
|
||||
- You don't need to register/unregister for webhooks, we do it for you
|
||||
- We receive the webhook, then keep trying to send it to you until you receive it. If your server goes down, no problem.
|
||||
|
||||
## Usage
|
||||
|
||||
There are two ways to use webhooks with Trigger.dev:
|
||||
|
||||
1. Use one of our built-in Integrations, such as [GitHub](/integrations/github). We'll take care of registering the webhook for you.
|
||||
2. [Create your own Integration](/integrations/create) that registers for webhooks, this is useful if you want to use a service that we don't have an Integration for.
|
||||
|
||||
## Example
|
||||
|
||||
```ts Github
|
||||
import { Job } from "@trigger.dev/sdk";
|
||||
import { Github, events } from "@trigger.dev/github";
|
||||
|
||||
//GitHub integration with API Key (it supports OAuth too)
|
||||
const github = new Github({
|
||||
id: "github",
|
||||
token: process.env.GITHUB_API_KEY!,
|
||||
});
|
||||
|
||||
new Job(client, {
|
||||
id: "critical-issue-alert",
|
||||
name: "Critical Issue Alert",
|
||||
version: "0.1.0",
|
||||
//When a GitHub issue is modified on the triggerdotdev/trigger.dev repo
|
||||
trigger: github.triggers.repo({
|
||||
event: events.onIssue,
|
||||
owner: "triggerdotdev",
|
||||
repo: "trigger.dev",
|
||||
}),
|
||||
//include any integrations you want to use
|
||||
integrations: {
|
||||
slack,
|
||||
},
|
||||
//this function gets executed when the webhook is received
|
||||
run: async (payload, io, ctx) => {
|
||||
await io.logger.info(`Action was ${payload.action}`);
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: "What is Trigger.dev?"
|
||||
sidebarTitle: "What is Trigger.dev?"
|
||||
---
|
||||
|
||||
Trigger.dev is a platform, SDK and API for building and running Jobs in your codebase, triggered by various sources, but without having to worry about managing any complicated orchestration infrastructure.
|
||||
|
||||
It can be used from _any_ Node.js (support versions) or TypeScript backend application (including serverless applications and microservices).
|
||||
|
||||
## What we take care of for you:
|
||||
|
||||
- We make it possible to run long-running Jobs on serverless platforms that have short timeouts (e.g. 30 seconds).
|
||||
- We provide an SDK for building Jobs in your codebase, triggered by various sources such as [events](/triggers/events), [scheduled events](/triggers/scheduled-events), and [webhooks](/triggers/webhooks).
|
||||
- We provide an orchestration platform for running Jobs in your codebase.
|
||||
- We provide out-of-the-box Integrations with popular services such as [Slack](/integrations/apis/slack), [OpenAI](/integrations/apis/openai), [GitHub](/integrations/apis/github) and [more](/integrations), which vastly simplifies the process interacting with 3rd-party services.
|
||||
- We handle OAuth for you
|
||||
- We provide a nice UI for viewing and debugging your Jobs.
|
||||
|
||||
## What you take care of:
|
||||
|
||||
- You write your Jobs in your codebase.
|
||||
- You get a Trigger.dev API Key and add it to your codebase.
|
||||
- You deploy your codebase.
|
||||
|
||||
## How it works
|
||||
|
||||
To get an idea of how Trigger.dev works, let's take a look at a simple Job that sends a Slack message when a GitHub issue is labelled as `critical`:
|
||||
|
||||
```ts
|
||||
import { Job } from "@trigger.dev/sdk";
|
||||
import { Github, events } from "@trigger.dev/github";
|
||||
import { Slack } from "@trigger.dev/slack";
|
||||
|
||||
//GitHub integration with API Key (it supports OAuth too)
|
||||
const github = new Github({
|
||||
id: "github",
|
||||
token: process.env.GITHUB_API_KEY!,
|
||||
});
|
||||
|
||||
//Slack integration with OAuth
|
||||
const slack = new Slack({
|
||||
id: "slack",
|
||||
});
|
||||
|
||||
new Job(client, {
|
||||
id: "critical-issue-alert",
|
||||
name: "Critical Issue Alert",
|
||||
version: "0.1.0",
|
||||
//When a GitHub issue is modified on the triggerdotdev/trigger.dev repo
|
||||
trigger: github.triggers.repo({
|
||||
event: events.onIssue,
|
||||
owner: "triggerdotdev",
|
||||
repo: "trigger.dev",
|
||||
}),
|
||||
//include any integrations you want to use
|
||||
integrations: {
|
||||
slack,
|
||||
},
|
||||
//this function gets executed when the trigger fires
|
||||
run: async (payload, io, ctx) => {
|
||||
await io.logger.info(`Action was ${payload.action}`);
|
||||
|
||||
if (payload.action === "labeled" && payload.label?.name === "critical") {
|
||||
//use the Slack integration to post a message
|
||||
await io.slack.postMessage("post message", {
|
||||
channel: "C04GWUTDC3W",
|
||||
text: `Issue ${payload.issue.number}: ${payload.issue.title} is critical!`,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
This code lives in a file inside your Next.js repo.
|
||||
|
||||
It is listening for the [issueEvent](/integrations/apis/github/triggers) GitHub webhook, and when it receives one, we will take care of calling the `run` function supplied to the `Job` constructor with the webhook payload. This gives you the following advantages over traditional webhooks:
|
||||
|
||||
- We will automatically register the webhook with GitHub for you, and verify the payload signature.
|
||||
- We provide a nicely typed `event` payload to your `run` function, so you don't have to setup webhook payload types.
|
||||
- If your server isn't running, we will wait until it's back online before attempting to run the Job.
|
||||
- It is very easy to test your Job locally using our [Test Run](/guides/running-tests) feature.
|
||||
|
||||
As you can see the above Job also makes a call to our Slack [postMessage](/integrations/apis/slack) function, which provides the following advantages over using the raw Slack API:
|
||||
|
||||
- We automatically handle the OAuth flow for you, so you don't have to worry about setting up a Slack app and dealing with credentials in your code (see our [Authentication](/concepts/authentication) guide for more details).
|
||||
- We will automatically retry the request if the Slack API returns an error.
|
||||
- We provide a nicely typed `response` object from your `postMessage` function, so you don't have to setup Slack API types.
|
||||
|
||||
## Why use Trigger.dev?
|
||||
|
||||
Apart from the reasons mentioned above, there are a few other reasons why you might want to use Trigger.dev:
|
||||
|
||||
- You want to access your database or other internal services from your Jobs, without having to expose them to the internet.
|
||||
- You want to colocate your Jobs with your code, so you can deploy them together in one atomic unit.
|
||||
- You want to build event-driven architectures without having to manage any complicated orchestration infrastructure.
|
||||
- You want to add in delays or retries to your Jobs, without having to worry about managing a queue.
|
||||
|
||||
## Architecture
|
||||
|
||||
Below is a simplified architecture diagram of how Trigger.dev works:
|
||||
|
||||
{/* https://www.tldraw.com/r/v2_KEeyTalIH0NRKdsb01Lqt?viewport=36%2C-165%2C2234%2C1420&page=page%3AOecar06rEOb6Kpu9XzDKo */}
|
||||

|
||||
|
||||
As you can see above, we communicate between your code and the Trigger.dev platform. This allows us to send events to your code, and receive tasks from your code.
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: "FAQ"
|
||||
description: "This section is aimed at collecting common questions from users to provide documented answers."
|
||||
---
|
||||
|
||||
<Accordion title="Can I self-host Trigger.dev?">
|
||||
Yes, view our [self-hosting guide](/documentation/guides/self-hosting).
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Does my data get sent to your servers?">
|
||||
Only what you choose to send. The main body of your Job code runs on your
|
||||
infrastructure. For example when you do a database query, that never touches
|
||||
us. We receive data that triggers the start of a Job, any data you pass to one
|
||||
of our API Integrations, and any data you choose to log using our logging
|
||||
function. We store this to display on the Runs page of your dashboard.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Does Trigger.dev only support Next.js?">
|
||||
No, you'll be able to use Trigger.dev with a variety of other frameworks,
|
||||
serverless or otherwise, such as Node.js, Remix, and Express, in addition to
|
||||
Next.js.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="How is this different to Zapier, Pipedream etc?">
|
||||
Trigger.dev is a code-first tool that lets you create Jobs directly in your
|
||||
code, rather than using a UI builder like Zapier. This means you can stay in
|
||||
your own IDE and keep your internal data secure.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Can I run Trigger.dev locally?">
|
||||
Yes. Jobs are created in your code locally.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Can I build complex Jobs?">
|
||||
Yes. There’s no limit to the complexity of Jobs you can create. Jobs are
|
||||
created in code so you can write conditional, looping, branching or time
|
||||
delayed logic.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="What is a 'Run'?">
|
||||
A run is a single execution of a Job. This can be in either development,
|
||||
staging or production. [View full details](/documentation/concepts/runs).
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Can I use version control or roll-backs?">
|
||||
Yes. You create Jobs directly in your own code so it’s version controlled with
|
||||
everything else.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="How long does it take to code up a Job?">
|
||||
A simple Job doing a couple of API calls from different services will take
|
||||
about 5 minutes to create.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Do you have all the Integrations I need?">
|
||||
View [our Integrations page](/integrations) to see the Integrations we
|
||||
currently support. If we don't have an Integration you need, you can request
|
||||
it or create it yourself.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Is Trigger.dev open source?">
|
||||
Yes, Trigger.dev is open source. We are strong supporters of open source
|
||||
software, and our first product, [jsonhero.io](https://jsonhero.io), has a
|
||||
thriving open source community. Trigger.dev follows in that tradition.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Is Trigger.dev a no/low-code tool?">
|
||||
No. Trigger.dev is designed for developers who want to create Jobs directly in
|
||||
code, without using a UI builder like Zapier. This allows developers to stay
|
||||
in their familiar development environment and customise their Jobs with code.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Can non-coders use this product?">
|
||||
Developers will need to create Jobs. However, anyone on the team can monitor
|
||||
running Jobs in the Trigger.dev dashboard.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="My question is not listed here">
|
||||
Hop in our [Discord](https://discord.gg/nkqV9xBYWy) and ask any question you have in there!
|
||||
|
||||
You could also open a [GitHub issue](https://github.com/triggerdotdev/trigger.dev/issues/new).
|
||||
|
||||
</Accordion>
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: "Get in touch with us!"
|
||||
sidebarTitle: "Get help"
|
||||
description: "Contact us if you have any questions, or would like help with any issues."
|
||||
---
|
||||
|
||||
<Note>We are active in the community and will respond to all messages.</Note>
|
||||
|
||||
Please email us at <a href="mailto:help@trigger.dev">help@trigger.dev</a> or choose one of the options below:
|
||||
|
||||
<CardGroup>
|
||||
<Card
|
||||
title="Join the community"
|
||||
icon="discord"
|
||||
href="https://discord.gg/nkqV9xBYWy"
|
||||
>
|
||||
The place to meet other users, the team and to get product updates.
|
||||
</Card>
|
||||
<Card
|
||||
title="Schedule a call"
|
||||
icon="video"
|
||||
href="https://cal.com/team/triggerdotdev/founders-call"
|
||||
>
|
||||
A call with someone from our team. We are happy to help.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: "Using the CLI"
|
||||
description: "How to use the CLI"
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
If you're setting up your project for the first time, we recommend using the CLI by following the [Quickstart guide](/documentation/quickstart).
|
||||
|
||||
## init Command
|
||||
|
||||
The `init` command incorporates Trigger.dev into your Next.js project. It performs the following functions:
|
||||
|
||||
- Adds Trigger.dev to the project.
|
||||
- Creates a new route.
|
||||
- Generates an example file.
|
||||
|
||||
During execution, this command requires some configuration parameters. Detailed information on these parameters can be found in the next section.
|
||||
|
||||

|
||||
|
||||
Run this `init` command in a terminal window to setup your project with Trigger.dev
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash npm
|
||||
npx @trigger.dev/cli@latest init
|
||||
```
|
||||
|
||||
```bash pnpm
|
||||
pnpm dlx @trigger.dev/cli@latest init
|
||||
```
|
||||
|
||||
```bash yarn
|
||||
yarn dlx @trigger.dev/cli@latest init
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### CLI steps explained
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Are you using the Trigger.dev cloud or self-hosted?">
|
||||
<ResponseField name="Option 1: Trigger.dev Cloud">
|
||||
Trigger.dev Cloud is a fully hosted service that provides the easiest and quickest way to use Trigger.dev.
|
||||
</ResponseField>
|
||||
<ResponseField name="Option 2: Self-hosted">
|
||||
Instead of using the Trigger.dev Cloud service which we host for you, you
|
||||
can host the Trigger.dev platform yourself. We provide an official
|
||||
Trigger.dev Docker image you can use to easily self-host on your preferred
|
||||
platform. More information on self-hosting can be found in the
|
||||
self-hosting section of the docs
|
||||
[here](/documentation/guides/self-hosting).
|
||||
<Accordion title="Enter the URL of your self-hosted Trigger.dev instance">
|
||||
When following the [self-hosting guide](/documentation/guides/self-hosting) you will deploy your Docker image to a platform of your choice. After completing this step, enter the URL of your self-hosted instance in this CLI step.
|
||||
</Accordion>
|
||||
</ResponseField>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Enter your development API key">
|
||||
To locate your development API key, login to the [Trigger.dev
|
||||
dashboard](https://cloud.trigger.dev) and select the Project you want to
|
||||
connect to. Then click on the Environments & API Keys tab in the left menu.
|
||||
You can copy your development API Key from the field at the top of this page.
|
||||
(Your development key will start with `tr_dev_`).
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Enter a unique ID for your endpoint">
|
||||
Enter a custom ID or use the default by hitting enter. You can learn more
|
||||
about endpoints
|
||||
[here](/documentation/concepts/environments-endpoints#endpoints).
|
||||
</Accordion>
|
||||
|
||||
</AccordionGroup>
|
||||
|
||||
## dev Command
|
||||
|
||||
Once you're running your Next.js project locally, you can then execute the `dev` CLI command to run Trigger.dev locally. You should run this command every time you want to use Trigger.dev locally.
|
||||
|
||||

|
||||
|
||||
<Warning>
|
||||
Make sure your Next.js site is running locally before continuing. You must
|
||||
also leave this `dev` terminal command running while you develop.
|
||||
</Warning>
|
||||
|
||||
In a **new terminal window or tab** run:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash npm
|
||||
npx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
```bash pnpm
|
||||
pnpm dlx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
```bash yarn
|
||||
yarn dlx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
<br />
|
||||
<Note>
|
||||
You can optionally pass the port if you're not running on 3000 by adding
|
||||
`--port 3001` to the end
|
||||
</Note>
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: "Contributing"
|
||||
description: "You can contribute Integrations and core code to the Trigger.dev platform "
|
||||
---
|
||||
|
||||
Trigger.dev is open source and we welcome contributions from the community.
|
||||
|
||||
<CardGroup>
|
||||
<Card
|
||||
title="GitHub Repo"
|
||||
icon="github"
|
||||
href="https://github.com/triggerdotdev/trigger.dev"
|
||||
>
|
||||
Our Open Source GitHub repo
|
||||
</Card>
|
||||
<Card
|
||||
title="View and create issues"
|
||||
icon="bug"
|
||||
href="https://github.com/triggerdotdev/trigger.dev/issues"
|
||||
>
|
||||
You can view open issues and create new ones
|
||||
</Card>
|
||||
<Card
|
||||
title="Create an Integration"
|
||||
icon="square-plus"
|
||||
href="/integrations/create"
|
||||
>
|
||||
Create an Integration for your own use or as a public package.
|
||||
</Card>
|
||||
<Card
|
||||
title="Join the community"
|
||||
icon="discord"
|
||||
href="https://discord.gg/nkqV9xBYWy"
|
||||
>
|
||||
The place to meet other users, the team and to get product updates.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,272 @@
|
||||
---
|
||||
title: "Create a Job"
|
||||
description: "How to create a Job in your codebase"
|
||||
---
|
||||
|
||||
> Jobs are the core of the system. They allow you to run code when some event occurs. They are built using a combination of Triggers and Tasks.
|
||||
|
||||
### Pre-requisites
|
||||
|
||||
Make sure your Project is set up with Trigger.dev. We recommend [using the CLI](/documentation/quickstart) to do this.
|
||||
|
||||
## How to write a Job in code
|
||||
|
||||
### 1. Create a Job file in your Project
|
||||
|
||||
This is where you will write your Job code. E.g. `my-job.ts`.
|
||||
|
||||
```ts
|
||||
//this path might be different depending on your project
|
||||
import { client } from "@/trigger";
|
||||
|
||||
client.defineJob({
|
||||
// This is the unique ID for your Job's end-point
|
||||
id: "your-job-id",
|
||||
// This is the name of your Job
|
||||
name: "Your Job name",
|
||||
// This is the version of our SDK you are using
|
||||
version: "0.0.1",
|
||||
...
|
||||
```
|
||||
|
||||
The `id` and `name` are important because they are used to create and identify your Job in the app.
|
||||
|
||||
<Note>
|
||||
This Job must be imported in the `trigger` file in order to be registered when
|
||||
the CLI dev command is run. This can be found in either the
|
||||
`app/api/trigger/route.ts` file if you're using the Next.js App Router, or
|
||||
`pages/api/trigger.ts` if you're using the Next.js Pages Router.
|
||||
</Note>
|
||||
|
||||
### 2. Choose a Trigger
|
||||
|
||||
This is what kicks-off a Job. There are a few different types of Triggers you can use:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Scheduled">
|
||||
Run a Job on a repeating schedule, using [intervalTrigger](/documentation/concepts/triggers/scheduled#interval)
|
||||
```ts
|
||||
client.defineJob({
|
||||
...
|
||||
trigger: intervalTrigger({
|
||||
seconds: 60,
|
||||
}),
|
||||
...
|
||||
```
|
||||
Or with CRON syntax, using [cronTrigger](/documentation/concepts/triggers/scheduled#using-cron-syntax):
|
||||
```ts
|
||||
client.defineJob({
|
||||
...
|
||||
trigger: cronTrigger({
|
||||
cron: "30 14 * * 1",
|
||||
}),
|
||||
...
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Webhook">
|
||||
|
||||
Start your Jobs when an event happens in another API. You'll need to use [Integrations](/integrations) to do this.
|
||||
|
||||
Here's an example with the GitHub integration.
|
||||
|
||||
```ts
|
||||
client.defineJob({
|
||||
...
|
||||
//E.g. When a GitHub issue is modified on the triggerdotdev/trigger.dev repo
|
||||
trigger: github.triggers.repo({
|
||||
event: events.onIssue,
|
||||
owner: "triggerdotdev",
|
||||
repo: "trigger.dev",
|
||||
}),
|
||||
...
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="Event">
|
||||
The [eventTrigger](/documentation/concepts/triggers/events) allows you to define an event that your Job listens for.
|
||||
|
||||
When you [send an event](/documentation/concepts/triggers/events#sending-events) with the same name the Job will run.
|
||||
|
||||
``` ts
|
||||
client.defineJob({
|
||||
...
|
||||
//E.g. when a user is created in your app (you send the event)
|
||||
trigger: eventTrigger({
|
||||
name: "user.created",
|
||||
schema: z.object({
|
||||
name: z.string(),
|
||||
email: z.string(),
|
||||
paidPlan: z.boolean(),
|
||||
}),
|
||||
...
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab title="Dynamic">
|
||||
These are advanced features that allows you to attach dynamic triggers to a Job. Full information [here](/documentation/concepts/triggers/dynamic).
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### 3. Create the Job Tasks
|
||||
|
||||
> A Task is a resumable unit of a Run that can be retried, resumed and is logged.
|
||||
|
||||
<Info>
|
||||
You can use just regular code in your Jobs. But you don't get the benefits of
|
||||
retrying, logging and resumability. More info on [Tasks vs regular
|
||||
code](/documentation/concepts/tasks#tasks-vs-regular-code).
|
||||
</Info>
|
||||
|
||||
You can string together multiple Tasks and regular code in any order you want.
|
||||
|
||||
**Useful built-in Tasks:**
|
||||
|
||||
| Task | Description | Task code |
|
||||
| ------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| [Delay](/documentation/concepts/delays) | Wait for a period of time | `await io.wait("wait", 60);` |
|
||||
| [Log](/sdk/io/logger) | Log a message | `await io.logger.log("Hello");` |
|
||||
| [Send Event](/sdk/io/sendevent) | Send an event (for eventTrigger) | `await io.sendEvent("my-event", { name: "my.event", payload: { hello: "world" } });` |
|
||||
| [Run task](/sdk/io/runtask) | Wrap your own code in this to create a Task | `await io.runTask("My Task", { name: "My Task" }, async () => { console.log("Hello"); });` |
|
||||
| [Background fetch](/sdk/io/backgroundfetch) | Fetch data from a URL that can take longer that the serverless timeout. | `await io.backgroundFetch("fetch-some-data", { url: "https://example.com" });` |
|
||||
|
||||
For a full list of built-in Tasks, see the [io SDK reference](/sdk/io).
|
||||
|
||||
**Integration Task examples:**
|
||||
|
||||
<Info>
|
||||
To use our integrations you will need to set them up in the app first. Our
|
||||
guide is [here](/documentation/guides/using-integrations).
|
||||
</Info>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="OpenAI" description="Generate text completions in a conversational context.">
|
||||
|
||||
**Task:** [backgroundCreateCompletion](/integrations/apis/openai)
|
||||
|
||||
```ts
|
||||
await io.openai.backgroundCreateChatCompletion("background-chat-completion", {
|
||||
model: "gpt-3.5-turbo",
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: "Create a good programming joke about background jobs",
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
View more OpenAI tasks [here](/integrations/apis/openai).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="GitHub" description="Add a custom label to a GitHub issue.">
|
||||
|
||||
**Task:** [addIssueLabels](/integrations/apis/github-tasks)
|
||||
|
||||
```ts
|
||||
await io.github.addIssueLabels("add label", {
|
||||
owner: payload.repository.owner.login,
|
||||
repo: payload.repository.name,
|
||||
issueNumber: payload.issue.number,
|
||||
labels: ["bug"],
|
||||
});
|
||||
```
|
||||
|
||||
View more GitHub tasks [here](/integrations/apis/github-tasks).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Resend" description="Send an email using Resend.">
|
||||
|
||||
**Task:** [sendEmail](/integrations/apis/resend)
|
||||
|
||||
```ts
|
||||
await io.resend.sendEmail("send-email", {
|
||||
to: payload.to,
|
||||
subject: payload.subject,
|
||||
text: payload.text,
|
||||
from: "Trigger.dev <hello@email.trigger.dev>",
|
||||
});
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Slack" description="Post a message to a Slack channel.">
|
||||
|
||||
**Task:** [postMessage](/integrations/apis/slack)
|
||||
|
||||
```ts
|
||||
await io.slack.postMessage("post message", {
|
||||
channel: "C04GWUTDC3W",
|
||||
text: "My first Slack message",
|
||||
});
|
||||
```
|
||||
|
||||
View more Slack tasks [here](/integrations/apis/slack).
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
These are just a few examples of Integration Tasks. For many more, browse our [Integrations section](/integrations/).
|
||||
|
||||
### 4. Register your Jobs
|
||||
|
||||
While your app is running, open a **new terminal window or tab** and run:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash npm
|
||||
npx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
```bash pnpm
|
||||
pnpm dlx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
```bash yarn
|
||||
yarn dlx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
This will register all of your Jobs, they should appear in your dashboard.
|
||||
|
||||
<Note>
|
||||
Not seeing your Job in the web app? It might be because you forgot to import
|
||||
it. This will need to be either in `app/api/trigger/route.ts` file if you're
|
||||
using the Next,js App Router, or `pages/api/trigger.ts` if you're using the
|
||||
Next,js Pages Router.
|
||||
</Note>
|
||||
|
||||
If you are having trouble getting your job running, please reach out to us and we will help you fix any issues:
|
||||
|
||||
- [Join our Discord](https://discord.gg/kA47vcd8P6)
|
||||
- [Email us](mailto:help@trigger.dev)
|
||||
|
||||
---
|
||||
|
||||
## Next steps
|
||||
|
||||
We recommend exploring all of the below sections to fully understand how to create and run Jobs using Trigger.dev.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Running your jobs"
|
||||
icon="wand-magic-sparkles"
|
||||
href="/documentation/guides/running-jobs"
|
||||
>
|
||||
A guide for how to run your Jobs. Triggering a test Run and Triggering your Job for real
|
||||
|
||||
</Card>
|
||||
|
||||
<Card title="Example Jobs" icon="slot-machine" href="/examples">
|
||||
View example Jobs / the example jobs repo. These are a great starting
|
||||
point for creating your own Jobs.
|
||||
</Card>
|
||||
<Card title="SDK reference" icon="code" href="/sdk">
|
||||
How to use the SDK. This includes all the available Tasks, triggers and
|
||||
actions you can use.
|
||||
</Card>
|
||||
|
||||
<Card title="Integrations" icon="grid-2" href="/integrations">
|
||||
Integrations make it easy to authenticate and use APIs.
|
||||
Learn how to use and create integrations.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: "Automatic endpoint refreshing"
|
||||
description: "Use our webhook to automatically tell us when you deploy"
|
||||
---
|
||||
|
||||
## In the dashboard
|
||||
|
||||
1. Go to the "Environments & API Keys" page in your Trigger.dev dashboard
|
||||

|
||||
2. Select your endpoint row in the table of endpoints.
|
||||

|
||||
3. There is a webhook URL in the "Automatic Refresh" section. Copy this URL.
|
||||

|
||||
|
||||
## How to use the webhook URL
|
||||
|
||||
### Vercel
|
||||
|
||||
You can use this webhook URL in your Vercel dashboard, so when a deployment succeeds it automatically refreshes the endpoint.
|
||||
|
||||
1. From your Vercel team dashboard, select "Settings"
|
||||

|
||||
2. Go to the "Webhooks" page
|
||||

|
||||
3. Select the "Deployment Succeeded" event, your Vercel Project, and paste in our webhook URL. Then "Create Webhook".
|
||||

|
||||
4. You're done! Whenever a deploy succeeds, Vercel will tell us to refresh your endpoint.
|
||||

|
||||
|
||||
### GitHub Actions
|
||||
|
||||
You can add a step to the GitHub Action that deploys your app.
|
||||
|
||||
```yaml .github/workflows/release.yml
|
||||
- name: 🚀 Refresh Trigger.dev Jobs
|
||||
env:
|
||||
DEPLOY_TEST_HOOK: ${{ secrets.TRIGGER_ENDPOINT_HOOK }}
|
||||
run: |
|
||||
curl -X POST $TRIGGER_ENDPOINT_HOOK
|
||||
```
|
||||
|
||||
You will need to [setup the `TRIGGER_ENDPOINT_HOOK` secret in your GitHub repo](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository). Set it to the webhook URL from the endpoint panel.
|
||||
|
||||
### Do an HTTP request yourself
|
||||
|
||||
Any `GET` or `POST` request to the webhook URL will cause a refresh of the Jobs for that endpoint. `POST` requests don't need a body. There is no authentication required.
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: "Manual endpoint refreshing"
|
||||
description: "You can manually refresh Endpoints in your Trigger.dev dashboard"
|
||||
---
|
||||
|
||||
1. Go to the "Environments & API Keys" page in your Trigger.dev dashboard
|
||||

|
||||
2. Select your endpoint row in the table of endpoints.
|
||||

|
||||
3. Click the "Refresh now" button
|
||||

|
||||
|
||||
You should see the "Last refreshed" date update to the current time.
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
title: "First-time setup"
|
||||
description: "The first time you deploy to a new environment you will need to setup the endpoint for that environment."
|
||||
---
|
||||
|
||||
## 1. Make sure your Client is configured correctly
|
||||
|
||||
The API Key you use for your `Client` is how we know which environment to run your code against:
|
||||
|
||||
```ts
|
||||
export const client = new TriggerClient({
|
||||
id: "nextjs-example",
|
||||
//this environment variable should be set to your DEV API Key locally,
|
||||
//and your PROD API Key in production
|
||||
apiKey: process.env.TRIGGER_API_KEY!,
|
||||
});
|
||||
```
|
||||
|
||||
## 2. Set your environment variables on your server
|
||||
|
||||
Ensure that your `TRIGGER_API_KEY` (or whatever you've set it to) environment variable is set on your server, to the correct value from the "Environments & API Keys" page in your Trigger.dev dashboard.
|
||||
|
||||

|
||||
|
||||
If you've used any other environment variables in your code (like API Keys for other services), make sure they are set on your server too.
|
||||
|
||||
The exact instructions will vary depending on where you deploy to. Here are the docs links to some popular services:
|
||||
|
||||
- [Vercel](https://vercel.com/docs/concepts/projects/environment-variables#)
|
||||
- [Cloudflare Pages](https://developers.cloudflare.com/pages/platform/functions/bindings/#environment-variables)
|
||||
- [Cloudflare Workers](https://developers.cloudflare.com/workers/platform/environment-variables/)
|
||||
- [Netlify](https://docs.netlify.com/environment-variables/overview/)
|
||||
|
||||
## 3. Deploy your code as usual
|
||||
|
||||
Your Job code lives in your codebase, so you can deploy it as you normally would.
|
||||
|
||||
## 4. Connect the Endpoint for the first time
|
||||
|
||||
1. Go to the "Environments & API Keys" page in your Trigger.dev dashboard
|
||||

|
||||
|
||||
2. Click the "Configure" button on the relevant endpoint
|
||||

|
||||
|
||||
3. Enter the URL of your Trigger.dev endpoint
|
||||

|
||||
|
||||
<Info>
|
||||
This is the value of the `path` option for the adaptor you're using. For
|
||||
Next.js, this would usually be `https://yourdomain.com/api/trigger`.
|
||||
</Info>
|
||||
|
||||
4. Click "Save". This will automatically connect, test your endpoint, and register all your Jobs.
|
||||

|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "Introduction"
|
||||
description: "A guide for how to deploy your Jobs"
|
||||
---
|
||||
|
||||
Deployment uses [Environments & Endpoints](/documentation/concepts/environments-endpoints) to connect your Jobs to the Trigger.dev platform.
|
||||
|
||||
## First time deploying to a new Environment
|
||||
|
||||
The first time you deploy to a new environment you will need to setup the
|
||||
endpoint for that environment.
|
||||
|
||||
<Card
|
||||
title="First time setup"
|
||||
icon="wrench"
|
||||
href="/documentation/guides/deployment-setup"
|
||||
>
|
||||
This only needs to be done once for each environment
|
||||
</Card>
|
||||
|
||||
## Subsequent deployments (i.e. refreshing your Endpoint)
|
||||
|
||||
If you add new Jobs, change the id of a Job, or change the Triggers of a Job then you will need to refresh your Endpoint.
|
||||
|
||||
There are two ways to do this:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Manual refreshing"
|
||||
icon="arrow-pointer"
|
||||
href="/documentation/guides/deployment-manual"
|
||||
>
|
||||
Manually refresh in your Trigger.dev dashboard
|
||||
</Card>
|
||||
<Card
|
||||
title="Automatic refreshing"
|
||||
icon="robot"
|
||||
href="/documentation/guides/deployment-automatic"
|
||||
>
|
||||
Automatically refresh by using our webhook
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: "Managing Jobs"
|
||||
description: "How to view, add, modify, and delete jobs"
|
||||
---
|
||||
|
||||
[Jobs](/documentation/concepts/jobs) live inside a [Project](/documentation/concepts/projects).
|
||||
|
||||
For Jobs to actually run, they need to be connected to the Trigger.dev platform.
|
||||
|
||||
## Viewing Jobs
|
||||
|
||||
The main page for a Project is the list of connected Jobs. You can see overview details for a each Job here, including details on the Trigger, Integrations and when it was last run.
|
||||
|
||||
<Frame caption="The homepage of a Project">
|
||||

|
||||
</Frame>
|
||||
|
||||
## How to add your first Job
|
||||
|
||||
We recommend you do the initial setup of a new Project by following our [quick start guide](/documentation/quickstart). Once completed you should have an example Job in your dashboard.
|
||||
|
||||
## Adding more Jobs locally
|
||||
|
||||
When you add a new Job to your codebase, you'll need to connect it to Trigger.dev. This is achieved by refreshing the endpoint in your local Dev environment.
|
||||
|
||||
1. Go to the "Environments & API Keys" page for your Project
|
||||

|
||||
2. Select the "DEV" row in the table of endpoints.
|
||||

|
||||
3. Click the "Refresh now" button
|
||||

|
||||
|
||||
<Note>
|
||||
You only need to do this when you add a new Job (a job with an ID that hasn't
|
||||
been connected to Trigger.dev before). If you modify an existing Job, you
|
||||
don't need to refresh the endpoint.
|
||||
</Note>
|
||||
|
||||
## Deploying Jobs
|
||||
|
||||
See our [deployment guide](/documentation/guides/deployment).
|
||||
|
||||
## Disabling Jobs
|
||||
|
||||
Sometimes there's a Job that you no longer want to be Triggered. You can achieve this by Disabling it. This will prevent the `run()` function being called for that Job.
|
||||
|
||||
## Archiving Jobs
|
||||
|
||||
<Note>Being able to archive Jobs is coming soon</Note>
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: "Express"
|
||||
description: "How to get setup and deploy your Express project"
|
||||
---
|
||||
|
||||
<Note>Support for Express is coming very soon</Note>
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
title: "Next.js"
|
||||
description: "How to get setup and deploy Jobs for your Next.js project"
|
||||
---
|
||||
|
||||
You can write Jobs in your Next.js codebase and deploy to both serverless platforms and long-running servers.
|
||||
|
||||
## Supported platforms
|
||||
|
||||
We support all platforms because under-the-hood an API endpoint is used to run your Jobs.
|
||||
|
||||
## Initial setup
|
||||
|
||||
View our [Quick start guide](/documentation/quickstart) to get setup.
|
||||
|
||||
## Writing Jobs
|
||||
|
||||
View our [guide for writing Jobs](/documentation/guides/create-a-job).
|
||||
|
||||
## Deployment
|
||||
|
||||
View our [deployment guide](/documentation/guides/deployment) to learn how to deploy your Jobs.
|
||||
|
||||
## Middleware
|
||||
|
||||
Next.js Middleware allows you to run code before a request is completed, and if you are using it currently in your Next.js project (or you add it later), you might need to guard against altering requests to the `/api/trigger` endpoint, which needs to be exposed to the Trigger.dev installation (either your self-hosted one or the Trigger.dev Cloud).
|
||||
|
||||
To make sure you aren't matching the `/api/trigger` route in your middleware, check your `config.matcher` export:
|
||||
|
||||
```ts middleware.ts
|
||||
import { NextResponse } from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
// This function can be marked `async` if using `await` inside
|
||||
export function middleware(request: NextRequest) {
|
||||
return NextResponse.redirect(new URL("/home", request.url));
|
||||
}
|
||||
|
||||
// See "Matching Paths" below to learn more
|
||||
export const config = {
|
||||
matcher: "/about/:path*",
|
||||
};
|
||||
```
|
||||
|
||||
The above matcher doesn't match `/api/trigger` so there won't be an issue here. But the following middleware.ts file will cause conflicts with Trigger.dev
|
||||
|
||||
```ts middleware.ts
|
||||
export function middleware(request: NextRequest) {
|
||||
return NextResponse.redirect(new URL("/home", request.url));
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
|
||||
};
|
||||
```
|
||||
|
||||
As you can see, the last matcher `"/(api|trpc)(.*)"` matches anything starting with `api`, which matches `/api/trigger`. You can add a negative-lookahead pattern to the matcher to exclude the `/api/trigger` route:
|
||||
|
||||
```ts middleware.ts
|
||||
export const config = {
|
||||
matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api((?!/trigger))|trpc)(.*)"],
|
||||
};
|
||||
```
|
||||
|
||||
The above will match anything starting with `/api` except for `/api/trigger`.
|
||||
|
||||
If you want to match all routes except for `/api/trigger`, you can use the following matcher:
|
||||
|
||||
```ts middleware.ts
|
||||
// Match all routes other than /api/trigger
|
||||
export const config = {
|
||||
matcher: ["/((?!api/trigger).*)"],
|
||||
};
|
||||
```
|
||||
|
||||
For more information about middleware matchers, head over to the Next.js [middleware documentation](https://nextjs.org/docs/pages/building-your-application/routing/middleware#matcher).
|
||||
|
||||
### Clerk.com Auth Middleware
|
||||
|
||||
If you are using [Clerk.com](https://clerk.com) for your Next.js authentication, make sure to update your middleware file to add `/api/trigger` to the `publicRoutes`, like so:
|
||||
|
||||
```ts middleware.ts
|
||||
import { authMiddleware } from "@clerk/nextjs";
|
||||
|
||||
// Adding the /api/trigger route to the public routes so clerk doesn't return a 401
|
||||
// /api/trigger will handle it's own authentication
|
||||
export default authMiddleware({
|
||||
publicRoutes: ["/api/trigger"],
|
||||
});
|
||||
|
||||
export const config = {
|
||||
matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
|
||||
};
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: "Rerunning"
|
||||
description: "From a Run page, you can rerun"
|
||||
---
|
||||
|
||||
On the Run page when the Run is in a `success` or `failed` state, you can rerun by clicking the `Rerun` button.
|
||||
|
||||

|
||||
|
||||
There are two possible rerun options.
|
||||
|
||||
### 1. Run again
|
||||
|
||||
This option is always available (when a run has finished).
|
||||
|
||||
It creates a brand new run with the same inputs as the original – the same Trigger payload, settings, connections etc.
|
||||
|
||||
<Warning>Stating the obvious: this will run all the code again.</Warning>
|
||||
|
||||
### 2. Retry job run
|
||||
|
||||
This option is only available when the run has failed.
|
||||
|
||||
It will continue the existing Run by retrying the Task that failed the Job.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: "Running your Jobs"
|
||||
description: "A guide for how to run your Jobs."
|
||||
---
|
||||
|
||||
There are two ways to run your Jobs:
|
||||
|
||||
1. Triggering a test Run
|
||||
2. Triggering your Job for real
|
||||
|
||||
## 1. Triggering a test Run
|
||||
|
||||
You can perform a Run with any payload you want or use one of our examples on the test page in our dashboard.
|
||||
|
||||
[How to do a test Run from the dashboard](/documentation/guides/testing-jobs).
|
||||
|
||||
## 2. Triggering your Job for real
|
||||
|
||||
Triggering your Job for real depends on the [type of trigger](/documentation/concepts/triggers) you have attached to your Job.
|
||||
|
||||
There are three types of Trigger:
|
||||
|
||||
### Scheduled Trigger
|
||||
|
||||
<Snippet file="scheduled-dev-warning.mdx" />
|
||||
|
||||
[Scheduled Triggers](/documentation/concepts/triggers/scheduled) are triggered automatically by our system on the schedule you define. Once you have [deployed](/documentation/guides/deployment) your Job, it will run automatically.
|
||||
|
||||
### Event Trigger
|
||||
|
||||
[Event Triggers](/documentation/concepts/triggers/event) are triggered by an event that you send from elsewhere in your code.
|
||||
|
||||
<Snippet file="send-event-options.mdx" />
|
||||
|
||||
### Webhook Trigger
|
||||
|
||||
[Webhook Triggers](/documentation/concepts/triggers/webhook) are triggered when you perform the action that the webhook subscribes to. For example, if you have a webhook Trigger that subscribes to the `pull_request` event on GitHub, then it will be triggered whenever a pull request is opened, closed, or updated on the repo you configured.
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: "Self hosting"
|
||||
description: "You can self-host the Trigger.dev platform"
|
||||
---
|
||||
|
||||
## What does this mean?
|
||||
|
||||
Instead of using the [Trigger.dev Cloud](https://cloud.trigger.dev) service which we host for you, you can host the Trigger.dev platform yourself.
|
||||
|
||||
## Local development
|
||||
|
||||
When you're working on your web app, you can run Trigger.dev locally alongside your web app.
|
||||
|
||||
- See our [GitHub docker project](https://github.com/triggerdotdev/docker) for instructions.
|
||||
- You will need to [setup tunneling](/documentation/guides/tunneling-platform) if you want to receive webhooks from external services.
|
||||
|
||||
## Deployment
|
||||
|
||||
We provide an official Trigger.dev [docker image](https://github.com/triggerdotdev/trigger.dev/pkgs/container/trigger.dev) you can use to easily self-host on your preferred platform. We also provide guides for some popular platforms:
|
||||
|
||||
<CardGroup>
|
||||
<Card
|
||||
title="Fly.io"
|
||||
icon="fly"
|
||||
href="/documentation/guides/self-hosting/flyio"
|
||||
>
|
||||
Easily to deploy to Fly.io
|
||||
</Card>
|
||||
<Card
|
||||
title="Render.com"
|
||||
icon="draw-square"
|
||||
href="/documentation/guides/self-hosting/flyio"
|
||||
>
|
||||
Easily to deploy to Render.com
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,143 @@
|
||||
---
|
||||
title: "Deploy to Fly.io"
|
||||
description: "Deploy self hosted version of [Trigger.dev](https://trigger.dev) to Fly.io"
|
||||
---
|
||||
|
||||
You can use this [repository](https://github.com/triggerdotdev/fly.io) as a jumping off point for deploying a self-hosted version of Trigger.dev on Fly.io using the Trigger.dev public docker image located at `ghcr.io/triggerdotdev/trigger.dev:latest`
|
||||
|
||||
## Fork the repository mentioned above and change the app name
|
||||
|
||||
You should fork the repository before starting so you can make changes and commit them. For example, you'll need to change the `app` property in the `fly.toml` file to be something other than `app = "trigger-v2-fly-demo"`.
|
||||
|
||||
## Install and configure the fly.io CLI
|
||||
|
||||
1. Install the Fly CLI tool:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```sh Mac
|
||||
brew install flyctl
|
||||
```
|
||||
|
||||
```sh Windows
|
||||
pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
2. Authenticate the CLI:
|
||||
|
||||
```sh
|
||||
fly auth login
|
||||
```
|
||||
|
||||
## Create the fly.io app and pg db
|
||||
|
||||
1. Launch the app:
|
||||
|
||||
```sh
|
||||
fly launch
|
||||
```
|
||||
|
||||
2. Follow the prompts by `fly launch` and make sure to answer them in the following way:
|
||||
|
||||
```sh
|
||||
? Would you like to copy its configuration to the new app? Yes
|
||||
? Choose an app name (leaving blank will default to 'trigger-v2-fly-demo') <enter your preferred app name here or leave blank>
|
||||
? Would you like to set up a Postgresql database now? Yes
|
||||
? Select configuration: Development - Single node, 1x shared CPU, 256MB RAM, 1GB disk <- feel free to pick a beefier machine
|
||||
? Would you like to set up an Upstash Redis database now? No
|
||||
? Would you like to deploy now? No
|
||||
```
|
||||
|
||||
## Gather your secret environment variables
|
||||
|
||||
### Required
|
||||
|
||||
`MAGIC_LINK_SECRET`, `SESSION_SECRET` and `ENCRYPTION_KEY`
|
||||
|
||||
All of these secrets should be 16-byte random strings, which you can easily generate (and copy into your pasteboard) with the following command:
|
||||
|
||||
```sh
|
||||
openssl rand -hex 16 | pbcopy
|
||||
```
|
||||
|
||||
`LOGIN_ORIGIN` and `APP_ORIGIN`
|
||||
|
||||
Both of these secrets should be set to the base URL of your fly application. For example `https://trigger-v2-fly-demo.fly.dev`
|
||||
|
||||
### Optional
|
||||
|
||||
`AUTH_GITHUB_CLIENT_ID` and `AUTH_GITHUB_CLIENT_SECRET`
|
||||
|
||||
1. If you plan on logging in with GitHub auth, you'll need to create a GitHub OAuth app with the following configuration:
|
||||
|
||||

|
||||
|
||||
2. Once you register the application you'll need to click on the "Generate new client secret" button:
|
||||
|
||||

|
||||
|
||||
3. And then you can copy out the AUTH_GITHUB_CLIENT_ID and AUTH_GITHUB_CLIENT_SECRET:
|
||||
|
||||

|
||||
|
||||
`RESEND_API_KEY`, `FROM_EMAIL` and `REPLY_TO_EMAIL`
|
||||
|
||||
We use [Resend.com](https://resend.com) for email sending (including the magic-link signup/login system). They have a generous free tier of 100 emails a day that should be sufficient. Signup for Resend.com and enter the environment vars below
|
||||
|
||||
## Set the secrets
|
||||
|
||||
Call the `fly secrets set` command to stage the secrets to be used on first deploy:
|
||||
|
||||
```sh
|
||||
fly secrets set \
|
||||
ENCRYPTION_KEY=<random string> \
|
||||
MAGIC_LINK_SECRET=<random string> \
|
||||
SESSION_SECRET=<random string> \
|
||||
LOGIN_ORIGIN="https://<fly app name>.fly.dev" \
|
||||
APP_ORIGIN="https://<fly app name>.fly.dev" \
|
||||
FROM_EMAIL="Acme Inc. <hello@yourdomain.com>" \
|
||||
REPLY_TO_EMAIL="Acme Inc. <reply@yourdomain.com>" \
|
||||
RESEND_API_KEY=<your API Key> \
|
||||
AUTH_GITHUB_CLIENT_ID=<your GitHub OAuth Client ID> \
|
||||
AUTH_GITHUB_CLIENT_SECRET=<your GitHUb OAuth Client Secret>
|
||||
|
||||
Secrets are staged for the first deployment
|
||||
```
|
||||
|
||||
## Deploy
|
||||
|
||||
Now you can deploy to fly. Here we are setting the machine VM size to use 1 dedicated CPU core with 2 GB of memory, but you can run `fly platform vm-sizes` to see other options. The below app will cost about $30/month.
|
||||
|
||||
```sh
|
||||
fly deploy --vm-size performance-1x
|
||||
```
|
||||
|
||||
## Visit and create an account
|
||||
|
||||
Once deployed, you should be able to open `https://<your fly app name>.fly.dev/` in your browser and create an account, either using GitHub or a magic email link.
|
||||
|
||||
## Initialize your Next.js project
|
||||
|
||||
Next you can easily bootstrap your Next.js project to use your self-hosted instance of Trigger.dev.
|
||||
|
||||
First, `cd` into your Next.js project, then run the `@trigger.dev/cli init` command to initialize your Next.js project:
|
||||
|
||||
```sh
|
||||
npx @trigger.dev/cli@latest init -t "https://<your fly app name>.fly.dev"
|
||||
```
|
||||
|
||||
When it asks for your development API key, head over to your self-hosted Trigger.dev dashboard and select the initial project you created when signing up, and head to the `Environments & API Keys` page to copy your `dev` API key:
|
||||
|
||||

|
||||
|
||||
## Start your dev server
|
||||
|
||||
Run your Next.js project dev server with `npm run dev` and then in a new terminal window you will need to run the `@trigger.dev/cli dev` command to connect to your Trigger.dev instance and allow it to tunnel to your local Next.js server:
|
||||
|
||||
```sh
|
||||
npx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
At this point you should be able to navigate to your Trigger.dev dashboard and view your registered jobs
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: "Deploy to Render"
|
||||
description: "Deploy self hosted version of [Trigger.dev](https://trigger.dev) to [Render](https://render.com/)"
|
||||
---
|
||||
|
||||
You can use this [repository](https://github.com/triggerdotdev/render.com) as a jumping off point for deploying a self-hosted version of Trigger.dev on Render using the Trigger.dev public docker image located at `ghcr.io/triggerdotdev/trigger.dev:latest`
|
||||
|
||||
### Fork the repository mentioned above and change the app name
|
||||
|
||||
You should fork the repository before starting so you can make changes and commit them. For example, in render.yaml file you'll need to change the name under services to a unique name for your app.
|
||||
|
||||
### Create a new web service
|
||||
|
||||
1. Go to the Render dashboard.
|
||||
|
||||
2. Click on "New" in the top right corner.
|
||||
|
||||
3. Choose "Web service"
|
||||
|
||||

|
||||
|
||||
4. Click on "Connect With GitHub" (if you have not already done so). You will need to authorize Render to access your GitHub repositories.
|
||||
|
||||
5. Once connected, you will see a list of your repositories. Choose the repository that contains your project.
|
||||
|
||||
6. Render will detect the render.yaml file in your repository and auto fill the fields, add your app name now.
|
||||
|
||||

|
||||
|
||||
7. Scrolldown, click on advanced. Here you will need to add the environment variables
|
||||
|
||||

|
||||
|
||||
### Gather your secret environment variables
|
||||
|
||||
The process for generating and collecting the required environment variables is identical to the one described in the [Fly.io guide](/documentation/guides/self-hosting/flyio#gather-your-secret-environment-variables). Follow the steps there to generate and collect the required environment variables.
|
||||
|
||||
### Set the environment variables
|
||||
|
||||
The render.yaml file declares several environment variables that your app needs to run. These include the `ENCRYPTION_KEY`, `MAGIC_LINK_SECRET` and `SESSION_SECRET`, and others. You need to manually set the values of these environment variables in the Render dashboard:
|
||||
|
||||
1. Click on "Add Environment Variable" to add a new environment variable.
|
||||
2. Enter the key and value for each environment variable declared in your render.yaml file. The key should match the name of the environment variable in the render.yaml file.
|
||||

|
||||
|
||||
### Deploy
|
||||
|
||||
Render automatically deploys your service when you push to the connected GitHub repository. Alternatively, you can manually trigger a deployment from the Render dashboard by clicking "Deploy" in the "Deploys" tab.
|
||||
|
||||
### Initialize your Next.js project
|
||||
|
||||
Next, you can easily bootstrap your Next.js project to use your self-hosted instance of Trigger.dev.
|
||||
|
||||
First, cd into your Next.js project, then run the `@trigger.dev/cli init` command to initialize your Next.js project:
|
||||
|
||||
```sh
|
||||
npx @trigger.dev/cli@latest init -t "https://<your render app name>.onrender.com"
|
||||
```
|
||||
|
||||
When it asks for your development API key, head over to your self-hosted Trigger.dev dashboard and select the initial project you created when signing up, and head to the `Environments & API Keys` page to copy your `dev` API key:
|
||||
|
||||

|
||||
|
||||
### Start your dev server
|
||||
|
||||
Run your Next.js project dev server with `npm run dev` and then in a new terminal window you will need to run the `@trigger.dev/cli dev` command to connect to your Trigger.dev instance and allow it to tunnel to your local Next.js server:
|
||||
|
||||
```sh
|
||||
npx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
At this point you should be able to navigate to your Trigger.dev dashboard and view your registered jobs
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: "Testing Jobs"
|
||||
description: "You can test Jobs from the dashboard."
|
||||
---
|
||||
|
||||
<Accordion title="Finding the Test page">
|
||||
There's a tab on the Job page called **Test**. Or you can click the "Test" button in the top right of the page.
|
||||
|
||||

|
||||
|
||||
</Accordion>
|
||||
|
||||
## Your options when Testing
|
||||
|
||||

|
||||
|
||||
1. Select the environment you'd like the test to run against.
|
||||
2. Some Triggers provide example payloads that you can select from. This will populate the code editor below.
|
||||
3. When you're happy with the payload, click **Run test**.
|
||||
|
||||
## Identifying test runs
|
||||
|
||||
Tests have a label in the top-right of the Run page and a tick in the Test column of the Runs list.
|
||||
|
||||

|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: "Local platform"
|
||||
description: "Running the Trigger.dev platform locally requires tunneling to the internet."
|
||||
---
|
||||
|
||||
Note this is only relevant to you if you are [running the platform locally](/documentation/guides/self-hosting).
|
||||
|
||||
## How do I do it?
|
||||
|
||||
There are a few ways to do this, but we recommend using [ngrok](https://ngrok.com/). It's free and easy to use.
|
||||
|
||||
### Start ngrok
|
||||
|
||||
1. Install ngrok:
|
||||
|
||||
<CodeGroup>
|
||||
```sh Mac
|
||||
brew install ngrok/ngrok/ngrok
|
||||
```
|
||||
|
||||
```sh Windows
|
||||
choco install ngrok
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
2. Open a new terminal window/tab, you need to leave this running
|
||||
|
||||
3. Create an http tunnel at port 3030:
|
||||
|
||||
```sh
|
||||
ngrok http 3030
|
||||
```
|
||||
|
||||
4. Grab your forwarding address in the ngrok output:
|
||||
|
||||

|
||||
|
||||
### 2. Use the forwarding URL
|
||||
|
||||
Use the forwarding URL that ngrok gave you for the `LOGIN_ORIGIN` and `API_ORIGIN` environment variables for the docker container.
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: "API Keys and Personal Access Tokens"
|
||||
description: "Lots of APIs use API Keys or Personal Access Tokens to authenticate. This guide will show you how to use them."
|
||||
---
|
||||
|
||||
## 1. Create an Integration client
|
||||
|
||||
```ts
|
||||
//1. Import the Integration packages you want to use
|
||||
import { Github } from "@trigger.dev/github";
|
||||
import { OpenAI } from "@trigger.dev/openai";
|
||||
|
||||
//2. Create a new instance of the Integration client
|
||||
// GitHub uses personal access tokens so the param is called `token`
|
||||
const github = new Github({
|
||||
//this is used to identify the connection
|
||||
id: "github",
|
||||
token: process.env.GITHUB_TOKEN!,
|
||||
});
|
||||
|
||||
// OpenAI uses API keys so the param is called `apiKey`
|
||||
const openai = new OpenAI({
|
||||
//this is used to identify the connection
|
||||
id: "openai",
|
||||
apiKey: process.env.OPENAI_API_KEY!,
|
||||
});
|
||||
```
|
||||
|
||||
Note that we used `process.env.GITHUB_TOKEN` and `process.env.OPENAI_API_KEY`. They're environment variables, which are a way of not putting secret values directly in your code.
|
||||
|
||||
For Next.js, local environment variables usually live in a `.env.local` file in the root of the project.
|
||||
|
||||
```bash .env.local
|
||||
#...other variables above here
|
||||
GITHUB_TOKEN="github_pat_1234567890xxxxxxxxxxxxxxxxxxxx"
|
||||
OPENAI_API_KEY="sk-12345678xxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
```
|
||||
|
||||
## 2. Use the Integration client
|
||||
|
||||
There are two way to use Integrations in a Job:
|
||||
|
||||
- You can perform Tasks in the `run` function, by passing the Integration client into the `integrations` object.
|
||||
- You can use webhooks to Trigger a Job.
|
||||
|
||||
This example automatically assigns "matt-aitken" to any new issue in the `trigger.dev` repo (lucky him).
|
||||
|
||||
```ts
|
||||
new Job(client, {
|
||||
id: "assign-on-issue-opened",
|
||||
name: "Assign on Issue Opened",
|
||||
version: "0.1.0",
|
||||
//1. If you want to use the Integration in the run function, add it here
|
||||
integrations: { github },
|
||||
//2. If the Integration supports webhooks, you can use them here
|
||||
trigger: github.triggers.repo({
|
||||
event: events.onIssueOpened,
|
||||
owner: "triggerdotdev",
|
||||
repo: "trigger.dev",
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
//3. Because we add `github` to Integrations, it comes through to `io.github` here
|
||||
const assignee = await io.github.addIssueAssignees("add assignee", {
|
||||
owner: payload.repository.owner.login,
|
||||
repo: payload.repository.name,
|
||||
issueNumber: payload.issue.number,
|
||||
assignees: ["matt-aitken"],
|
||||
});
|
||||
|
||||
return assignee;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 3. Viewing connections in the dashboard
|
||||
|
||||
### The Integrations page
|
||||
|
||||
<Snippet file="integration-list.mdx" />
|
||||
|
||||
### Connected API Key Integration detail page
|
||||
|
||||

|
||||
|
||||
Some useful things on this page
|
||||
|
||||
1. The `id` that you gave the connection when you defined it in your code
|
||||
2. The Jobs that are using this connection
|
||||
|
||||
## References
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="View Integrations" icon="grid-2" href="/integrations">
|
||||
Trigger.dev integrates with a wide range of services.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: "OAuth"
|
||||
description: "Use OAuth to authenticate your team or to add Integrations to your product so your users can connect their accounts."
|
||||
---
|
||||
|
||||
## 1. Create an Integration client (in code)
|
||||
|
||||
```ts
|
||||
//1. Import the Integration packages you want to use
|
||||
import { Slack } from "@trigger.dev/slack";
|
||||
import { Github } from "@trigger.dev/github";
|
||||
|
||||
//2. Create a new instance of the Integration client
|
||||
const slack = new Slack({
|
||||
//this is used to identify the connection
|
||||
id: "slack",
|
||||
});
|
||||
|
||||
//GitHub supports OAuth (as well as Personal Access Tokens)
|
||||
const github = new Github({
|
||||
//this is used to identify the connection
|
||||
id: "github",
|
||||
});
|
||||
```
|
||||
|
||||
When using OAuth, you only need to specify the `id`.
|
||||
|
||||
## 2. Use the Integration client
|
||||
|
||||
There are two way to use Integrations in a Job:
|
||||
|
||||
- You can perform Tasks in the `run` function, by passing the Integration client into the `integrations` object.
|
||||
- You can use webhooks to Trigger a Job.
|
||||
|
||||
This example send a Slack message when someone stars the `trigger.dev` GitHub repo 🤩.
|
||||
|
||||
```ts
|
||||
new Job(client, {
|
||||
id: "star-slack-notification",
|
||||
name: "New Star Slack Notification",
|
||||
version: "0.1.0",
|
||||
//1. If you want to use the Integration in the run function, add it here
|
||||
integrations: { slack },
|
||||
//2. If the Integration supports webhooks, you can use them here
|
||||
trigger: github.triggers.repo({
|
||||
event: events.onNewStar,
|
||||
owner: "triggerdotdev",
|
||||
repo: "empty",
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
//3. Because we add `slack` to Integrations, it comes through to `io.slack` here
|
||||
const response = await io.slack.postMessage("Slack star", {
|
||||
text: `${payload.sender.login} starred ${payload.repository.full_name}.\nTotal: ${payload.repository.stargazers_count}⭐️`,
|
||||
channel: "C04GWUTDC3W",
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 3. Creating the OAuth connection in the dashboard
|
||||
|
||||
Now you need to setup the OAuth client in the dashboard. You will use the `id` that you specified in your code to associate them.
|
||||
|
||||
1. Go to the "Integrations page" in your dashboard. Click the Integration you want to setup.
|
||||

|
||||
|
||||
2. Select OAuth as the authentication type.
|
||||

|
||||
|
||||
3. Select "Developer" as the user type.
|
||||

|
||||
|
||||
4. Enter the `id` that you specified in your code. Select the scopes that you want and enter a unique title.
|
||||

|
||||
|
||||
5. Click the Connect button, it will take you through the OAuth flow.
|
||||
|
||||
## 4. Viewing your connection clients
|
||||
|
||||
### The Integrations page
|
||||
|
||||
<Snippet file="integration-list.mdx" />
|
||||
|
||||
### Connected OAuth integration detail page
|
||||
|
||||

|
||||
|
||||
Some useful things on this page
|
||||
|
||||
1. The `id` that you gave the connection when you defined it in your code
|
||||
2. The Jobs that are using this connection
|
||||
3. All the connections associated with this Integration client (there will be more than one if you're authenticated your users)
|
||||
4. The scopes that this connection has access to
|
||||
|
||||
## References
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="View Integrations" icon="grid-2" href="/integrations">
|
||||
Trigger.dev integrates with a wide range of services.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,167 @@
|
||||
---
|
||||
title: "Using Integrations"
|
||||
description: "How to use Integrations"
|
||||
---
|
||||
|
||||
<Note>
|
||||
You can use any API in your Jobs by using existing Node.js SDKs or HTTP
|
||||
requests. Integrations just make it much easier especially when you want to
|
||||
use OAuth. And you get great logging.
|
||||
</Note>
|
||||
|
||||
[Integrations](/documentation/concepts/integrations) allow you to quickly use APIs, including webhooks and Tasks.
|
||||
|
||||
## Authentication
|
||||
|
||||
There are two ways to authenticate Integrations, OAuth and API Keys/Access Tokens.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="API Keys/Access Tokens"
|
||||
icon="key"
|
||||
href="/documentation/guides/using-integrations-apikeys"
|
||||
>
|
||||
Use API Keys or Access Tokens to connect an Integration
|
||||
</Card>
|
||||
<Card
|
||||
title="OAuth"
|
||||
icon={
|
||||
<svg viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M50.5013 0C49.1646 0 47.7861 0.0417711 46.3659 0.125313C43.609 0.292398 40.685 0.75188 37.594 1.50376C34.67 2.25564 32.1637 3.09106 30.0752 4.01002C26.9006 5.43024 23.6842 7.26817 20.4261 9.52381C16.7502 12.1136 13.4921 15.2464 10.6516 18.9223C7.81119 22.5982 5.51378 26.6082 3.7594 30.9524L3.13283 32.4561C2.38095 34.2941 1.8797 35.6725 1.62907 36.5915C0.543024 40.3509 0 44.4444 0 48.8722C0 52.9657 0.37594 56.8505 1.12782 60.5263C2.96575 68.8805 6.39098 76.0234 11.4035 81.9549C15.7477 87.1345 21.5539 91.6458 28.8221 95.4887C32.8321 97.5773 37.406 98.9766 42.5439 99.6867C47.6817 100.397 52.8822 100.355 58.1454 99.5614C63.4085 98.7677 68.2122 97.2849 72.5564 95.1128C80.0752 91.2698 86.4244 85.4636 91.604 77.6942C94.1938 73.8513 96.1988 69.6742 97.619 65.1629C99.2063 60.1504 100 54.9708 100 49.6241C100 44.8621 99.1228 39.8914 97.3684 34.7118C95.9482 30.3676 94.0267 26.3158 91.604 22.5564C87.3434 15.7895 81.9967 10.4845 75.5639 6.6416C68.2122 2.21387 59.858 0 50.5013 0ZM46.2406 23.8095H53.0075C54.3442 23.8095 55.5556 24.2063 56.6416 25C57.7277 25.7936 58.4795 26.817 58.8972 28.0702L72.1805 68.1704C72.7652 69.8413 72.6608 71.4494 71.8672 72.995C71.0735 74.5405 69.883 75.5639 68.2957 76.0652C67.6274 76.2322 66.9591 76.3158 66.2907 76.3158C64.9541 76.3158 63.7427 75.9398 62.6566 75.188C61.5706 74.4361 60.8187 73.3918 60.401 72.0551L57.5188 62.9073H42.4812L39.599 72.0551C39.1813 73.3083 38.4294 74.3317 37.3434 75.1253C36.2573 75.919 35.0459 76.3158 33.7093 76.3158C33.0409 76.3158 32.4144 76.2322 31.8296 76.0652C30.1587 75.5639 28.9265 74.5614 28.1328 73.0576C27.3392 71.5539 27.193 69.9666 27.6942 68.2957L40.3509 28.1955C40.7686 26.8588 41.5205 25.7936 42.6065 25C43.6926 24.2063 44.9039 23.8095 46.2406 23.8095Z"
|
||||
fill="#818cf8"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
href="/documentation/guides/using-integrations-oauth"
|
||||
>
|
||||
Use OAuth to connect an Integration for your team or your users
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Using for Jobs & Tasks
|
||||
|
||||
You must pass Integrations into your Job to run integration tasks. Passed in Integrations will be available on the `io` object in the `run()` function with the same name as the key. For example:
|
||||
|
||||
<Snippet file="how-to-pass-integrations.mdx" />
|
||||
|
||||
Both the `postMessage` and `addIssueLabels` functions above are implemented as an "Authenticated Task" that is defined inside the Integration, where the first argument is always the task [key](/documentation/concepts/tasks#task-keys) and the second argument is the parameters for the task. For example, here is how you would call the `postMessage` function above:
|
||||
|
||||
```ts
|
||||
client.defineJob({
|
||||
// ...
|
||||
integrations: {
|
||||
slack,
|
||||
},
|
||||
run: async (payload, io, ctx) => {
|
||||
const response = await io.slack.postMessage("✋", {
|
||||
channel: "C04GWUTDC3W",
|
||||
text: "My first Slack message",
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The above code will create a [Task](/documentation/concepts/tasks) that will use the authentication configured for the specified Slack integration.
|
||||
|
||||
If the integration does not support a specific task function that you want to use, you can use the `runTask` function to get access to the authenticated client.
|
||||
|
||||
For example, the Slack integration doesn't expose an Authenticated Task function for deleting a message, but you can use the `chat.delete` function provided by the [@slack/web-api package](https://slack.dev/node-slack-sdk/web-api) directly:
|
||||
|
||||
```ts
|
||||
client.defineJob({
|
||||
// ...
|
||||
integrations: {
|
||||
slack,
|
||||
},
|
||||
run: async (payload, io, ctx) => {
|
||||
const response = await io.slack.postMessage("✋", {
|
||||
channel: "C04GWUTDC3W",
|
||||
text: "My first Slack message",
|
||||
});
|
||||
|
||||
await io.wait("⏰", 24 * 60 * 60 * 1000); // wait 24 hours
|
||||
|
||||
await io.slack.runTask("delete", async (slack) => {
|
||||
return slack.chat.delete({
|
||||
channel: "C04GWUTDC3W",
|
||||
ts: response.ts!,
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You can optionally pass a third parameter to `runTask` to specify the task parameters:
|
||||
|
||||
```ts
|
||||
await io.slack.runTask(
|
||||
"delete",
|
||||
async (slack) => {
|
||||
return slack.chat.delete({
|
||||
channel: "C04GWUTDC3W",
|
||||
ts: response.ts!,
|
||||
});
|
||||
},
|
||||
{
|
||||
name: "Delete message",
|
||||
properties: [{ label: "Message", text: response.ts }],
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
View the [runTask](/sdk/io/runtask#parameters) reference for more information.
|
||||
|
||||
## Using outside of Jobs
|
||||
|
||||
If you want to use integrations that support "local auth" only (e.g. API keys, like Stripe and Supabase) outside of a Job you can use the `.native` property on the integration to get direct access to the client. For example:
|
||||
|
||||
```ts stripe.ts
|
||||
import { Stripe } from "@trigger.dev/stripe";
|
||||
|
||||
const stripe = new Stripe({
|
||||
id: "stripe",
|
||||
apiKey: process.env.STRIPE_SECRET_KEY!
|
||||
});
|
||||
|
||||
async function createCustomer() {
|
||||
await stripe.native.customers.create({
|
||||
// ... customer attributes go here
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Using for Triggers
|
||||
|
||||
Some integrations provide triggers that you can use to start a Job. For example, the GitHub integration provides a `push` trigger that will start a Job when a new commit is pushed to a repository:
|
||||
|
||||
```ts
|
||||
import { Github, events } from "@trigger.dev/github";
|
||||
|
||||
const github = new Github({
|
||||
id: "github",
|
||||
token: process.env.GITHUB_TOKEN!,
|
||||
});
|
||||
|
||||
client.defineJob({
|
||||
id: "github-integration-on-push",
|
||||
name: "GitHub Integration - On Push",
|
||||
version: "0.1.0",
|
||||
trigger: github.triggers.repo({
|
||||
event: events.onPush,
|
||||
owner: "triggerdotdev",
|
||||
repo: "trigger.dev",
|
||||
}),
|
||||
run: async (payload, io, ctx) => {
|
||||
// do something on push
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Behind the scenes, our `@trigger.dev/github` integration will create a webhook on your repository that will call our API when a new push event is received. We will then start your Job with the payload from the push event.
|
||||
|
||||
<Note>
|
||||
If you are just using an integration to trigger a job but not using
|
||||
authenticated tasks inside the job run, there is no need to pass the
|
||||
integration in the job `integrations` option.
|
||||
</Note>
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: "Video walkthrough"
|
||||
description: "Go from zero to a working Job in your Next.js app in 10 minutes."
|
||||
---
|
||||
|
||||
The Job subscribes to new GitHub issues and if the issues haven't been dealt with after 24 hours a Slack reminder is sent and they're assigned to someone.
|
||||
|
||||
You can view the [source code here](https://github.com/triggerdotdev/examples/tree/main/github-issue-reminder).
|
||||
|
||||
<iframe
|
||||
className="w-full aspect-video"
|
||||
src="https://www.youtube.com/embed/uocBQt2HeQo"
|
||||
title="Create a serverless background job in 10 mins"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
|
||||
We cover how to:
|
||||
|
||||
- get around serverless timeouts using Trigger.dev.
|
||||
- use the CLI to get setup.
|
||||
- run the Job locally.
|
||||
- create a GitHub onIssueOpened Trigger.
|
||||
- test the Job.
|
||||
- use Integrations inside the Job, including using API Keys (GitHub) and OAuth (Slack).
|
||||
- write the main logic of the Job.
|
||||
- use rerun to quickly iterate.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: "Viewing Runs"
|
||||
description: "See every Task in every Run so you can tell exactly what happened."
|
||||
---
|
||||
|
||||
## The Runs list
|
||||
|
||||
The main page for a Job is a paginated table of Runs. The newest Runs are at the top.
|
||||
|
||||

|
||||
|
||||
<Note>Filtering Runs is coming soon</Note>
|
||||
|
||||
## Run page
|
||||
|
||||

|
||||
|
||||
You can view the details of the Trigger, all the Tasks and the return value of the Run by clicking the elements in the timeline of the left hand side.
|
||||
|
||||
Some Tasks have subtasks which are collapsed by default but can be opened by clicking them.
|
||||
@@ -0,0 +1,308 @@
|
||||
---
|
||||
title: "Zod Guide"
|
||||
sidebarTitle: "Zod"
|
||||
description: "TypeScript-first schema validation with static type inference"
|
||||
---
|
||||
|
||||
## Intro
|
||||
|
||||
Zod is a fantastic utility package by [@colinhacks](https://twitter.com/colinhacks) that allows for defining runtime schema validation and type-safety.
|
||||
|
||||
We use it [extensively](https://github.com/search?q=repo%3Atriggerdotdev%2Ftrigger.dev+%22zod%22%3B&type=code) internally at Trigger.dev.
|
||||
|
||||
But there are a few places where we ask you to provide us with a Zod schema, for example when defining your own [events](/documentation/concepts/triggers/events):
|
||||
|
||||
```ts
|
||||
new Job(client, {
|
||||
id: "new-user",
|
||||
name: "New user",
|
||||
version: "0.1.0",
|
||||
//the eventTrigger uses zod to define the schema
|
||||
trigger: eventTrigger({
|
||||
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 (payload, io, ctx) => {
|
||||
//do stuff
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
So it will help to know a little about Zod and how to use it. We definitely recommend the well written [Zod README](https://github.com/colinhacks/zod#readme) but we've included a short primer below.
|
||||
|
||||
<Tip>
|
||||
Wherever we require you to pass in a Zod schema, you can always start with
|
||||
`z.any()` which accepts `any` type and then add more strict validations later.
|
||||
</Tip>
|
||||
|
||||
## Basic Usage
|
||||
|
||||
There are three main steps to using Zod:
|
||||
|
||||
1. Define a schema
|
||||
|
||||
```ts
|
||||
import { z } from "zod";
|
||||
|
||||
const mySchema = z.object({
|
||||
name: z.string(),
|
||||
email: z.string(),
|
||||
paidPlan: z.boolean(),
|
||||
});
|
||||
```
|
||||
|
||||
2. Infer TypeScript types from the schema
|
||||
|
||||
```ts
|
||||
type MySchema = z.infer<typeof mySchema>;
|
||||
```
|
||||
|
||||
3. Validate data against the schema
|
||||
|
||||
```ts
|
||||
const data: unknown = {
|
||||
name: "Eric",
|
||||
email: "eric@trigger.dev",
|
||||
paidPlan: true,
|
||||
};
|
||||
|
||||
const result = mySchema.parse(data);
|
||||
```
|
||||
|
||||
When using Zod with Trigger.dev, you'll only really need to do the first step, and by passing it to us (through the `schema` property of the `customEvent` function), we'll do the second and third steps for you.
|
||||
|
||||
## Defining Schemas
|
||||
|
||||
### Primitives
|
||||
|
||||
Zod schemas are a way to define the shape of an object. They can be as simple as a single type, or as complex as a nested object.
|
||||
|
||||
```ts
|
||||
// Primitives
|
||||
z.string();
|
||||
z.number();
|
||||
z.boolean();
|
||||
z.date();
|
||||
z.undefined();
|
||||
z.null();
|
||||
```
|
||||
|
||||
Any schema can be marked as optional, which means the schema can be `undefined` or `null`:
|
||||
|
||||
```ts
|
||||
z.string().optional();
|
||||
```
|
||||
|
||||
Schemas can also be marked optional by providing a default value:
|
||||
|
||||
```ts
|
||||
const optionalString = z.string().default("default value");
|
||||
|
||||
const value = optionalString.parse(undefined); // value === "default value"
|
||||
```
|
||||
|
||||
If you need to allow a value to be `null`, you can use `nullable()`:
|
||||
|
||||
```ts
|
||||
const nullableString = z.string().nullable();
|
||||
|
||||
const value = nullableString.parse(null);
|
||||
```
|
||||
|
||||
You can also use Zod to coerce primites into other types. For example, you can coerce a string into a number:
|
||||
|
||||
```ts
|
||||
const numberString = z.coerce.number();
|
||||
|
||||
const value = numberString.parse("123"); // value === 123
|
||||
```
|
||||
|
||||
The following primitives are supported:
|
||||
|
||||
```ts
|
||||
z.coerce.string();
|
||||
z.coerce.number();
|
||||
z.coerce.boolean();
|
||||
z.coerce.bigint();
|
||||
z.coerce.date();
|
||||
```
|
||||
|
||||
Coercing dates are especially useful when you are receiving a `string` from an API and want to convert it to a JavaScript `Date` object:
|
||||
|
||||
```ts
|
||||
const date = z.coerce.date();
|
||||
|
||||
const value = date.parse("2021-01-01T00:00:00.000Z"); // value === Date object
|
||||
```
|
||||
|
||||
### Objects
|
||||
|
||||
Object schemas are the most common type of schema. They allow you to define the shape of an object, and the types of each property.
|
||||
|
||||
```ts
|
||||
const mySchema = z.object({
|
||||
name: z.string(),
|
||||
email: z.string(),
|
||||
paidPlan: z.boolean(),
|
||||
});
|
||||
```
|
||||
|
||||
All properties are required by default, although you can make them all optional using `partial()`:
|
||||
|
||||
```ts
|
||||
const mySchema = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
email: z.string(),
|
||||
paidPlan: z.boolean(),
|
||||
})
|
||||
.partial();
|
||||
```
|
||||
|
||||
You can also make individual properties optional:
|
||||
|
||||
```ts
|
||||
const mySchema = z.object({
|
||||
name: z.string(),
|
||||
email: z.string(),
|
||||
paidPlan: z.boolean().optional(),
|
||||
});
|
||||
```
|
||||
|
||||
By default an object schema will strip out any extra properties that are not defined in the schema. You can disable this behavior using `passthrough()`:
|
||||
|
||||
```ts
|
||||
const mySchema = z.object({
|
||||
name: z.string(),
|
||||
});
|
||||
|
||||
mySchema.parse({ name: "Eric", email: "eric@trigger.dev" }); // { name: "Eric" }
|
||||
mySchema.passthrough().parse({ name: "Eric", email: "eric@trigger.dev" }); // { name: "Eric", email: "eric@trigger.dev" }
|
||||
```
|
||||
|
||||
Or you can use `strict()` to make the schema throw an error if there are any extra properties:
|
||||
|
||||
```ts
|
||||
const mySchema = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
mySchema.parse({ name: "Eric", email: "eric@trigger.dev" }); // throws error
|
||||
```
|
||||
|
||||
Zod includes a few useful object schema utilities to help with reusing schemas, `extends()` and `merge()`:
|
||||
|
||||
```ts
|
||||
const baseSchema = z.object({
|
||||
name: z.string(),
|
||||
});
|
||||
|
||||
const extendedSchema = baseSchema.extend({
|
||||
email: z.string(),
|
||||
});
|
||||
|
||||
const mergedSchema = baseSchema.merge(
|
||||
z.object({
|
||||
email: z.string(),
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
You can also use `pick()` and `omit()` to create a new schema that only includes or excludes certain properties:
|
||||
|
||||
```ts
|
||||
const mySchema = z.object({
|
||||
name: z.string(),
|
||||
email: z.string(),
|
||||
paidPlan: z.boolean(),
|
||||
});
|
||||
|
||||
const pickedSchema = mySchema.pick({ name: true, email: true });
|
||||
const omittedSchema = mySchema.omit({ paidPlan: true });
|
||||
```
|
||||
|
||||
### Arrays
|
||||
|
||||
You can specify the schema of an array using `z.array()`:
|
||||
|
||||
```ts
|
||||
z.array(z.string()); // string[]
|
||||
z.array(z.number()); // number[]
|
||||
z.array(z.object({ name: z.string() })); // Array<{ name: string }>
|
||||
```
|
||||
|
||||
You can also specify the type of array that has a fixed number of elements using `z.tuple()`:
|
||||
|
||||
```ts
|
||||
z.tuple([z.string(), z.number(), z.boolean()]); // [string, number, boolean]
|
||||
```
|
||||
|
||||
### Unions
|
||||
|
||||
You can specify a union of schemas using `z.union()`:
|
||||
|
||||
```ts
|
||||
z.union([z.string(), z.number(), z.boolean()]); // string | number | boolean
|
||||
```
|
||||
|
||||
Discriminating unions are also supported, and especially useful when paired with type narrowing:
|
||||
|
||||
```ts
|
||||
const mySchema = z.discriminatingUnion("type", [
|
||||
z.object({
|
||||
type: z.literal("a"),
|
||||
data: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("b"),
|
||||
data: z.number(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const value = mySchema.parse({ type: "a", data: "hello" });
|
||||
|
||||
if (type.a) {
|
||||
// value is { type: "a", data: string }
|
||||
} else if (type.b) {
|
||||
// value is { type: "b", data: number }
|
||||
}
|
||||
```
|
||||
|
||||
### Records
|
||||
|
||||
You can specify a record of schemas using `z.record()`, useful for when you have a map of values but don't care about the keys:
|
||||
|
||||
```ts
|
||||
z.record(z.string()); // Record<string, string>
|
||||
z.record(z.number()); // Record<string, number>
|
||||
```
|
||||
|
||||
### JSON type
|
||||
|
||||
If you want to accept any valid JSON value, you can use the following schema:
|
||||
|
||||
```ts
|
||||
const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
||||
type Literal = z.infer<typeof literalSchema>;
|
||||
type Json = Literal | { [key: string]: Json } | Json[];
|
||||
const jsonSchema: z.ZodType<Json> = z.lazy(() =>
|
||||
z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)])
|
||||
);
|
||||
|
||||
jsonSchema.parse(data);
|
||||
```
|
||||
|
||||
Hat tip to [ggoodman](https://github.com/ggoodman) for this one.
|
||||
|
||||
## Resources
|
||||
|
||||
Matt Pocock [@mattpocock](https://twitter.com/mattpocockuk) has a great free Zod Tutorial up on [Total Typescript](https://www.totaltypescript.com/tutorials/zod) that covers the basics of Zod.
|
||||
|
||||
Easily generate Zod schemas from [JSON](https://transform.tools/json-to-zod), [JSON Schemas](https://transform.tools/json-schema-to-zod), or [TypeScript](https://transform.tools/typescript-to-zod) types.
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: "Welcome to the Trigger.dev documentation."
|
||||
---
|
||||
|
||||
Trigger.dev is an open source framework for creating long-running Jobs directly in your Next.js app with API Integrations, webhooks, scheduling and delays. You can reliably run Jobs that wouldn't normally work in serverless environments (like Vercel) because of timeouts.
|
||||
|
||||
You can use [Trigger.dev Cloud](https://cloud.trigger.dev) or [Self-host Trigger.dev](/documentation/guides/self-hosting) on your own infrastructure.
|
||||
|
||||
<Note>
|
||||
Trigger.dev v2 currently only supports serverless. During our beta we will add
|
||||
[support for long-running
|
||||
servers](https://github.com/triggerdotdev/trigger.dev/issues/244).
|
||||
</Note>
|
||||
|
||||
<CardGroup>
|
||||
<Card title="Quick start" icon="person-running-fast" href="quickstart">
|
||||
Get started in 5 minutes.
|
||||
</Card>
|
||||
<Card
|
||||
title="Video walkthrough"
|
||||
icon="video"
|
||||
href="/documentation/guides/video-walkthrough"
|
||||
>
|
||||
Go from zero to a working Job in your Next.js app in 10 minutes.
|
||||
</Card>
|
||||
<Card
|
||||
title="What is Trigger.dev"
|
||||
icon="wand-magic-sparkles"
|
||||
href="/documentation/concepts/what-is-triggerdotdev"
|
||||
>
|
||||
Learn more about how Trigger.dev works and how it can help you.
|
||||
</Card>
|
||||
<Card title="Integrations" icon="grid-2" href="/integrations">
|
||||
Trigger.dev integrates with a wide range of services.
|
||||
</Card>
|
||||
<Card title="Examples" icon="slot-machine" href="/examples">
|
||||
One of the quickest ways to learn how Trigger.dev works is to view some
|
||||
example Jobs.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Getting help
|
||||
|
||||
We'd love to hear from you or give you a hand getting started. Here are some ways to get in touch with us. We'd also ❤️ your support.
|
||||
|
||||
<CardGroup>
|
||||
<Card
|
||||
title="Join our Discord server"
|
||||
icon="discord"
|
||||
href="https://discord.gg/kA47vcd8P6"
|
||||
color="#5865F2"
|
||||
>
|
||||
The #help-and-questions channel is a great place to get help with any
|
||||
questions about Trigger.dev.
|
||||
</Card>
|
||||
<Card
|
||||
title="Follow us on Twitter"
|
||||
icon="twitter"
|
||||
href="https://twitter.com/triggerdotdev"
|
||||
color="#1DA1F2"
|
||||
>
|
||||
Follow us on Twitter to get the latest updates and news.
|
||||
</Card>
|
||||
<Card
|
||||
title="Schedule a call"
|
||||
icon="phone"
|
||||
href="https://cal.com/team/triggerdotdev/support"
|
||||
>
|
||||
Arrange a call with one of the founders. We can help answer questions, build
|
||||
API Integrations for you and give 1-on-1 help building your first Job.
|
||||
</Card>
|
||||
<Card
|
||||
title="Give us a star on GitHub"
|
||||
icon="star"
|
||||
href="https://github.com/triggerdotdev/trigger.dev"
|
||||
color="#fbbf24"
|
||||
>
|
||||
Check us out at triggerdotdev/trigger.dev
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,236 @@
|
||||
---
|
||||
title: "Quick Start"
|
||||
description: "Start creating Jobs in 5 minutes"
|
||||
---
|
||||
|
||||
This quick start guide will get you up and running with Trigger.dev.
|
||||
|
||||
<Accordion title="Don't have a Next.js project yet to add Trigger.dev to? No problem, you can complete the Quick Start using a blank Next.js project:">
|
||||
Create a blank project by running the `create-next-app` command in your terminal:
|
||||
|
||||
```bash
|
||||
npx create-next-app@latest
|
||||
```
|
||||
|
||||
Trigger.dev works with either the Pages or App Router configuration.
|
||||
|
||||
</Accordion>
|
||||
|
||||
## Create a Trigger.dev account
|
||||
|
||||
You can either
|
||||
|
||||
- Use the [Trigger.dev Cloud](https://cloud.trigger.dev) (we're currently in private beta).
|
||||
- Or [self-host](/documentation/guides/self-hosting) the service.
|
||||
|
||||
### Create your first project
|
||||
|
||||
Once you've created an account, follow the steps to:
|
||||
|
||||
1. Complete your account details.
|
||||
2. Create your first Organization and Project.
|
||||
|
||||
### Getting an API key
|
||||
|
||||
1. Go to the "Environments & API Keys" page in your project.
|
||||

|
||||
|
||||
2. Copy the `DEV` API key.
|
||||

|
||||
|
||||
## Run the CLI `init` command
|
||||
|
||||
The easiest way to get started it to use the CLI. It will add Trigger.dev to your existing Next.js project, setup a route and give you an example file.
|
||||
|
||||
In a terminal window run:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash npm
|
||||
npx @trigger.dev/cli@latest init
|
||||
```
|
||||
|
||||
```bash pnpm
|
||||
pnpm dlx @trigger.dev/cli@latest init
|
||||
```
|
||||
|
||||
```bash yarn
|
||||
yarn dlx @trigger.dev/cli@latest init
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
It will ask you a few questions
|
||||
|
||||
1. Are you using the [Trigger.dev Cloud](https://trigger.dev) or [self-hosting](/documentation/guides/self-hosting)? You're probably using the cloud.
|
||||
2. Enter your development API key. Enter the key you copied earlier.
|
||||
3. Enter a unique ID for your endpoint (you can just use the default by hitting enter)
|
||||
|
||||
## Run your Next.js site
|
||||
|
||||
Make sure your Next.js site is running locally, we will connect to it to register your Jobs.
|
||||
|
||||
<Warning>You must leave this running for the rest of the steps.</Warning>
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash npm
|
||||
npm run dev
|
||||
```
|
||||
|
||||
```bash pnpm
|
||||
pnpm run dev
|
||||
```
|
||||
|
||||
```bash yarn
|
||||
yarn run dev
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Run the CLI `dev` command
|
||||
|
||||
The CLI `dev` command allows the Trigger.dev service to send messages to your Next.js site. This is required for registering Jobs, triggering them and running tasks. To achieve this it creates a tunnel (using [ngrok](https://ngrok.com/)) so Trigger.dev can send messages to your machine.
|
||||
|
||||
You should leave the `dev` command running when you're developing.
|
||||
|
||||
In a **new terminal window or tab** run:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash npm
|
||||
npx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
```bash pnpm
|
||||
pnpm dlx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
```bash yarn
|
||||
yarn dlx @trigger.dev/cli@latest dev
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
<br />
|
||||
<Note>
|
||||
You can optionally pass the port if you're not running on 3000 by adding
|
||||
`--port 3001` to the end
|
||||
</Note>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Experiencing an error? This could be due to middleware.">
|
||||
Instructions of how to resolve any issues due to middleware [here](https://trigger.dev/docs/documentation/guides/platforms/nextjs#middleware)
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Advanced: Run your Next.js server together with the CLI">
|
||||
You can modify your `package.json` to run both the Next.js server and the CLI `dev` command together.
|
||||
|
||||
1. Install the `concurrently` package:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash npm
|
||||
npm install concurrently --save-dev
|
||||
```
|
||||
|
||||
```bash pnpm
|
||||
pnpm install concurrently --save-dev
|
||||
```
|
||||
|
||||
```bash yarn
|
||||
yarn add concurrently --dev
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
2. Modify your `package.json` file's `dev` script.
|
||||
|
||||
```json package.json
|
||||
...
|
||||
"scripts": {
|
||||
"dev": "concurrently --kill-others npm:dev:*",
|
||||
"dev:next": "next dev",
|
||||
"dev:trigger": "npx @trigger.dev/cli dev",
|
||||
...
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Your first job
|
||||
|
||||
The CLI init command created a simple Job for you. There will be a new file either `api/trigger/route.ts` or `pages/api/trigger.ts`.
|
||||
|
||||
In there is this Job:
|
||||
|
||||
```typescript
|
||||
//Job definition – uses the client
|
||||
new Job(client, {
|
||||
// 1. Metadata
|
||||
id: "example-job",
|
||||
name: "Example Job",
|
||||
version: "0.0.1",
|
||||
// 2. Trigger
|
||||
trigger: eventTrigger({
|
||||
name: "example.event",
|
||||
}),
|
||||
// 3. Run function
|
||||
run: async (payload, io, ctx) => {
|
||||
// do something
|
||||
await io.logger.info("Hello world!", { payload });
|
||||
|
||||
return {
|
||||
message: "Hello world!",
|
||||
};
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If you navigate to your Trigger.dev project you will see this Job in the "Jobs" section:
|
||||
|
||||

|
||||
|
||||
## Triggering the Job
|
||||
|
||||
There are two way to trigger this Job.
|
||||
|
||||
1. Use the "Test" functionality in the dashboard.
|
||||
2. Use the Trigger.dev API (either via our SDK or a web request)
|
||||
|
||||
### "Testing" from the dashboard
|
||||
|
||||
Click into the Job and then open the "Test" tab. You should see this page:
|
||||
|
||||

|
||||
|
||||
This Job doesn't have a payload schema (meaning it takes an empty object), so you can simple click the "Run test" button.
|
||||
|
||||
Congratulations, you should get redirected so you can see your first Run!
|
||||
|
||||
## What's next?
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Write your first Job"
|
||||
icon="hexagon-plus"
|
||||
href="/documentation/guides/create-a-job"
|
||||
>
|
||||
A Guide for how to create your first real Job
|
||||
</Card>
|
||||
<Card
|
||||
title="What is Trigger.dev"
|
||||
icon="wand-magic-sparkles"
|
||||
href="/documentation/concepts/what-is-triggerdotdev"
|
||||
>
|
||||
Learn more about how Trigger.dev works and how it can help you.
|
||||
</Card>
|
||||
<Card title="Examples" icon="slot-machine" href="/examples">
|
||||
One of the quickest ways to learn how Trigger.dev works is to view some
|
||||
example Jobs.
|
||||
</Card>
|
||||
<Card title="Get help" icon="hire-a-helper" href="/documentation/get-help">
|
||||
Struggling getting setup or have a question? We're here to help.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: "Roadmap"
|
||||
description: "Coming changes to Trigger.dev"
|
||||
---
|
||||
|
||||
## Next up
|
||||
|
||||
Features and Integrations we'll be working on next.
|
||||
|
||||
#### Features
|
||||
|
||||
- Trigger.dev Connect: authenticate your users so you can quickly add Integrations to your app.
|
||||
- Vercel Integration
|
||||
- Error alerts: get notified when your Jobs fail or don't start.
|
||||
- Filtering Runs (e.g. by status)
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Examples Repository
|
||||
description: "Pre-built Next.js projects with Jobs."
|
||||
---
|
||||
|
||||
We have an [examples GitHub repo](https://github.com/triggerdotdev/examples) that we add to all the time. It's a great place to start if you're looking for inspiration.
|
||||
|
||||
Instructions on how to run each of the below projects are included in their respective READMEs (linked below).
|
||||
|
||||
| Name | Description | Integrations |
|
||||
| -------------------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------- |
|
||||
| [Delays](https://github.com/triggerdotdev/examples/tree/main/delays) | A Next.js project containing Jobs using delays | N/A |
|
||||
| [Scheduled](https://github.com/triggerdotdev/examples/tree/main/scheduled) | A Next.js project containing interval and cron scheduled Jobs | N/A |
|
||||
| [GitHub](https://github.com/triggerdotdev/examples/tree/main/github) | A Next.js project containing GitHub Jobs | [GitHub](/integrations/apis/github) |
|
||||
| [OpenAI](https://github.com/triggerdotdev/examples/tree/main/openai) | A Next.js project containing OpenAI Jobs | [OpenAI](/integrations/apis/openai) |
|
||||
| [Resend](https://github.com/triggerdotdev/examples/tree/main/resend) | A Next.js project containing Resend Jobs | [Resend](/integrations/apis/resend) |
|
||||
| [Slack](https://github.com/triggerdotdev/examples/tree/main/slack) | A Next.js project containing Slack Jobs | [Slack](integrations/apis/slack) |
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Example Jobs
|
||||
description: "An ever-growing list of example Jobs which you can use to get started with Trigger.dev."
|
||||
---
|
||||
|
||||
<Info>
|
||||
If you are using integrations, you'll need set up authentication either using
|
||||
OAuth or API keys / access tokens. You can find out how to do that in the
|
||||
[integrations section](/integrations).
|
||||
</Info>
|
||||
|
||||
| Job (code in link) | Description | Integrations used |
|
||||
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| [Basic delay](https://github.com/triggerdotdev/examples/blob/main/delays/src/jobs/delayJob.ts) | Logs a message to the console, waits for 5 minutes, and then logs another message. | N/A |
|
||||
| [Basic interval](https://github.com/triggerdotdev/examples/blob/main/scheduled/src/jobs/interval.ts) | This Job will run every 60 seconds, starting 60 seconds after this Job is first indexed. | N/A |
|
||||
| [Cron scheduled interval](https://github.com/triggerdotdev/examples/blob/main/scheduled/src/jobs/cronScheduled.ts) | A scheduled Job which runs at 2:30pm every Monday. | N/A |
|
||||
| [Tell me a joke using OpenAI](https://github.com/triggerdotdev/examples/blob/main/openai/src/jobs/tellMeAJoke.ts) | Generates a random joke using OpenAI GPT 3.5. | [OpenAI](/integrations/apis/openai) |
|
||||
| [Generate an image using OpenAI](https://github.com/triggerdotdev/examples/blob/main/openai/src/jobs/generateHedgehogImages.ts) | Generates a random image of a hedgehog using OpenAI DALL-E. | [OpenAI](/integrations/apis/openai) |
|
||||
| [Add a custom label to a GitHub issue when it is created](https://github.com/triggerdotdev/examples/blob/main/github/src/jobs/onIssueOpened.ts) | When a new GitHub issue is opened it adds a "Bug" label to it. | [GitHub](/integrations/apis/github) |
|
||||
| [GitHub new star alert](https://github.com/triggerdotdev/examples/blob/main/github/src/jobs/newStarAlert.ts) | When a repo is starred a message is logged with the new Stargazers count. | [GitHub](/integrations/apis/github) |
|
||||
| [Github new star alert in Slack](https://github.com/triggerdotdev/examples/blob/main/github/src/jobs/newStarToSlack.ts) | When a repo is starred, a message is sent to a Slack channel with the name and URL of the GitHub user who starred the repo, and the updated Stargazers count. | [GitHub](/integrations/apis/github), [Slack](/integrations/apis/slack) |
|
||||
| [Send a Slack message when an event is received](https://github.com/triggerdotdev/examples/blob/main/slack/src/jobs/sendSlackMessage.ts) | Sends a Slack message to a specific channel when an event is received. | [Slack](/integrations/apis/slack) |
|
||||
| [Send an email using Resend](https://github.com/triggerdotdev/examples/blob/main/resend/src/jobs/resendBasicEmail.ts) | Send a basic email using Resend | [Resend](/integrations/apis/resend) |
|
||||
|
||||
If you have any ideas for Jobs you would like to build, you can fill in the [Job request form](https://bcymafitv0e.typeform.com/to/YLUKy9my#source=example-jobs-docs).
|
||||
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 375 KiB |
|
After Width: | Height: | Size: 623 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 754 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 137 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 571 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 151 KiB |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 233 KiB |