From f475c40c827ee5800355c098b3f0ebbe0920e555 Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Sun, 30 May 2021 10:30:53 -0400 Subject: [PATCH] add some typescript bindings for the youtube api --- server/services/youtube.ts | 85 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/server/services/youtube.ts b/server/services/youtube.ts index 0e3584723..a39fe5be5 100644 --- a/server/services/youtube.ts +++ b/server/services/youtube.ts @@ -1,5 +1,5 @@ import { URL } from "url"; -import axios from "axios"; +import axios, { AxiosResponse } from "axios"; import _ from "lodash"; import { RedisClient } from "redis"; import { ServiceAdapter, VideoRequest } from "../serviceadapter"; @@ -21,6 +21,84 @@ interface YoutubeChannelData { customUrl?: string } +interface YoutubeApiVideoListResponse { + kind: "youtube#videoListResponse"; + etag: string; + nextPageToken: string; + prevPageToken: string; + pageInfo: YoutubeApiPageInfo; + items: YoutubeApiVideo[]; +} + +interface YoutubeApiPageInfo { + totalResults: number; + resultsPerPage: number; +} + +interface YoutubeApiVideo { + kind: "youtube#video"; + etag: string; + id: string; + snippet?: { + publishedAt: string; + channelId: string; + title: string; + description: string; + thumbnails: { + medium: YoutubeThumbnailInfo; + default: YoutubeThumbnailInfo; + }; + channelTitle: string; + tags: string[]; + categoryId: string; + liveBroadcastContent: string; + defaultLanguage: string; + localized: { + title: string; + description: string; + }; + defaultAudioLanguage: string; + }; + contentDetails?: { + duration: string; + dimension: string; + definition: string; + caption: string; + licensedContent: boolean; + regionRestriction: { + allowed?: (string)[] | null; + blocked?: (string)[] | null; + }; + projection: string; + hasCustomThumbnail: boolean; + }; + status?: { + uploadStatus: string; + failureReason: string; + rejectionReason: string; + privacyStatus: string; + publishAt: string; + license: string; + embeddable: boolean; + publicStatsViewable: boolean; + madeForKids: boolean; + selfDeclaredMadeForKids: boolean; + }; + statistics?: { + viewCount: number; + likeCount: number; + dislikeCount: number; + favoriteCount: number; + commentCount: number; + }; +} + +interface YoutubeThumbnailInfo { + url: string; + width: number; + height: number; +} + export default class YouTubeAdapter extends ServiceAdapter { apiKey: string redisClient: RedisClient @@ -282,7 +360,7 @@ export default class YouTubeAdapter extends ServiceAdapter { const parts = this.getNeededParts(onlyProperties); log.silly(`Requesting ${parts.length} parts for ${ids.length} videos`); try { - const res = await this.api + const res: AxiosResponse = await this.api .get("/videos", { params: { key: this.apiKey, @@ -291,8 +369,7 @@ export default class YouTubeAdapter extends ServiceAdapter { }, }); const results: Video[] = []; - for (let i = 0; i < res.data.items.length; i++) { - const item = res.data.items[i]; + for (const item of res.data.items) { const video: Video = { service: this.serviceId, id: item.id,