Skip to content
This repository has been archived by the owner on Sep 20, 2023. It is now read-only.

Allow channel tags + channel urls #128

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 32 additions & 39 deletions app/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -677,63 +677,56 @@ class YoutubeGrabberHelper {
case 1: return this.performChannelUrlRequest(channelId, urlAppendix)
case 2: return this.performUserUrlRequest(channelId, urlAppendix)
case 3: return this.performCUrlRequest(channelId, urlAppendix)
case 4: return this.performChannelTagRequest(channelId, urlAppendix)
case 5: return this.performChannelRequest(channelId, urlAppendix)
default: return this.performChannelPageRequestWithFallbacks(channelId, urlAppendix)
}
}

async performChannelPageRequestWithFallbacks(channelId, urlAppendix) {
const ajaxUrl = `https://www.youtube.com/channel/${channelId}/${urlAppendix}`
let workedUrl = 1
let channelPageResponse = await this.makeChannelRequest(ajaxUrl)

if (channelPageResponse.error) {
// Try again as a user channel
const userUrl = `https://www.youtube.com/user/${channelId}/${urlAppendix}`
channelPageResponse = await this.makeChannelRequest(userUrl)
workedUrl = 2
if (channelPageResponse.error) {
const cUrl = `https://www.youtube.com/c/${channelId}/${urlAppendix}`
channelPageResponse = await this.makeChannelRequest(cUrl)
workedUrl = 3
if (channelPageResponse.error) {
return Promise.reject(channelPageResponse.message)
}
}
async performChannelRequest(ajaxUrl, urlAppendix, cType) {
if (urlAppendix !== null) {
ajaxUrl += ajaxUrl.endsWith('/') ? urlAppendix : '/' + urlAppendix
}
return { response: channelPageResponse, channelIdType: workedUrl }
}

async performChannelUrlRequest(channelId, urlAppendix) {
const ajaxUrl = `https://www.youtube.com/channel/${channelId}/${urlAppendix}`

const channelPageResponse = await this.makeChannelRequest(ajaxUrl)

if (channelPageResponse.error) {
return Promise.reject(channelPageResponse.message)
}
return { response: channelPageResponse, channelIdType: 1 }
return { response: channelPageResponse, channelIdType: cType }
}

async performUserUrlRequest(channelId, urlAppendix) {
const ajaxUrl = `https://www.youtube.com/user/${channelId}/${urlAppendix}`
async performChannelPageRequestWithFallbacks(channelId, urlAppendix) {
return await this.performChannelUrlRequest(channelId, urlAppendix).catch(async _ => {
return await this.performChannelTagRequest(channelId, urlAppendix).catch(async _ => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made tag second as it seems like youtube will pe preferring these urls

return await this.performUserUrlRequest(channelId, urlAppendix).catch(async _ => {
return await this.performCUrlRequest(channelId, urlAppendix).catch(async _ => {
return await this.performChannelRequest(channelId, urlAppendix).catch(async e => {
return Promise.reject(e)
})
})
})
})
})
}

const channelPageResponse = await this.makeChannelRequest(ajaxUrl)
async performChannelUrlRequest(channelId, urlAppendix) {
const ajaxUrl = `https://www.youtube.com/channel/${channelId}/`
return await this.performChannelRequest(ajaxUrl, urlAppendix, 1)
}

if (channelPageResponse.error) {
return Promise.reject(channelPageResponse.message)
}
return { response: channelPageResponse, channelIdType: 2 }
async performUserUrlRequest(channelId, urlAppendix) {
const ajaxUrl = `https://www.youtube.com/user/${channelId}/`
return await this.performChannelRequest(ajaxUrl, urlAppendix, 2)
}

async performCUrlRequest(channelId, urlAppendix) {
const ajaxUrl = `https://www.youtube.com/c/${channelId}/${urlAppendix}`

const channelPageResponse = await this.makeChannelRequest(ajaxUrl)
const ajaxUrl = `https://www.youtube.com/c/${channelId}/`
return await this.performChannelRequest(ajaxUrl, urlAppendix, 3)
}

if (channelPageResponse.error) {
return Promise.reject(channelPageResponse.message)
}
return { response: channelPageResponse, channelIdType: 3 }
async performChannelTagRequest(channelTag, urlAppendix) {
const ajaxUrl = `https://www.youtube.com/@${channelTag}/`
return await this.performChannelRequest(ajaxUrl, urlAppendix, 4)
}

static findTab(tabs) {
Expand Down
6 changes: 4 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ declare module "yt-channel-info" {
Default = 0,
ChannelId,
LegacyName,
CustomURL
CustomURL,
ChannelTag,
ChannelUrl
}

/**
Expand Down Expand Up @@ -259,7 +261,7 @@ declare module "yt-channel-info" {
static searchChannelMore(payload: ContinuationPayload): Promise<ChannelInfoResponseContinuation<Video>>;

static getChannelLivestreams(payload: ChannelLivestreamsPayload): ChannelInfoResponse<Video>;

static getChannelShorts(payload: ChannelShortsPayload): ChannelInfoResponse<Video>;

static getRelatedChannelsMore(payload: ContinuationPayload): Promise<ChannelInfoResponseContinuation<RelatedChannel>>;
Expand Down
24 changes: 24 additions & 0 deletions test/channelUrl.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
const ytch = require('../index')
describe('Standalone Mode: Channel URL Testing', () => {
test('Fallback URL', () => {
// https://www.youtube.com/channel/UCfMJ2MchTSW2kWaT0kK94Yw
const parameters = { channelId: 'UCfMJ2MchTSW2kWaT0kK94Yw', channelIdType: 0 }
return ytch.getChannelInfo(parameters).then((data) => {
expect(data.authorId).toBe('UCfMJ2MchTSW2kWaT0kK94Yw')
})
})

test('Channel URL (ID-based)', () => {
// https://www.youtube.com/channel/UCfMJ2MchTSW2kWaT0kK94Yw
const parameters = { channelId: 'UCfMJ2MchTSW2kWaT0kK94Yw', channelIdType: 1 }
Expand All @@ -23,4 +31,20 @@ describe('Standalone Mode: Channel URL Testing', () => {
expect(data.authorId).toBe('UCkRfArvrzheW2E7b6SVT7vQ')
})
})

test('Whole URL', () => {
// https://www.youtube.com/channel/UCfMJ2MchTSW2kWaT0kK94Yw
const parameters = { channelId: 'https://www.youtube.com/channel/UCfMJ2MchTSW2kWaT0kK94Yw', channelIdType: 5 }
return ytch.getChannelInfo(parameters).then((data) => {
expect(data.authorId).toBe('UCfMJ2MchTSW2kWaT0kK94Yw')
})
})

test('Channel tag URL (whole url passed)', () => {
// https://www.youtube.com/@SurveillanceReport
const parameters = { channelId: 'SurveillanceReport', channelIdType: 4 }
return ytch.getChannelInfo(parameters).then((data) => {
expect(data.authorId).toBe('UC0W_BIuwk8D0Bv4THbVZZOQ')
})
})
})