Skip to content

Commit ed3f8c6

Browse files
committed
Supabase guide wip
1 parent e5c8f8b commit ed3f8c6

File tree

1 file changed

+114
-187
lines changed

1 file changed

+114
-187
lines changed

docs/guides/frameworks/supabase-edge-functions-ffmpeg-deepgram.mdx

Lines changed: 114 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Triggering tasks from Supabase Database Webhooks"
33
sidebarTitle: "Database webhooks"
4-
description: "This guide shows you how to trigger a task when a row is added to a table, using a Supabase Database Webhook and Edge Function."
4+
description: "This guide shows you how to trigger a task when a row is added to a table in a Supabase database, using a Database Webhook and Edge Function."
55
---
66

77
import Prerequisites from "/snippets/framework-prerequisites.mdx";
@@ -14,11 +14,11 @@ import NextjsTroubleshootingButtonSyntax from "/snippets/nextjs-button-syntax.md
1414
import WorkerFailedToStartWhenRunningDevCommand from "/snippets/worker-failed-to-start.mdx";
1515
import SupabaseDocsCards from "/snippets/supabase-docs-cards.mdx";
1616

17-
## Workflow overview
17+
## Overview
1818

19-
Generate a transcription from a video URL using [Supabase](https://supabase.com), [FFmpeg](https://www.ffmpeg.org/) and [Deepgram](https://deepgram.com) and Trigger.dev.
19+
This workflow generates a transcription from a video URL and updates a table in a database, using [Supabase](https://supabase.com), [FFmpeg](https://www.ffmpeg.org/) and [Deepgram](https://deepgram.com) and Trigger.dev.
2020

21-
In this walk-through guide you will learn how to set up and deploy a Supabase Edge Function that is triggered by an `insert` row action in a table via a Database Webhook.
21+
You will learn how to set up and deploy a Supabase Edge Function that is triggered by an `insert` row action in a table via a Database Webhook.
2222

2323
The Edge Function triggers a deployed Trigger.dev task which takes a payload from the new inserted data from the table. This is then processed using FFmpeg and Deepgram. The resulting string is then `updated` back into the original table row in Supabase.
2424

@@ -46,165 +46,6 @@ The Edge Function triggers a deployed Trigger.dev task which takes a payload fro
4646
<CliInitStep />
4747
</Steps>
4848

49-
## Create and deploy the video processing Trigger.dev task
50-
51-
Before setting up your Edge Function and Database Webhook, you'll need to create your Trigger.dev task. This can be tested independently from the rest of the workflow.
52-
53-
Create a new task file in your `/trigger` folder (the same place your 'Hello World' task is). Call it `videoProcessAndUpdate.ts`.
54-
55-
This task with take a video from a public video url, extract the audio using FFmpeg and transcribe the audio using Deepgram.
56-
57-
<Note>We will add the Supabase `update` step further on in the tutorial.</Note>
58-
59-
```ts /trigger/videoProcessAndUpdate.ts
60-
import { createClient as createDeepgramClient } from "@deepgram/sdk";
61-
import { logger, task } from "@trigger.dev/sdk/v3";
62-
import ffmpeg from "fluent-ffmpeg";
63-
import fs from "fs";
64-
import fetch from "node-fetch";
65-
import { Readable } from "node:stream";
66-
import os from "os";
67-
import path from "path";
68-
import { Database } from "../../database.types";
69-
70-
const deepgram = createDeepgramClient(process.env.DEEPGRAM_SECRET_KEY);
71-
72-
export const videoProcessAndUpdate = task({
73-
id: "video-process-and-update",
74-
run: async (payload: { videoUrl: string }) => {
75-
const { videoUrl } = payload;
76-
77-
logger.log(`Processing video at URL: ${videoUrl}`);
78-
79-
// Generate temporary file video_urls
80-
const tempDirectory = os.tmpdir();
81-
const outputPath = path.join(tempDirectory, `audio_${Date.now()}.wav`);
82-
83-
// Fetch the video
84-
const response = await fetch(videoUrl);
85-
86-
// Extract the audio
87-
await new Promise((resolve, reject) => {
88-
if (!response.body) {
89-
return reject(new Error("Failed to fetch video"));
90-
}
91-
92-
ffmpeg(Readable.from(response.body))
93-
.outputOptions([
94-
"-vn", // Disable video output
95-
"-acodec pcm_s16le", // Use PCM 16-bit little-endian encoding
96-
"-ar 44100", // Set audio sample rate to 44.1 kHz
97-
"-ac 2", // Set audio channels to stereo
98-
])
99-
.output(outputPath)
100-
.on("end", resolve)
101-
.on("error", reject)
102-
.run();
103-
});
104-
105-
logger.log(`Audio extracted from video`, { outputPath });
106-
107-
// Transcribe the audio using Deepgram
108-
const { result, error } = await deepgram.listen.prerecorded.transcribeFile(
109-
fs.readFileSync(outputPath),
110-
{
111-
model: "nova-2",
112-
smart_format: true,
113-
diarize: true,
114-
}
115-
);
116-
117-
if (error) {
118-
throw error;
119-
}
120-
121-
console.dir(result, { depth: null });
122-
123-
// Convert the result object to a string
124-
const transcription = result.results.channels[0].alternatives[0].paragraphs?.transcript;
125-
126-
logger.log(`Transcription: ${transcription}`);
127-
128-
// Delete the temporary audio file
129-
fs.unlinkSync(outputPath);
130-
logger.log(`Temporary audio file deleted`, { outputPath });
131-
132-
return {
133-
message: `Summary of the audio: ${transcription}`,
134-
result,
135-
};
136-
},
137-
});
138-
```
139-
140-
### Adding the FFmpeg build extension
141-
142-
<Note>
143-
This task can also be tested in `dev` without adding the build extension, but we recommend adding
144-
the extension during the setup process.
145-
</Note>
146-
147-
Before you can deploy the task, you'll need to add our FFmpeg extension:
148-
149-
```ts trigger.config.ts
150-
import { ffmpeg } from "@trigger.dev/build/extensions/core";
151-
import { defineConfig } from "@trigger.dev/sdk/v3";
152-
153-
export default defineConfig({
154-
project: "<project ref>",
155-
// Your other config settings...
156-
build: {
157-
extensions: [ffmpeg()],
158-
},
159-
});
160-
```
161-
162-
<Note>
163-
[Build extensions](/config/config-file#extensions) allow you to hook into the build system and
164-
customize the build process or the resulting bundle and container image (in the case of
165-
deploying). You can use pre-built extensions or create your own.
166-
</Note>
167-
168-
You'll also need to add `@trigger.dev/build` to your `package.json` file under `devDependencies` if you don't already have it there.
169-
170-
### Adding the Deepgram environment variable
171-
172-
You will need to add your `DEEPGRAM_SECRET_KEY` as an environment variable in your Trigger.dev project. You can do this in the Trigger.dev dashboard under the 'environment variables' tab.
173-
174-
![Adding environment variables](/images/environment-variables-page.jpg)
175-
176-
### Deploying your task
177-
178-
You can now deploy your task and test it in the Trigger.dev [dashboard](https://cloud.trigger.dev).
179-
180-
<CodeGroup>
181-
182-
```bash npm
183-
npx trigger.dev@latest deploy
184-
```
185-
186-
```bash pnpm
187-
pnpm dlx trigger.dev@latest deploy
188-
```
189-
190-
```bash yarn
191-
yarn dlx trigger.dev@latest deploy
192-
```
193-
194-
</CodeGroup>
195-
196-
### Testing your task
197-
198-
To test this task in the dashboard, select the `prod` environment and use the following payload:
199-
200-
```json
201-
{
202-
"audioUrl": "https://dpgr.am/spacewalk.wav"
203-
}
204-
```
205-
206-
Congratulations! You should now see the video transcription logged in a successful run.
207-
20849
## Create and deploy a Supabase Edge Function and configure the Database Webhook
20950

21051
### Add your Trigger.dev prod secret key to the Supabase dashboard
@@ -221,7 +62,7 @@ Add `TRIGGER_SECRET_KEY` <Icon icon="circle-4" iconType="solid" size={20} color=
22162

22263
### Create a new Edge Function using the Supabase CLI
22364

224-
Now create an Edge Function using the Supabase CLI. Call it `video-processing-handler`. This will trigger your task using the data received from the Database Webhook.
65+
Now create an Edge Function using the Supabase CLI. Call it `video-processing-handler`. This function will be triggered by the Database Webhook.
22566

22667
```bash
22768
supabase functions new video-processing-handler
@@ -232,30 +73,15 @@ Replace the `video-processing-handler` placeholder code with the following code:
23273
```ts functions/video-processing-handler/index.ts
23374
// Setup type definitions for built-in Supabase Runtime APIs
23475
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
235-
// Import the Trigger.dev SDK - replace "<your-sdk-version>" with the version of the SDK you are using, e.g. "3.0.0". You can find this in your package.json file.
236-
import { tasks } from "npm:@trigger.dev/[email protected]/v3";
237-
import type { videoProcessAndUpdate } from "../../../src/trigger/video-process-and-update.ts";
238-
// 👆 **type-only** import
23976

24077
// Sets up a Deno server that listens for incoming JSON requests
24178
Deno.serve(async (req) => {
24279
const payload = await req.json();
24380

244-
const videoUrl = payload.record.video_url;
245-
246-
await tasks.trigger<typeof videoProcessAndUpdate>("video-process-and-update", { videoUrl });
247-
console.log(payload ?? "No video_url provided");
248-
24981
return new Response("ok");
25082
});
25183
```
25284

253-
<Note>
254-
Tasks in the `trigger` folder use Node, so they must stay in there or they will not run,
255-
especially if you are using a different runtime like Deno. Also do not add "`npm:`" to imports
256-
inside your task files, for the same reason.
257-
</Note>
258-
25985
### Deploy the Edge Function
26086

26187
Now deploy your new Edge Function with the following command:
@@ -321,16 +147,28 @@ and select the Edge Function you have created: `video-processing-handler`.{" "}
321147

322148
Your Database Webhook is now ready to use.
323149

324-
## Triggering the task
150+
## Creating and deploying the Trigger.dev task and updating the edge function
151+
152+
### Creating and deploying the Trigger.dev task
325153

326-
### Adding the logic to update the table row
154+
Create a new task file in your `/trigger` folder (the same place your 'Hello World' task was created). Call it `videoProcessAndUpdate.ts`.
327155

328-
First, you must go back to your `videoProcessAndUpdate` task code from earlier and add in the Supabase logic. This will:
156+
This task with take a video from a public video url, extract the audio using FFmpeg and transcribe the audio using Deepgram. The transcription summary will then be added back to the original row in the `video_transcriptions` table in Supabase.
329157

330-
- Create a Supabase client (you must update your environment variables in order for this to work)
331-
- Create a function which updates the table row with the exact match of the `video_url` payload with the new generated transcription.
158+
#### Generate the Database type definitions for your Supabase table
159+
160+
First, you need to [generate the type definitions](https://supabase.com/docs/guides/api/rest/generating-types) for your Supabase table using the Supabase CLI. This will allow you to use TypeScript to interact with your table.
161+
162+
```bash
163+
npx supabase generate types --project-url <your-project-url> --project-key <your-anon-key> --schema public
164+
```
165+
166+
<Note> Replace `<your-project-url>` with your Supabase project URL and `<your-anon-key>` with your `anon` `public` API key. </Note>
167+
168+
#### Create the transcription task
332169

333170
```ts /trigger/videoProcessAndUpdate.ts
171+
// Install any missing dependencies below using npm or yarn
334172
import { createClient as createDeepgramClient } from "@deepgram/sdk";
335173
import { createClient as createSupabaseClient } from "@supabase/supabase-js";
336174
import { logger, task } from "@trigger.dev/sdk/v3";
@@ -393,6 +231,8 @@ export const videoProcessAndUpdate = task({
393231
{
394232
model: "nova-2",
395233
smart_format: true,
234+
// paragraphs: true,
235+
// punctuate: true,
396236
diarize: true,
397237
}
398238
);
@@ -431,13 +271,100 @@ export const videoProcessAndUpdate = task({
431271
});
432272
```
433273

434-
### Adding your Supabase environment variables
274+
#### Adding the FFmpeg build extension
435275

436-
You will need to add your `SUPABASE_PROJECT_URL` and `SUPABASE_SERVICE_ROLE_KEY` as environment variables in your Trigger.dev project.
276+
Before you can deploy the task, you'll need to add the FFmpeg build extension to your `trigger.config.ts` file.
277+
278+
```ts trigger.config.ts
279+
import { ffmpeg } from "@trigger.dev/build/extensions/core";
280+
import { defineConfig } from "@trigger.dev/sdk/v3";
281+
282+
export default defineConfig({
283+
project: "<project ref>", // Replace with your project ref
284+
// Your other config settings...
285+
build: {
286+
extensions: [ffmpeg()],
287+
},
288+
});
289+
```
290+
291+
<Note>
292+
[Build extensions](/config/config-file#extensions) allow you to hook into the build system and
293+
customize the build process or the resulting bundle and container image (in the case of
294+
deploying). You can use pre-built extensions or create your own.
295+
</Note>
296+
297+
<Note>
298+
You'll also need to add `@trigger.dev/build` to your `package.json` file under `devDependencies`
299+
if you don't already have it there.
300+
</Note>
301+
302+
### Add your Deepgram and Supabase environment variables to your Trigger.dev project
303+
304+
You will need to add your `DEEPGRAM_SECRET_KEY`, `SUPABASE_PROJECT_URL` and `SUPABASE_SERVICE_ROLE_KEY` as environment variables in your Trigger.dev project. This can be found in the 'Environment Variables' page in your Trigger.dev project dashboard.
437305

438306
![Adding environment variables](/images/environment-variables-page.jpg)
439307

440-
### Testing the entire workflow
308+
### Deploying your task
309+
310+
You can now deploy your task using the following command:
311+
312+
<CodeGroup>
313+
314+
```bash npm
315+
npx trigger.dev@latest deploy
316+
```
317+
318+
```bash pnpm
319+
pnpm dlx trigger.dev@latest deploy
320+
```
321+
322+
```bash yarn
323+
yarn dlx trigger.dev@latest deploy
324+
```
325+
326+
</CodeGroup>
327+
328+
#### Update the Edge Function to trigger the task
329+
330+
Finally, we need to replace your `video-processing-handler` Edge Function code with the below to trigger the `videoProcessAndUpdate` task when it is called.
331+
332+
```ts functions/video-processing-handler/index.ts
333+
// Setup type definitions for built-in Supabase Runtime APIs
334+
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
335+
// Import the Trigger.dev SDK - replace "<your-sdk-version>" with the version of the SDK you are using, e.g. "3.0.0". You can find this in your package.json file.
336+
import { tasks } from "npm:@trigger.dev/<your-sdk-version>/v3";
337+
338+
// Sets up a Deno server that listens for incoming JSON requests
339+
Deno.serve(async (req) => {
340+
const payload = await req.json();
341+
342+
// This payload will contain the video url from the new row in the table
343+
const videoUrl = payload.record.video_url;
344+
345+
// Trigger the videoProcessAndUpdate task with the videoUrl payload
346+
await tasks.trigger<typeof videoProcessAndUpdate>("video-process-and-update", { videoUrl });
347+
console.log(payload ?? "No name provided");
348+
349+
return new Response("ok");
350+
});
351+
```
352+
353+
<Note>
354+
Tasks in the `trigger` folder use Node, so they must stay in there or they will not run,
355+
especially if you are using a different runtime like Deno. Also do not add "`npm:`" to imports
356+
inside your task files, for the same reason.
357+
</Note>
358+
359+
#### Redeploy the Edge Function
360+
361+
Now your Edge function has been update you will need to redeploy it to Supabase.
362+
363+
```bash
364+
supabase functions deploy video-processing-handler
365+
```
366+
367+
## Triggering the task
441368

442369
Your `video-processing-handler` Edge Function is now set up to trigger the `videoProcessAndUpdate` task every time a new row is inserted into your `video_transcriptions` table.
443370

0 commit comments

Comments
 (0)