diff --git a/package.json b/package.json index 70356f954..0de521602 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "eslint": "9.6.0", "eslint-plugin-cypress": "3.3.0", "globals": "15.8.0", - "knip": "5.24.2", + "knip": "5.24.3", "prettier": "3.3.2", "prettier-plugin-organize-imports": "4.0.0", "typescript": "5.5.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a2682f4d..a6c1dd845 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: 15.8.0 version: 15.8.0 knip: - specifier: 5.24.2 - version: 5.24.2(@types/node@20.14.10)(typescript@5.5.3) + specifier: 5.24.3 + version: 5.24.3(@types/node@20.14.10)(typescript@5.5.3) prettier: specifier: 3.3.2 version: 3.3.2 @@ -4812,8 +4812,8 @@ packages: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} - knip@5.24.2: - resolution: {integrity: sha512-Y8YyqkheQ4IlVw1s5nOBrT4LZUl4g++gKmX+d/J9lxoR8pz6UV0Otn3GBbuc9JYYMjKVW94GLVtB7hKlzJSmrQ==} + knip@5.24.3: + resolution: {integrity: sha512-1KzMxvxKuNwOKcETu8GNnvFyxVy168Gkwls2eyLDtgXVhddoh9tRdiTs/cmZeGsLkFVSoH/FujL/wAvil9nFyg==} engines: {node: '>=18.6.0'} hasBin: true peerDependencies: @@ -12422,7 +12422,7 @@ snapshots: klona@2.0.6: {} - knip@5.24.2(@types/node@20.14.10)(typescript@5.5.3): + knip@5.24.3(@types/node@20.14.10)(typescript@5.5.3): dependencies: '@ericcornelissen/bash-parser': 0.5.3 '@nodelib/fs.walk': 2.0.0 diff --git a/server/src/common/innertube/innertubeFetch.ts b/server/src/common/innertube/innertubeFetch.ts index 61776155f..e7de6e088 100644 --- a/server/src/common/innertube/innertubeFetch.ts +++ b/server/src/common/innertube/innertubeFetch.ts @@ -21,6 +21,8 @@ export const innertubeFetch = async (input: InputType, init?: RequestInit) => { url = input.url; } + console.log(url); + return vtFetch.rawFetch(url, { ...(typeof input === 'string' ? {} : input), ...init, diff --git a/server/src/common/proxyAgent.ts b/server/src/common/proxyAgent.ts index a29aa4f15..c9c45ca19 100644 --- a/server/src/common/proxyAgent.ts +++ b/server/src/common/proxyAgent.ts @@ -60,7 +60,7 @@ const getSocksProxyAgent = (proxyUrl: string) => { const socksProxy = parseSocksURL(proxyUrl); const socksProxyAgent = socksDispatcher(socksProxy); return { - proxyAgent: socksDispatcher(socksProxy), + proxyAgent: socksProxyAgent, done: async () => { await socksProxyAgent.close(); } diff --git a/server/src/core/channels/channels.service.ts b/server/src/core/channels/channels.service.ts index 1fac256f7..9f1c9a31b 100644 --- a/server/src/core/channels/channels.service.ts +++ b/server/src/core/channels/channels.service.ts @@ -5,6 +5,7 @@ import fs from 'fs'; import { Model } from 'mongoose'; import path from 'path'; import { General } from 'server/common/general.schema'; +import { innertubeClient } from 'server/common/innertube/innertube'; import sharp from 'sharp'; import { checkParams, throwChannelError } from './channels.helper'; import { ChannelCommunityPostsContinuationDto } from './dto/response/channel-community-posts-continuation.dto'; @@ -30,6 +31,24 @@ export class ChannelsService { private readonly GeneralModel: Model ) {} + async resolveId(channelId: string): Promise { + if (!checkParams(channelId)) { + throw new BadRequestException('Error fetching channel homepage', 'Invalid channelId'); + } + if (channelId.startsWith('UC') && channelId.length === 24) { + return channelId; + } + + const innertube = await innertubeClient(); + + const page = await innertube.resolveURL(`http://youtube.com/${channelId}`); + if (page?.payload?.browseId) { + return page.payload.browseId; + } + + throw new NotFoundException('Channel not found'); + } + async getChannelHome(channelId: string): Promise { if (!checkParams(channelId)) { throw new BadRequestException('Error fetching channel homepage', 'Invalid channelId'); @@ -43,12 +62,11 @@ export class ChannelsService { // } } - getChannelInfo(channelId: string): Promise { - if (!checkParams(channelId)) { - throw new BadRequestException('Error fetching channel info', 'Invalid channelId'); - } + async getChannelInfo(channelId: string): Promise { try { - return YoutubeGrabber.getChannelInfo({ channelId }) as unknown as Promise; + const id = await this.resolveId(channelId); + const innertube = await innertubeClient(); + return (await innertube.getChannel(id)).getAbout() as any; } catch (error) { throwChannelError(error, 'Error fetching channel info'); } diff --git a/server/src/core/channels/yt-channel-info/app/YoutubeGrabber.ts b/server/src/core/channels/yt-channel-info/app/YoutubeGrabber.ts index 55913c92b..bd4d31e7c 100644 --- a/server/src/core/channels/yt-channel-info/app/YoutubeGrabber.ts +++ b/server/src/core/channels/yt-channel-info/app/YoutubeGrabber.ts @@ -99,6 +99,12 @@ export class YoutubeGrabber { .topicChannelDetailsRenderer; // = topicChannelDetailsRenderer } + + if (!channelHeaderData) { + channelHeaderData = + channelPageDataResponse?.header?.pageHeaderRenderer?.content?.pageHeaderViewModel; + } + const headerTabs = channelPageDataResponse?.contents?.twoColumnBrowseResultsRenderer?.tabs; const channelTabs = headerTabs .filter(tab => tab?.tabRenderer !== undefined && tab?.tabRenderer !== null) @@ -151,6 +157,10 @@ export class YoutubeGrabber { if (typeof channelHeaderData?.banner !== 'undefined') { bannerThumbnails = channelHeaderData?.banner?.thumbnails; + + if (!bannerThumbnails) { + bannerThumbnails = channelHeaderData?.banner?.imageBannerViewModel?.image?.sources; + } } const subscriberSplit = subscriberText?.split(' ');