Fetching videos with the Youtube API

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.

Making Migrations

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.

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.

Description

Once the project is created, search for the Youtube Data API in the search bar, and click “enable”.

Description

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.

Fetching Youtube Videos

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,
  };
}

Cron Jobs and rebuilding the site.

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! 😎

Table of Contents