UNPKG

suchtube

Version:

YouTube search as a service, with Slack and Discord integration and CLI

109 lines (89 loc) 2.91 kB
const YOUTUBE_API_URL = 'https://www.googleapis.com/youtube/v3/search' const youtubeAPI = async (query, options) => { const params = { q: query, key: process.env.SUCHTUBE_YOUTUBE_DATA_API_V3, maxResults: (options.all || options.random) ? 50 : 1, part: 'snippet' } if (!params.key || params.key == "") { throw new Error('Whoops! You must set your YouTube Data API key') } if (options.duration && options.duration !== 'any') { params.videoDuration = options.duration params.type = 'video' } // Build URL with query parameters const url = new URL(YOUTUBE_API_URL) Object.keys(params).forEach(key => url.searchParams.append(key, params[key])) const response = await fetch(url) const data = await response.json() return data.items.map(item => { let id, link, linkEmbed, kind switch (item.id.kind) { case 'youtube#channel': id = item.id.channelId kind = 'channel' link = `https://www.youtube.com/channel/${id}` linkEmbed = null break case 'youtube#playlist': id = item.id.playlistId kind = 'playlist' link = `https://www.youtube.com/playlist?list=${id}` linkEmbed = `https://www.youtube.com/embed?listType=playlist&list=${id}` break default: id = item.id.videoId kind = 'video' link = `https://www.youtube.com/watch?v=${id}` linkEmbed = `https://www.youtube.com/embed/${id}` break } return { id: id, kind: kind, link: link, linkEmbed: linkEmbed, title: item.snippet.title, description: item.snippet.description, thumbnail: item.snippet.thumbnails.medium.url, publishedAt: item.snippet.publishedAt, channelTitle: item.snippet.channelTitle } }) } // Helper function to apply time parameter to video links const applyTimeToVideo = (video, time) => { if (!time || video.kind === 'channel') { return video } const processedVideo = {...video} processedVideo.link = video.link + '&t=' + time if (video.kind === 'video') { processedVideo.linkEmbed = video.linkEmbed + '?start=' + time } else { processedVideo.linkEmbed = video.linkEmbed + '&start=' + time } return processedVideo } // Create an API object that can be stubbed in tests export const api = { youtubeAPI } export const search = async (query, options = {}) => { const videos = await api.youtubeAPI(query, options) if (videos.length == 0) return // If --all option is used, return all videos if (options.all) { return videos.map(video => applyTimeToVideo(video, options.time)) } let video if (options.random) { let index = Math.floor(Math.random() * videos.length) video = {...videos[index]} } else { video = {...videos[0]} } return applyTimeToVideo(video, options.time) }