Skip to content

Commit 28e84f6

Browse files
authored
feat(route/youtube): cache handle lookup (#17466)
1 parent f31071c commit 28e84f6

File tree

1 file changed

+31
-23
lines changed

1 file changed

+31
-23
lines changed

lib/routes/youtube/user.ts

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import cache from '@/utils/cache';
33
import utils from './utils';
44
import { config } from '@/config';
55
import { parseDate } from '@/utils/parse-date';
6-
import got from '@/utils/got';
7-
import { load } from 'cheerio';
6+
import ofetch from '@/utils/ofetch';
7+
import * as cheerio from 'cheerio';
88
import ConfigNotFoundError from '@/errors/types/config-not-found';
99

1010
export const route: Route = {
@@ -44,34 +44,42 @@ async function handler(ctx) {
4444
const username = ctx.req.param('username');
4545
const embed = !ctx.req.param('embed');
4646

47-
let playlistId;
48-
let channelName;
49-
let image;
50-
let description;
47+
let userHandleData;
5148
if (username.startsWith('@')) {
52-
const link = `https://www.youtube.com/${username}`;
53-
const response = await got(link);
54-
const $ = load(response.data);
55-
const ytInitialData = JSON.parse(
56-
$('script')
57-
.text()
58-
.match(/ytInitialData = ({.*?});/)?.[1] || '{}'
59-
);
60-
const channelId = ytInitialData.metadata.channelMetadataRenderer.externalId;
61-
channelName = ytInitialData.metadata.channelMetadataRenderer.title;
62-
image = ytInitialData.metadata.channelMetadataRenderer.avatar?.thumbnails?.[0]?.url;
63-
description = ytInitialData.metadata.channelMetadataRenderer.description;
64-
playlistId = (await utils.getChannelWithId(channelId, 'contentDetails', cache)).data.items[0].contentDetails.relatedPlaylists.uploads;
49+
userHandleData = await cache.tryGet(`youtube:handle:${username}`, async () => {
50+
const link = `https://www.youtube.com/${username}`;
51+
const response = await ofetch(link);
52+
const $ = cheerio.load(response);
53+
const ytInitialData = JSON.parse(
54+
$('script')
55+
.text()
56+
.match(/ytInitialData = ({.*?});/)?.[1] || '{}'
57+
);
58+
const metadataRenderer = ytInitialData.metadata.channelMetadataRenderer;
59+
60+
const channelId = metadataRenderer.externalId;
61+
const channelName = metadataRenderer.title;
62+
const image = metadataRenderer.avatar?.thumbnails?.[0]?.url;
63+
const description = metadataRenderer.description;
64+
const playlistId = (await utils.getChannelWithId(channelId, 'contentDetails', cache)).data.items[0].contentDetails.relatedPlaylists.uploads;
65+
66+
return {
67+
channelName,
68+
image,
69+
description,
70+
playlistId,
71+
};
72+
});
6573
}
66-
playlistId = playlistId || (await utils.getChannelWithUsername(username, 'contentDetails', cache)).data.items[0].contentDetails.relatedPlaylists.uploads;
74+
const playlistId = userHandleData?.playlistId || (await utils.getChannelWithUsername(username, 'contentDetails', cache)).data.items[0].contentDetails.relatedPlaylists.uploads;
6775

6876
const data = (await utils.getPlaylistItems(playlistId, 'snippet', cache)).data.items;
6977

7078
return {
71-
title: `${channelName || username} - YouTube`,
79+
title: `${userHandleData?.channelName || username} - YouTube`,
7280
link: username.startsWith('@') ? `https://www.youtube.com/${username}` : `https://www.youtube.com/user/${username}`,
73-
description: description || `YouTube user ${username}`,
74-
image,
81+
description: userHandleData?.description || `YouTube user ${username}`,
82+
image: userHandleData?.image,
7583
item: data
7684
.filter((d) => d.snippet.title !== 'Private video' && d.snippet.title !== 'Deleted video')
7785
.map((item) => {

0 commit comments

Comments
 (0)