Tue Dec 19 2023
Recently I published my first actual video on Youtube and with a few more in the works, I decided I’d start adding videos to my website similar to how I list articles. In this article, I’ll guide you through how I added a cron-job that automatically fetches the latest videos from my Youtube Channel and displays them on my website.
As I wanted to store the video’s information in the database, I started with making a migration file called videos
and a Video
model to go along with it.
node ace make:migration videos
node ace make:model Video
Inside the videos migration file, I added several columns for storing the video’s title, description, thumbnail and ID. Then in the Video model file, I added this as columns like so;
import BaseSchema from "@ioc:Adonis/Lucid/Schema";
export default class extends BaseSchema {
protected tableName = "videos";
public async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments("id");
table.string("youtube_id");
table.string("title");
table.string("thumbnail");
table.text("description");
/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp("created_at", { useTz: true });
table.timestamp("updated_at", { useTz: true });
});
}
public async down() {
this.schema.dropTable(this.tableName);
}
}
import { DateTime } from "luxon";
import { BaseModel, column } from "@ioc:Adonis/Lucid/Orm";
export default class Video extends BaseModel {
@column({ isPrimary: true })
public id: number;
@column()
public youtube_id: string;
@column()
public title: string;
@column()
public description: string;
@column()
public thumbnail: string | null;
@column.dateTime({ autoCreate: true })
public createdAt: DateTime;
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime;
}
I ran the migration using node ace migration:run
and then moved onto fetching the videos with the Youtube API.
To get an API key for the Youtube, we need to head over to the Google Cloud Console. In GCC, we’ll create a new project called YoutubeAPI
.
Once the project is created, search for the Youtube Data API in the search bar, and click “enable”.
GCC will redirect you to the management page for the Youtube Data API. On this screen, click the “credentials” tab and then “+ create credentials” → “API Key”.
Voila! We now have a Youtube API key.
To fetch videos, we’ll first need to install the google apis npm package, and create a new file called Youtube.ts
inside our App/Services
directory.
npm install googleapis
Then inside our newly-created Youtube.ts
file, we’ll write a new function that fetches all the videos in the “uploads” playlist, and saves them in the database.
import Video from "App/Models/Video";
import { google } from "googleapis";
const youtube = google.youtube({
version: "v3",
auth: "YOUR_API_KEY",
});
export async function fetchYoutubeVideos() {
const response = await youtube.playlistItems.list({
part: ["contentDetails,snippet, id"],
playlistId: "UPLOAD_PLAYLIST_ID",
});
let videos = response.data.items;
// If there's no videos, just return
if (!videos) {
return;
}
// Loop through each video and create it in the database if it doesn't exist.
await Promise.all(
videos.map(async (video) => {
return await Video.firstOrCreate(
{
youtube_id: video.snippet?.resourceId?.videoId?.toString(),
},
{
title: video.snippet?.title!,
thumbnail: video.snippet?.thumbnails?.medium?.url,
youtube_id: video.snippet?.resourceId?.videoId?.toString(),
description: video.snippet?.description!,
}
);
})
);
return {
done: true,
};
}
Finally, we’ll add a cron job to fetch the videos every 2 weeks. Check out Building a Post Scheduler to learn how to add cron jobs to AdonisJS.
App/Cron/index.ts
/**
* Fetch Videos: Runs every 14th day-of-month from 1 through 31..
*/
scheduler.scheduleJob("0 0 1/14 * *", async function () {
await fetchYoutubeVideos();
await rebuildSite();
});
In this cron job, I also add a rebuildSite()
which is sends a POST request to my site’s frontend (hosted on Netlify) to rebuild the site. During the build process, the frontend fetches videos from the API’s list Videos endpoint so it can statically generate a list of videos similar to the blog layout.
That concludes this tutorial on how to fetch Youtube videos/how I added youtube videos to my website using AdonisJS.
Thanks for reading and happy coding! 😎