Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added supabase database operations and new snippet #1359

Merged
merged 11 commits into from
Sep 26, 2024
27 changes: 14 additions & 13 deletions docs/guides/examples/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ sidebarTitle: "Introduction"
description: "Learn how to use Trigger.dev with these practical task examples."
---

| Example task | Description |
| :------------------------------------------------------------ | :-------------------------------------------------------------------------- |
| [DALL·E 3 image generation](/guides/examples/dall-e3-generate-image) | Use OpenAI's GPT-4o and DALL·E 3 to generate an image and text. |
| [FFmpeg video processing](/guides/examples/ffmpeg-video-processing) | Use FFmpeg to process a video in various ways and save it to Cloudflare R2. |
| [OpenAI with retrying](/guides/examples/open-ai-with-retrying) | Create a reusable OpenAI task with custom retry options. |
| [PDF to image](/guides/examples/pdf-to-image) | Use `MuPDF` to turn a PDF into images and save them to Cloudflare R2. |
| [React to PDF](/guides/examples/react-pdf) | Use `react-pdf` to generate a PDF and save it to Cloudflare R2. |
| [Puppeteer](/guides/examples/puppeteer) | Use Puppeteer to generate a PDF or scrape a webpage. |
| [Resend email sequence](/guides/examples/resend-email-sequence) | Send a sequence of emails over several days using Resend with Trigger.dev. |
| [Sharp image processing](/guides/examples/sharp-image-processing) | Use Sharp to process an image and save it to Cloudflare R2. |
| [Stripe webhook](/guides/examples/stripe-webhook) | Trigger a task from Stripe webhook events. |
| [Supabase Storage upload](/guides/examples/supabase-storage-upload) | Download a video from a URL and upload it to Supabase Storage using S3. |
| [Vercel AI SDK](/guides/examples/vercel-ai-sdk) | Use Vercel AI SDK to generate text using OpenAI. |
| Example task | Description |
| :---------------------------------------------------------------------------- | :----------------------------------------------------------------------------- |
| [DALL·E 3 image generation](/guides/examples/dall-e3-generate-image) | Use OpenAI's GPT-4o and DALL·E 3 to generate an image and text. |
| [FFmpeg video processing](/guides/examples/ffmpeg-video-processing) | Use FFmpeg to process a video in various ways and save it to Cloudflare R2. |
| [OpenAI with retrying](/guides/examples/open-ai-with-retrying) | Create a reusable OpenAI task with custom retry options. |
| [PDF to image](/guides/examples/pdf-to-image) | Use `MuPDF` to turn a PDF into images and save them to Cloudflare R2. |
| [React to PDF](/guides/examples/react-pdf) | Use `react-pdf` to generate a PDF and save it to Cloudflare R2. |
| [Puppeteer](/guides/examples/puppeteer) | Use Puppeteer to generate a PDF or scrape a webpage. |
| [Resend email sequence](/guides/examples/resend-email-sequence) | Send a sequence of emails over several days using Resend with Trigger.dev. |
| [Sharp image processing](/guides/examples/sharp-image-processing) | Use Sharp to process an image and save it to Cloudflare R2. |
| [Stripe webhook](/guides/examples/stripe-webhook) | Trigger a task from Stripe webhook events. |
| [Supabase database operations](/guides/examples/supabase-database-operations) | Run basic CRUD operations on a table in a Supabase database using Trigger.dev. |
| [Supabase Storage upload](/guides/examples/supabase-storage-upload) | Download a video from a URL and upload it to Supabase Storage using S3. |
| [Vercel AI SDK](/guides/examples/vercel-ai-sdk) | Use Vercel AI SDK to generate text using OpenAI. |
197 changes: 197 additions & 0 deletions docs/guides/examples/supabase-database-operations.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
---
title: "Supabase database operations using Trigger.dev"
sidebarTitle: "Supabase database operations"
description: "These examples demonstrate how to run basic CRUD operations on a table in a Supabase database using Trigger.dev."
---

import SupabaseDocsCards from "/snippets/supabase-docs-cards.mdx";

## Add a new user to a table in a Supabase database

This is a basic task which inserts a new row into a table from a Trigger.dev task.

### Key features

- Shows how to set up a Supabase client using the `@supabase/supabase-js` library
- Shows how to add a new row to a table using `insert`

### Prerequisites

- A [Supabase account](https://supabase.com/dashboard/) and a project set up
- In your Supabase project, create a table called `user_subscriptions`.
- In your `user_subscriptions` table, create a new column:
- `user_id`, with the data type: `text`

### Task code

```ts trigger/supabase-database-insert.ts
import { createClient } from "@supabase/supabase-js";
import { task } from "@trigger.dev/sdk/v3";
// Generate the Typescript types using the Supabase CLI: https://supabase.com/docs/guides/api/rest/generating-types
import { Database } from "database.types";

// Create a single Supabase client for interacting with your database
// 'Database' supplies the type definitions to supabase-js
const supabase = createClient<Database>(
// These details can be found in your Supabase project settings under `API`
process.env.SUPABASE_PROJECT_URL as string, // e.g. https://abc123.supabase.co - replace 'abc123' with your project ID
process.env.SUPABASE_SERVICE_ROLE_KEY as string // Your service role secret key
);

export const supabaseDatabaseInsert = task({
id: "add-new-user",
run: async (payload: { userId: string }) => {
const { userId } = payload;

// Insert a new row into the user_subscriptions table with the provided userId
const { error } = await supabase.from("user_subscriptions").insert({
user_id: userId,
});

// If there was an error inserting the new user, throw an error
if (error) {
throw new Error(`Failed to insert new user: ${error.message}`);
}

return {
message: `New user added successfully: ${userId}`,
};
},
});
```

<Note>
This task uses your service role secret key to bypass Row Level Security. There are different ways
of configuring your [RLS
policies](https://supabase.com/docs/guides/database/postgres/row-level-security), so always make
sure you have the correct permissions set up for your project.
</Note>

### Testing your task

To test this task in the [Trigger.dev dashboard](https://cloud.trigger.dev), you can use the following payload:

```json
{
"userId": "user_12345"
}
```

If the task completes successfully, you will see a new row in your `user_subscriptions` table with the `user_id` set to `user_12345`.

## Update a user's subscription on a table in a Supabase database

This task shows how to update a user's subscription on a table. It checks if the user already has a subscription and either inserts a new row or updates an existing row with the new plan.

This type of task is useful for managing user subscriptions, updating user details, or performing other operations you might need to do on a database table.

### Key features

- Shows how to set up a Supabase client using the `@supabase/supabase-js` library
- Adds a new row to the table if the user doesn't exist using `insert`
- Checks if the user already has a plan, and if they do updates the existing row using `update`
- Demonstrates how to use [AbortTaskRunError](https://trigger.dev/docs/errors-retrying#using-aborttaskrunerror) to stop the task run without retrying if an invalid plan type is provided

### Prerequisites

- A [Supabase account](https://supabase.com/dashboard/) and a project set up
- In your Supabase project, create a table called `user_subscriptions` (if you haven't already)
- In your `user_subscriptions` table, create these columns (if they don't already exist):

- `user_id`, with the data type: `text`
- `plan`, with the data type: `text`
- `updated_at`, with the data type: `timestamptz`

### Task code

```ts trigger/supabase-update-user-subscription.ts
import { createClient } from "@supabase/supabase-js";
import { AbortTaskRunError, task } from "@trigger.dev/sdk/v3";
// Generate the Typescript types using the Supabase CLI: https://supabase.com/docs/guides/api/rest/generating-types
import { Database } from "database.types";

// Define the allowed plan types
type PlanType = "hobby" | "pro" | "enterprise";

// Create a single Supabase client for interacting with your database
// 'Database' supplies the type definitions to supabase-js
const supabase = createClient<Database>(
// These details can be found in your Supabase project settings under `API`
process.env.SUPABASE_PROJECT_URL as string, // e.g. https://abc123.supabase.co - replace 'abc123' with your project ID
process.env.SUPABASE_SERVICE_ROLE_KEY as string // Your service role secret key
);

export const supabaseUpdateUserSubscription = task({
id: "update-user-subscription",
run: async (payload: { userId: string; newPlan: PlanType }) => {
const { userId, newPlan } = payload;

// Abort the task run without retrying if the new plan type is invalid
if (!["hobby", "pro", "enterprise"].includes(newPlan)) {
throw new AbortTaskRunError(
`Invalid plan type: ${newPlan}. Allowed types are 'hobby', 'pro', or 'enterprise'.`
);
}

// Query the user_subscriptions table to check if the user already has a subscription
const { data: existingSubscriptions } = await supabase
.from("user_subscriptions")
.select("user_id")
.eq("user_id", userId);

if (!existingSubscriptions || existingSubscriptions.length === 0) {
// If there are no existing users with the provided userId and plan, insert a new row
const { error: insertError } = await supabase.from("user_subscriptions").insert({
user_id: userId,
plan: newPlan,
updated_at: new Date().toISOString(),
});

// If there was an error inserting the new subscription, throw an error
if (insertError) {
throw new Error(`Failed to insert user subscription: ${insertError.message}`);
}
} else {
// If the user already has a subscription, update their existing row
const { error: updateError } = await supabase
.from("user_subscriptions")
// Set the plan to the new plan and update the timestamp
.update({ plan: newPlan, updated_at: new Date().toISOString() })
.eq("user_id", userId);

// If there was an error updating the subscription, throw an error
if (updateError) {
throw new Error(`Failed to update user subscription: ${updateError.message}`);
}
}

// Return an object with the userId and newPlan
return {
userId,
newPlan,
};
},
});
```

<Note>
This task uses your service role secret key to bypass Row Level Security. There are different ways
of configuring your [RLS
policies](https://supabase.com/docs/guides/database/postgres/row-level-security), so always make
sure you have the correct permissions set up for your project.
</Note>

## Testing your task

To test this task in the [Trigger.dev dashboard](https://cloud.trigger.dev), you can use the following payload:

```json
{
"userId": "user_12345",
"newPlan": "pro"
}
```

If the task completes successfully, you will see a new row in your `user_subscriptions` table with the `user_id` set to `user_12345`, the `plan` set to `pro`, and the `updated_at` timestamp updated to the current time.

<SupabaseDocsCards />
4 changes: 4 additions & 0 deletions docs/guides/examples/supabase-storage-upload.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ sidebarTitle: "Supabase Storage upload"
description: "This example demonstrates how to download a video from a URL and upload it to Supabase Storage using Trigger.dev."
---

import SupabaseDocsCards from "/snippets/supabase-docs-cards.mdx";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Update the Import Path for SupabaseDocsCards

The current import path /snippets/supabase-docs-cards.mdx may be incorrect since the file is located at docs/snippets/supabase-docs-cards.mdx. Consider updating the import to a relative path to ensure it resolves correctly.

  • Change the import statement to use a relative path, such as:
    import SupabaseDocsCards from "./snippets/supabase-docs-cards.mdx";
  • Verify the project's configuration for absolute imports to ensure that /snippets/supabase-docs-cards.mdx correctly resolves to docs/snippets/supabase-docs-cards.mdx.
🔗 Analysis chain

Verify the import path for SupabaseDocsCards

The import statement uses an absolute path starting with "/". Ensure that this path is correct and resolves properly in your project structure. Consider using a relative path if it's more appropriate for your project setup.


Further Verify the Import Path for SupabaseDocsCards

The previous attempt to locate supabase-docs-cards.mdx in the snippets directory failed. Please run the following script to search for the file across the repository:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence of the imported file
fd -t f "supabase-docs-cards.mdx" snippets

Length of output: 138


Script:

#!/bin/bash
# Search for the imported file across the repository
fd -t f "supabase-docs-cards.mdx"

Length of output: 71


## Overview

This task downloads a video from a provided URL, saves it to a temporary file, and then uploads the video file to Supabase Storage using S3.
Expand Down Expand Up @@ -72,3 +74,5 @@ To test this task in the dashboard, you can use the following payload:
"videoUrl": "<a-video-url>" // Replace <a-video-url> with the URL of the video you want to upload
}
```

<SupabaseDocsCards />
3 changes: 2 additions & 1 deletion docs/guides/frameworks/supabase-edge-functions-basic.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ 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";
import SupabaseDocsCards from "/snippets/supabase-docs-cards.mdx";

## Overview

Expand Down Expand Up @@ -177,4 +178,4 @@ Check your [cloud.trigger.dev](http://cloud.trigger.dev) dashboard and you shoul
</Step>
</Steps>

<UsefulNextSteps />
<SupabaseDocsCards />
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
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."
description: "This guide will show you how to trigger a task when a row is added to a table using a Supabase database webhook and edge function."
---

import Prerequisites from "/snippets/framework-prerequisites.mdx";
Expand All @@ -15,6 +15,7 @@ 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";
import SupabaseDocsCards from "/snippets/supabase-docs-cards.mdx";

## Overview

Expand Down Expand Up @@ -233,4 +234,4 @@ Inside that run you will see the payload that was sent from the database webhook

</Steps>

<UsefulNextSteps />
<SupabaseDocsCards />
23 changes: 5 additions & 18 deletions docs/guides/frameworks/supabase-guides-overview.mdx
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
---
title: "Supabase guides"
title: "Supabase overview"
sidebarTitle: "Overview"
description: "Guides for using Supabase with Trigger.dev."
description: "Guides and examples for using Supabase with Trigger.dev."
---

<CardGroup cols={2}>
<Card
title="Edge function hello world"
icon="bolt"
href="/guides/frameworks/supabase-edge-functions-basic"
>
Learn how to trigger a task from a Supabase edge function when a URL is visited.
</Card>
<Card
title="Edge function database webhooks"
icon="bolt"
href="/guides/frameworks/supabase-edge-functions-database-webhooks"
>
Learn how to trigger a task from a Supabase edge function when an event occurs in your database.
</Card>
</CardGroup>
import SupabaseDocsCards from "/snippets/supabase-docs-cards.mdx";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Missing supabase-docs-cards.mdx File

The snippets/supabase-docs-cards.mdx file does not exist, but it is being imported in the following files:

  • docs/examples/supabase-storage-upload.mdx
  • docs/examples/supabase-database-operations.mdx
  • docs/guides/frameworks/supabase-edge-functions-basic.mdx
  • docs/guides/frameworks/supabase-guides-overview.mdx
  • docs/guides/frameworks/supabase-edge-functions-database-webhooks.mdx
🔗 Analysis chain

Modular approach with SupabaseDocsCards import.

The introduction of a separate component for Supabase documentation cards is a good practice for maintainability and reusability. This modular approach allows for easier updates and consistency across the documentation.

Please verify the existence and correct implementation of the imported file:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence and content of the imported file
if [ -f "snippets/supabase-docs-cards.mdx" ]; then
    echo "File exists. Displaying its content:"
    cat "snippets/supabase-docs-cards.mdx"
else
    echo "Error: File 'snippets/supabase-docs-cards.mdx' does not exist."
fi

Length of output: 292


Script:

#!/bin/bash
# Verify the existence and content of the imported file
if [ -f "snippets/supabase-docs-cards.mdx" ]; then
    echo "File exists. Displaying its content:"
    cat "snippets/supabase-docs-cards.mdx"
else
    echo "Error: File 'snippets/supabase-docs-cards.mdx' does not exist."
fi

Length of output: 186


Script:

#!/bin/bash
# Search for usages of SupabaseDocsCards in .mdx files
rg "SupabaseDocsCards" --glob "*.mdx" -A 3 -B 1

Length of output: 2519


<SupabaseDocsCards />
Loading