diff --git a/docs/guides/frameworks/supabase-edge-functions-basic.mdx b/docs/guides/frameworks/supabase-edge-functions-basic.mdx new file mode 100644 index 000000000..cdb5a126c --- /dev/null +++ b/docs/guides/frameworks/supabase-edge-functions-basic.mdx @@ -0,0 +1,179 @@ +--- +title: "Triggering tasks from Supabase edge functions" +sidebarTitle: "Edge function hello world" +description: "This guide will show you how to trigger a task from a Supabase edge function, and then view the run in our dashboard." +--- + +import Prerequisites from "/snippets/framework-prerequisites.mdx"; +import SupabasePrerequisites from "/snippets/supabase-prerequisites.mdx"; +import CliInitStep from "/snippets/step-cli-init.mdx"; +import CliDevStep from "/snippets/step-cli-dev.mdx"; +import CliRunTestStep from "/snippets/step-run-test.mdx"; +import CliViewRunStep from "/snippets/step-view-run.mdx"; +import UsefulNextSteps from "/snippets/useful-next-steps.mdx"; +import TriggerTaskNextjs from "/snippets/trigger-tasks-nextjs.mdx"; +import NextjsTroubleshootingMissingApiKey from "/snippets/nextjs-missing-api-key.mdx"; +import NextjsTroubleshootingButtonSyntax from "/snippets/nextjs-button-syntax.mdx"; +import WorkerFailedToStartWhenRunningDevCommand from "/snippets/worker-failed-to-start.mdx"; + +## Overview + +Supabase edge functions allow you to trigger tasks either when an event is sent from a third party (e.g. when a new Stripe payment is processed, when a new user signs up to a service, etc), or when there are any changes or updates to your Supabase database. + +This guide shows you how to set up and deploy a simple Supabase edge function example that triggers a task when an edge function URL is accessed. + +## Prerequisites + +- Ensure you have the [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) installed +- Ensure TypeScript is installed +- [Create a Trigger.dev account](https://cloud.trigger.dev) +- [Create a new Trigger.dev project](/guides/dashboard/creating-a-project) + +## Initial setup + + + + + + + + + +## Create a new Supabase edge function and deploy it + + + + + +We'll call this example `edge-function-trigger`. + +In your project, run the following command in the terminal using the Supabase CLI: + +```bash +supabase functions new edge-function-trigger +``` + + + + + +Replace the placeholder code in your `edge-function-trigger/index.ts` file with the following: + +```ts functions/edge-function-trigger/index.ts +// Setup type definitions for built-in Supabase Runtime APIs +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +// Import the Trigger.dev SDK - replace "" with the version of the SDK you are using, e.g. "3.0.0-beta.55". You can find this in your package.json file. +import { tasks } from "npm:@trigger.dev/sdk@/v3"; +// Import your task type from your /trigger folder +import type { helloWorldTask } from "../../../src/trigger/example.ts"; + +Deno.serve(async () => { + await tasks.trigger( + // Your task id + "hello-world", + // Your task payload + "Hello from a Supabase Edge Function!" + ); + return new Response("OK"); +}); +``` + +You can only import the `type` from the task. + + Tasks in the `trigger` folder use Node, so they must stay in there or they will not run, + especially if you are using a different runtime like Deno. Also do not add "`npm:`" to imports + inside your task files, for the same reason. + + + + + + +You can now deploy your edge function with the following command in your terminal: + +```bash +supabase functions deploy edge-function-trigger --no-verify-jwt +``` + + + `--no-verify-jwt` removes the JSON Web Tokens requirement from the authorization header. By + default this should be on, but it is not required for this example. Learn more about JWTs + [here](https://supabase.com/docs/guides/auth/jwts). + + +Follow the CLI instructions and once complete you should now see your new edge function deployment in your Supabase edge functions dashboard. + +There will be a link to the dashboard in your terminal output, or you can find it at this URL: + +`https://supabase.com/dashboard/project//functions` + +Replace `your-project-id` with your actual project ID. + + + + + +## Set your Trigger.dev prod secret key in the Supabase dashboard + +To trigger a task from your edge function, you need to set your Trigger.dev secret key in the Supabase dashboard. + +To do this, first go to your Trigger.dev [project dashboard](https://cloud.trigger.dev) and copy the `prod` secret key from the API keys page. + +![How to find your prod secret key](/images/api-key-prod.png) + +Then, in [Supabase](https://supabase.com/dashboard/projects), select your project, navigate to 'Project settings' , click 'Edge functions' in the configurations menu, and then click the 'Add new secret' button. + +Add `TRIGGER_SECRET_KEY` with the pasted value of your Trigger.dev `prod` secret key. + +![Add secret key in Supabase](/images/supabase-keys-1.png) + +## Deploy your task and trigger it from your edge function + + + + + +Next, deploy your `hello-world` task to [Trigger.dev cloud](https://cloud.trigger.dev). + + + +```bash npm +npx trigger.dev@beta deploy +``` + +```bash pnpm +pnpm dlx trigger.dev@beta deploy +``` + +```bash yarn +yarn dlx trigger.dev@beta deploy +``` + + + + + + + +To do this all you need to do is simply open the `edge-function-trigger` URL. + +`https://supabase.com/dashboard/project//functions` + +Replace `your-project-id` with your actual project ID. + +In your Supabase project, go to your Edge function dashboard, find `edge-function-trigger`, copy the URL, and paste it into a new window in your browser. + +Once loaded you should see ‘OK’ on the new screen. + +![Edge function URL](/images/supabase-function-url.png) + +The task will be triggered when your edge function URL is accessed. + +Check your [cloud.trigger.dev](http://cloud.trigger.dev) dashboard and you should see a succesful `hello-world` task. + + **Congratulations, you have run a simple Hello World task from a Supabase edge function!** + + + + + diff --git a/docs/guides/frameworks/supabase-edge-functions-database-webhooks.mdx b/docs/guides/frameworks/supabase-edge-functions-database-webhooks.mdx new file mode 100644 index 000000000..3c2622161 --- /dev/null +++ b/docs/guides/frameworks/supabase-edge-functions-database-webhooks.mdx @@ -0,0 +1,233 @@ +--- +title: "Triggering tasks from Supabase database webhooks" +sidebarTitle: "Database webhooks" +description: "This guide will show you how to trigger a task when a row is added to a table using Supabase database webhooks." +--- + +import Prerequisites from "/snippets/framework-prerequisites.mdx"; +import SupabasePrerequisites from "/snippets/supabase-prerequisites.mdx"; +import CliInitStep from "/snippets/step-cli-init.mdx"; +import CliDevStep from "/snippets/step-cli-dev.mdx"; +import CliRunTestStep from "/snippets/step-run-test.mdx"; +import CliViewRunStep from "/snippets/step-view-run.mdx"; +import UsefulNextSteps from "/snippets/useful-next-steps.mdx"; +import TriggerTaskNextjs from "/snippets/trigger-tasks-nextjs.mdx"; +import NextjsTroubleshootingMissingApiKey from "/snippets/nextjs-missing-api-key.mdx"; +import NextjsTroubleshootingButtonSyntax from "/snippets/nextjs-button-syntax.mdx"; +import WorkerFailedToStartWhenRunningDevCommand from "/snippets/worker-failed-to-start.mdx"; + +## Overview + +Database webhooks allow you to send realtime data from your database to another system whenever an event occurs in your table e.g. when a row is inserted, updated, or deleted, or when a specific column is updated. + +This guide shows you how to set up a Supabase database webhook and deploy a simple edge function that triggers a "Hello world" task every time a new row is inserted into your table. + +## Prerequisites + +- Ensure you have the [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) installed +- Ensure TypeScript is installed +- [Create a Trigger.dev account](https://cloud.trigger.dev) +- [Create a new Trigger.dev project](/guides/dashboard/creating-a-project) + +## Initial setup + + + + + + + + + +## Create and deploy a new Supabase edge function and create a new database webhook + + + + + +First, go to your Trigger.dev [project dashboard](https://cloud.trigger.dev) and copy the `prod` secret key from the API keys page. + +![How to find your prod secret key](/images/api-key-prod.png) + +Then, in [Supabase](https://supabase.com/dashboard/projects), select the project you want to use, navigate to 'Project settings' , click 'Edge functions' in the configurations menu, and then click the 'Add new secret' button. + +Add `TRIGGER_SECRET_KEY` with the pasted value of your Trigger.dev `prod` secret key. + +![Add secret key in Supabase](/images/supabase-keys-1.png) + + + + + +Now create a new edge function using the Supabase CLI. We will call it `database-webhook`. + +```bash +supabase functions new database-webhook +``` + + + + + +Replace the `database-webhook` placeholder code with the following code: + +```ts functions/database-webhook/index.ts +import "jsr:@supabase/functions-js/edge-runtime.d.ts"; +// Import the Trigger.dev SDK - replace "" with the version of the SDK you are using, e.g. "3.0.0-beta.55". You can find this in your package.json file. +import { tasks } from "npm:@trigger.dev/sdk@/v3"; +// Import your task type from your /trigger folder +import type { helloWorldTask } from "../../../src/trigger/example.ts"; + +console.log("Hello from 'database-webhook' function!"); + +Deno.serve(async (req) => { + // Listens for incoming JSON requests + const payload = await req.json(); + // Triggers the "hello-world" task with the payload + await tasks.trigger( + // Your task id + "hello-world", + // Your task payload + "hello from a Supabase Edge Function!" + ); + return new Response("ok"); +}); +``` + +This code sets up a Deno server that listens for incoming JSON requests, triggers a "hello-world" task, logs the received payload, and responds with "ok". This setup is typical for a webhook endpoint that processes incoming data and triggers some action (in this case, the "hello-world" task) based on that data. + +You can only import the `type` from the task. + + Tasks in the `trigger` folder use Node, so they must stay in there or they will not run, + especially if you are using a different runtime like Deno. Also do not add "`npm:`" to imports + inside your task files, for the same reason. + + + + + + +Now deploy your edge function with the following command: + +```bash +supabase functions deploy database-webhook +``` + +Follow the CLI instructions, selecting the same project you added your `prod` secret key to, and once complete you should see your new edge function deployment in your Supabase edge functions dashboard. + +There will be a link to the dashboard in your terminal output, or you can find it at this URL: + +`https://supabase.com/dashboard/project//functions` + +Replace `your-project-id` with your actual project ID. + + + + + +Next, in your Supabase project dashboard, click on 'Table Editor' in the left-hand menu and create a new table. + +![How to create a new table](/images/supabase-new-table-1.png) + +In this example we will call our table `skynet`. + +Add a new column called `name` with the type `text`. + +![How to add a new column](/images/supabase-new-table-2.png) + + + + + +By default, Supabase edge functions require a JSON Web Token ([JWT](<(https://supabase.com/docs/guides/auth/jwts)>)) in the authorization header. This is to ensure that only authorized users can access your edge functions. + +In your Supabase project dashboard, click 'Project settings' , then the 'API' tab , and copy the `anon` `public` API key from the table . + +![How to find your Supabase API keys](/images/supabase-api-key.png) + +Then, go to 'Database' click on 'Webhooks' , and then click 'Create a new hook' . + +![How to create a new webhook](/images/supabase-create-webhook-1.png) + + Call the hook `edge-function-hook`. + + Select the new table you have created: +`public` `skynet`. + + Choose the `insert` event. + +![How to create a new webhook 2](/images/supabase-create-webhook-2.png) + + Under 'Webhook configuration', select +'Supabase Edge functions'{" "} + + Under 'Edge function', choose `POST` +and select the edge function you have created: `database-webhook`.{" "} + + Under 'HTTP Headers', add a new header with the key `Authorization` and the value `Bearer ` (replace `` with the `anon` `public` API key you copied earlier). + + Click 'Create webhook'.{" "} + +![How to create a new webhook 3](/images/supabase-create-webhook-3.png) + +Your database webhook is now ready to use. + + + + + +## Deploy your task and trigger it from your new `database-webhook` edge function + + + + + +The next step is to deploy your `hello-world` task to [Trigger.dev cloud](https://cloud.trigger.dev). + +To do this, run the following command in the terminal: + + + +```bash npm +npx trigger.dev@beta deploy +``` + +```bash pnpm +pnpm dlx trigger.dev@beta deploy +``` + +```bash yarn +yarn dlx trigger.dev@beta deploy +``` + + + + + + + +Your `database-webhook` edge function is now set up to trigger the `hello-world` task every time a new row is inserted into your `skynet` table. + +To do this, go back to your Supabase project dashboard, click on 'Table Editor' in the left-hand menu, click on the `skynet` table , and then click 'Insert', 'Insert Row' . + +![How to insert a new row 1](/images/supabase-new-table-3.png) + +Add a new item under `name`, with the value `Sarah Connor` (this can be any string). + +![How to insert a new row 2](/images/supabase-new-table-4.png) + +Go back to your edge function dashboard , and under 'Logs' you should see a new run of your `database-webhook` edge function. + +![How to view the logs](/images/supabase-logs.png) + +Then, check your [cloud.trigger.dev](http://cloud.trigger.dev) project 'Runs' list and you should see a successful `hello-world` task which has been triggered when you added a new row with the `name` `Sarah Connor` to your `skynet` Supabase table. + +![How to insert a new row 2](/images/supabase-trigger-screenshot.png) + +**Congratulations, you have successfully triggered a task from a Supabase edge function using a database webhook!** + + + + + + diff --git a/docs/images/api-key-dev.png b/docs/images/api-key-dev.png new file mode 100644 index 000000000..78ceccd26 Binary files /dev/null and b/docs/images/api-key-dev.png differ diff --git a/docs/images/api-key-prod.png b/docs/images/api-key-prod.png new file mode 100644 index 000000000..18bf38483 Binary files /dev/null and b/docs/images/api-key-prod.png differ diff --git a/docs/images/supabase-api-key.png b/docs/images/supabase-api-key.png new file mode 100644 index 000000000..612c2cf4c Binary files /dev/null and b/docs/images/supabase-api-key.png differ diff --git a/docs/images/supabase-create-webhook-1.png b/docs/images/supabase-create-webhook-1.png new file mode 100644 index 000000000..34eac7f00 Binary files /dev/null and b/docs/images/supabase-create-webhook-1.png differ diff --git a/docs/images/supabase-create-webhook-2.png b/docs/images/supabase-create-webhook-2.png new file mode 100644 index 000000000..18ab7195c Binary files /dev/null and b/docs/images/supabase-create-webhook-2.png differ diff --git a/docs/images/supabase-create-webhook-3.png b/docs/images/supabase-create-webhook-3.png new file mode 100644 index 000000000..cfe306510 Binary files /dev/null and b/docs/images/supabase-create-webhook-3.png differ diff --git a/docs/images/supabase-function-url.png b/docs/images/supabase-function-url.png new file mode 100644 index 000000000..d66124368 Binary files /dev/null and b/docs/images/supabase-function-url.png differ diff --git a/docs/images/supabase-keys-1.png b/docs/images/supabase-keys-1.png new file mode 100644 index 000000000..9449d75ce Binary files /dev/null and b/docs/images/supabase-keys-1.png differ diff --git a/docs/images/supabase-logs.png b/docs/images/supabase-logs.png new file mode 100644 index 000000000..2533f0fd7 Binary files /dev/null and b/docs/images/supabase-logs.png differ diff --git a/docs/images/supabase-new-table-1.png b/docs/images/supabase-new-table-1.png new file mode 100644 index 000000000..eb461255a Binary files /dev/null and b/docs/images/supabase-new-table-1.png differ diff --git a/docs/images/supabase-new-table-2.png b/docs/images/supabase-new-table-2.png new file mode 100644 index 000000000..ffe336bdc Binary files /dev/null and b/docs/images/supabase-new-table-2.png differ diff --git a/docs/images/supabase-new-table-3.png b/docs/images/supabase-new-table-3.png new file mode 100644 index 000000000..4baed1fc7 Binary files /dev/null and b/docs/images/supabase-new-table-3.png differ diff --git a/docs/images/supabase-new-table-4.png b/docs/images/supabase-new-table-4.png new file mode 100644 index 000000000..03dad93f1 Binary files /dev/null and b/docs/images/supabase-new-table-4.png differ diff --git a/docs/images/supabase-trigger-screenshot.png b/docs/images/supabase-trigger-screenshot.png new file mode 100644 index 000000000..13905dc8d Binary files /dev/null and b/docs/images/supabase-trigger-screenshot.png differ diff --git a/docs/mint.json b/docs/mint.json index 220e17e57..64080ea8a 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -227,7 +227,20 @@ }, { "group": "Frameworks", - "pages": ["guides/frameworks/nodejs", "guides/frameworks/nextjs", "guides/frameworks/remix"] + "pages": [ + "guides/frameworks/nodejs", + "guides/frameworks/nextjs", + "guides/frameworks/remix", + { + "group": "Supabase", + "icon": "bolt", + "iconType": "solid", + "pages": [ + "guides/frameworks/supabase-edge-functions-basic", + "guides/frameworks/supabase-edge-functions-database-webhooks" + ] + } + ] }, { "group": "Dashboard", diff --git a/docs/snippets/step-cli-dev.mdx b/docs/snippets/step-cli-dev.mdx index 43e71de5c..ec62aedc6 100644 --- a/docs/snippets/step-cli-dev.mdx +++ b/docs/snippets/step-cli-dev.mdx @@ -1,6 +1,6 @@ -The CLI `dev` command runs a server for your tasks. It will watches for changes in your `/trigger` directory and communicates with the Trigger.dev platform to register your tasks, perform runs, and send data back and forth. +The CLI `dev` command runs a server for your tasks. It watches for changes in your `/trigger` directory and communicates with the Trigger.dev platform to register your tasks, perform runs, and send data back and forth. It can also update your `@trigger.dev/*` packages to prevent version mismatches and failed deploys. You will always be prompted first. diff --git a/docs/snippets/step-cli-init.mdx b/docs/snippets/step-cli-init.mdx index b54cc7890..d75f2ade9 100644 --- a/docs/snippets/step-cli-init.mdx +++ b/docs/snippets/step-cli-init.mdx @@ -1,6 +1,6 @@ -The easiest way to get started it to use the CLI. It will add Trigger.dev to your existing project, create a `/trigger` folder and give you an example task. +The easiest way to get started is to use the CLI. It will add Trigger.dev to your existing project, create a `/trigger` folder and give you an example task. Run this command in the root of your project to get started: @@ -29,4 +29,4 @@ It will do a few things: Install the "Hello World" example task when prompted. We'll use this task to test the setup. - \ No newline at end of file + diff --git a/docs/snippets/supabase-prerequisites.mdx b/docs/snippets/supabase-prerequisites.mdx new file mode 100644 index 000000000..59c7081aa --- /dev/null +++ b/docs/snippets/supabase-prerequisites.mdx @@ -0,0 +1,52 @@ + + + If you already have a Supabase project on your local machine you can skip this step. + +You can create a new project by running the following command in your terminal using the Supabase CLI: + +```bash +supabase init +``` + + + If you are using VS Code, ensure to answer 'y' when asked to generate VS Code settings for Deno, + and install any recommended extensions. + + + + + + +If your project does not already have `package.json` or/and `tsconfig.json` files (e.g. if you are using Deno), create them manually and add them to your project root folder. + + If your project has these files you can skip this step. + +Both of these files are required for the Trigger.dev SDK to work correctly. + +```ts package.json +{ + "devDependencies": { + // This should be the version of typescript you are using + "typescript": "^5.3.3" + } +} +``` + +```ts tsconfig.json +{ + "compilerOptions": { + "target": "esnext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "esModuleInterop": true, + "strict": true, + "outDir": "dist", + "skipLibCheck": true, + "lib": ["DOM", "DOM.Iterable"], + "noEmit": true + }, + "include": ["./src/**/*.ts", "trigger.config.ts"] +} +``` + +