Back to APIs

Upload videos, manage your playlists and subscribers.

Using the YouTube API with Trigger.dev

You can use Trigger.dev with any existing Node SDK or even just using fetch. Using io.runTask makes your YouTube background job resumable and appear in our dashboard.

Use io.runTask() and the official SDK or fetch.

Use our HTTP endpoint to subscribe to webhooks

Example code using YouTube

Below are some working code examples of how you can use YouTube with Trigger.dev. These samples are open source and maintained by the community, you can copy and paste them into your own projects.

1
import { TriggerClient } from "@trigger.dev/sdk";
2
import { createHmac } from "crypto";
3
import { XMLParser } from "fast-xml-parser";
4
5
// Docs: https://developers.google.com/youtube/v3/guides/push_notifications
6
// Go to https://pubsubhubbub.appspot.com/subscribe and enter the following details:
7
// callback URL is endpoint URL
8
// Topic URL is https://www.youtube.com/xml/feeds/videos.xml?channel_id=CHANNEL_ID (replace CHANNEL_ID with your channel ID)
9
// Select Verify Type as Synchronous
10
// Select mode as subscribe
11
// For Hmac secret and Verify Token, enter the same value. This is the secret that will be used to verify the request.
12
// Get endpoint URL and Secret from the `trigger.dev` dashboard
13
// Set the YOUTUBE_SIGNING_SECRET (Secret) in the .env file.
14
15
// Create an HTTP Endpoint, with the YouTube details
16
export const youtube = client.defineHttpEndpoint({
17
id: "youtube.com",
18
title: "YouTube",
19
source: "youtube.com",
20
icon: "youtube",
21
respondWith: {
22
// Don't trigger runs if they match this filter
23
skipTriggeringRuns: true,
24
filter: {
25
query: {
26
"hub.mode": [{ $endsWith: "subscribe" }],
27
},
28
},
29
handler: async (request, verify) => {
30
const searchParams = new URL(request.url).searchParams;
31
32
if (
33
searchParams.get("hub.verify_token") !==
34
process.env.YOUTUBE_SIGNING_SECRET
35
) {
36
return new Response("Unauthorized", { status: 401 });
37
}
38
return new Response(searchParams.get("hub.challenge") ?? "OK", {
39
status: 200,
40
});
41
},
42
},
43
verify: async (request) => {
44
const signature = request.headers.get("x-hub-signature");
45
46
if (!signature) {
47
return { success: false, reason: "Missing header" };
48
}
49
50
const secret = process.env.YOUTUBE_SIGNING_SECRET;
51
52
if (!secret) {
53
return { success: false, reason: "Missing secret" };
54
}
55
56
const [algorithm, hash] = signature.split("=");
57
const body = await request.text();
58
const digest = createHmac(algorithm, secret).update(body).digest("hex");
59
60
if (hash !== digest) {
61
return { success: false, reason: "Failed sha1 verification" };
62
}
63
64
return { success: true };
65
},
66
});
67
68
client.defineJob({
69
id: "http-youtube",
70
name: "HTTP YouTube",
71
version: "1.0.0",
72
enabled: true,
73
// Create a trigger from the HTTP endpoint
74
trigger: youtube.onRequest(),
75
run: async (request, io, ctx) => {
76
const body = await request.text();
77
const parser = new XMLParser();
78
const jObj = parser.parse(body);
79
await io.logger.info(`Body`, jObj);
80
},
81
});