Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,697 changes: 5,697 additions & 0 deletions Node/quickstarts/genkit-helloworld/functions/pnpm-lock.yaml

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions Node/youtube/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# YouTube: Get information about a YouTube channel (2nd Gen)

This quickstart demonstrates how to query the
[YouTube Data API](https://developers.google.com/youtube/v3) using **Cloud
Functions for Firebase (2nd Gen)** with an HTTPS trigger.

## Introduction

The function `getChannelInfo` returns information about a Youtube channel. By
default it will return information about the
[Firebase YouTube channel](https://www.youtube.com/user/Firebase), but you can pass it a
`channelId` URL Query parameter to query any channel you'd like.

## Setup

### Get a YouTube API Key

1. Create a Firebase Project on the
[Firebase Console](https://console.firebase.google.com) if you don't already have a project you want to use.
1. Upgrade your Firebase project to the
[Blaze "pay as you go" plan](https://firebase.google.com/pricing)
1. Enable the Youtube API by visiting the
[API console](http://console.cloud.google.com/marketplace/product/google/youtube.googleapis.com),
selecting your Firebase project, and clicking "ENABLE".
1. Once the API is enabled, visit the
[credentials tab](http.console.cloud.google.com/apis/api/youtube.googleapis.com/credentials)
and click "CREATE CREDENTIALS" to create a YouTube API key.

### Clone and configure the function

1. Install the Firebase CLI and log in:
```
npm install --global firebase-tools

firebase login
```
1. Clone or download this repo and open the `Node/youtube` directory.
1. `cd` into the `functions` directory and install dependencies with `pnpm install`
1. Set up your Firebase project by running `firebase use --add` with the
Firebase CLI, select your Project ID and follow the instructions.
1. Set the YouTube API key as a secret:
```bash
firebase functions:secrets:set YOUTUBE_API_KEY
```
When prompted, enter the API key you created.

### Run your function locally with the Firebase Emulator Suite

1. Start the emulator:
```bash
firebase emulators:start --only functions
```
1. Check the emulator output to find the URL of the `getChannelInfo` function. It will looks something like `http://localhost:5001/my-project-id/us-central1/getChannelInfo`
1. Via CURL or in your browser, visit the URL that the function is running at. Optionally, add a query string `?channelId=SOME_CHANNEL_ID` to the end of the URL.
1. You should get a JSON response with information about the YouTube channel!


## Deploy the app to prod

Deploy to Firebase using the following command:

```bash
firebase deploy
```

This deploys and activates the `getChannelInfo` function.

> The first time you call `firebase deploy` on a new project with Functions will take longer than usual.

## Modify it to your needs

Now that you've got this sample working, modify it to work for your use case! Some ideas:

- Check out the other things you can query with the [YouTube Data API](https://developers.google.com/youtube/v3/docs)
- Convert `getChannelInfo` function to a scheduled function, and write the new latest videos for a channel into Firestore or Realtime Database
- ...anything else you can think of!
8 changes: 8 additions & 0 deletions Node/youtube/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"functions": {
"source": "functions",
"predeploy": [
"pnpm --prefix \"$RESOURCE_DIR\" run compile"
]
}
}
71 changes: 71 additions & 0 deletions Node/youtube/functions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const { onCall } = require("firebase-functions/v2/https");
const { defineSecret } = require("firebase-functions/v2/params");
Copy link
Collaborator

Choose a reason for hiding this comment

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

remove the /v2 from the import path. v2 is the default import

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! I've removed the /v2 from the import paths as you suggested.

Copy link
Collaborator

Choose a reason for hiding this comment

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

remove the v2 from the import path. v2 is the default import

const { google } = require("googleapis");

const youtubeApiKey = defineSecret("YOUTUBE_API_KEY");

const FIREBASE_YOUTUBE_CHANNEL_ID = "UCP4bf6IHJJQehibu6ai__cg";

exports.getChannelInfo = onCall({ secrets: [youtubeApiKey] }, async (request: any) => {
const youtube = google.youtube({
version: "v3",
auth: youtubeApiKey.value(),
});

const channelId = request.data.channelId || FIREBASE_YOUTUBE_CHANNEL_ID;

// Fetch channel information
// https://developers.google.com/youtube/v3/docs/channels/list
const { data: channelData } = await youtube.channels.list({
part: ["snippet", "statistics"],
id: [channelId],
maxResults: 1,
});

if (!channelData.items || channelData.items.length !== 1) {
return { error: `Channel with ID ${channelId} not found.` };
}

const channel = channelData.items[0];

// Fetch the channel's latest videos
// https://developers.google.com/youtube/v3/docs/search/list
const { data: videoData } = await youtube.search.list({
part: ["id", "snippet"],
order: "date",
channelId,
maxResults: 3,
});

const videos = videoData.items || [];

return {
id: channelId,
channelTitle: channel.snippet!.title,
channelDescription: channel.snippet!.description,
subscriberCount: channel.statistics!.subscriberCount,
recentVideos: videos.map((video: any) => {
return {
videoTitle: video.snippet!.title,
videoUrl: `https://www.youtube.com/watch?v=${video.id!.videoId}`,
videoDescription: video.snippet!.description,
};
}),
};
});
62 changes: 62 additions & 0 deletions Node/youtube/functions/lib/index.js
Copy link
Collaborator

Choose a reason for hiding this comment

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

add this lib output folder to a gitignore in this directory

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Node/youtube/functions/lib/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions Node/youtube/functions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "youtube-2nd-gen",
"description": "Cloud Functions for Firebase 2nd Gen YouTube Sample",
"main": "lib/index.js",
"engines": {
"node": "22"
},
"scripts": {
"lint": "eslint .",
"serve": "firebase emulators:start --only functions",
"compile": "tsc",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"firebase-admin": "^12.0.0",
"firebase-functions": "^5.0.0",
"googleapis": "^133.0.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"typescript": "^5.4.5"
},
"private": true
}
Loading