-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Add 2nd-gen YouTube Sample #1220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
e809303
ad9f20f
b7a7740
3d1338f
e7c539c
884810f
c628d04
1a340a3
b13c54b
ca04ef7
ea07c50
2be60a0
282e2dd
0df09c2
cd4da12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"functions": { | ||
"source": "functions", | ||
"predeploy": [ | ||
"pnpm --prefix \"$RESOURCE_DIR\" run compile" | ||
] | ||
} | ||
} |
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/https"); | ||
const { defineSecret } = require("firebase-functions/params"); | ||
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, | ||
}; | ||
}), | ||
}; | ||
}); |
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "youtube-2nd-gen", | ||
"description": "Cloud Functions for Firebase 2nd Gen YouTube Sample", | ||
"main": "lib/index.js", | ||
"engines": { | ||
"node": "22" | ||
}, | ||
"scripts": { | ||
"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 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use ESM in this file, not CJS. update package.json to type:module too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the file to use ESM and also updated the
package.json
to include"type": "module"
.