import { google } from 'googleapis';
class YouTubeClient {
youtube;
constructor(apiKey) {
if (!apiKey) {
throw new Error('YouTube API key is required. Set YOUTUBE_API_KEY environment variable.');
}
this.youtube = google.youtube({
version: 'v3',
auth: apiKey,
});
}
async searchVideos(options) {
const { query, maxResults = 10, type = 'video' } = options;
try {
const response = await this.youtube.search.list({
part: ['snippet'],
q: query,
type: [type],
maxResults: Math.min(maxResults, 50), // YouTube API max is 50
order: 'relevance',
});
const items = response.data.items || [];
return items
.filter((item) => item.id?.videoId !== undefined)
.map((item) => ({
videoId: item.id.videoId,
title: item.snippet?.title || 'Untitled',
channelTitle: item.snippet?.channelTitle || 'Unknown Channel',
description: item.snippet?.description || '',
thumbnailUrl: item.snippet?.thumbnails?.high?.url ||
item.snippet?.thumbnails?.default?.url || '',
publishedAt: item.snippet?.publishedAt || '',
}));
}
catch (error) {
if (error instanceof Error) {
if (error.message.includes('quota')) {
throw new Error('YouTube API quota exceeded. Please try again later or check your API key limits.');
}
if (error.message.includes('403')) {
throw new Error('YouTube API access forbidden. Please check your API key permissions.');
}
throw new Error(`YouTube API error: ${error.message}`);
}
throw error;
}
}
generatePlaylistUrl(videoIds) {
if (videoIds.length === 0) {
throw new Error('At least one video ID is required to create a playlist URL.');
}
if (videoIds.length === 1) {
return `https://www.youtube.com/watch?v=${videoIds[0]}`;
}
// YouTube watch_videos endpoint creates a temporary playlist
return `https://www.youtube.com/watch_videos?video_ids=${videoIds.join(',')}`;
}
}
let clientInstance = null;
export function getYouTubeClient() {
if (!clientInstance) {
const apiKey = process.env.YOUTUBE_API_KEY;
if (!apiKey) {
throw new Error('YOUTUBE_API_KEY environment variable is not set.');
}
clientInstance = new YouTubeClient(apiKey);
}
return clientInstance;
}
export { YouTubeClient };
//# sourceMappingURL=youtube-client.js.map