Skip to content

Commit

Permalink
refactor: Throw an error if an invalid client is specified
Browse files Browse the repository at this point in the history
  • Loading branch information
LuanRT committed Aug 8, 2024
1 parent 0e91a08 commit 4942992
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 14 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const youtube = await Innertube.create(/* options */);
| `generate_session_locally` | `boolean` | Specifies whether to generate the session data locally or retrieve it from YouTube. This can be useful if you need more performance. **NOTE:** If you are using the cache option and a session has already been generated, this will be ignored. If you want to force a new session to be generated, you must clear the cache or disable session caching. | `false` |
| `enable_session_cache` | `boolean` | Specifies whether to cache the session data. | `true` |
| `device_category` | `DeviceCategory` | Platform to use for the session. | `DESKTOP` |
| `client_type` | `ClientType` | InnerTube client type. | `WEB` |
| `client_type` | `ClientType` | InnerTube client type. It is not recommended to change this unless you know what you are doing. | `WEB` |
| `timezone` | `string` | The time zone. | `*` |
| `cache` | `ICache` | Used to cache algorithms, session data, and OAuth2 tokens. | `undefined` |
| `cookie` | `string` | YouTube cookies. | `undefined` |
Expand Down Expand Up @@ -271,7 +271,7 @@ Retrieves video info.
| Param | Type | Description |
| --- | --- | --- |
| target | `string` \| `NavigationEndpoint` | If `string`, the id of the video. If `NavigationEndpoint`, the endpoint of watchable elements such as `Video`, `Mix` and `Playlist`. To clarify, valid endpoints have payloads containing at least `videoId` and optionally `playlistId`, `params` and `index`. |
| client? | `InnerTubeClient` | `WEB`, `ANDROID`, `YTMUSIC`, `YTMUSIC_ANDROID` or `TV_EMBEDDED` |
| client? | `InnerTubeClient` | InnerTube client to use. |

<details>
<summary>Methods & Getters</summary>
Expand Down Expand Up @@ -338,7 +338,7 @@ Suitable for cases where you only need basic video metadata. Also, it is faster
| Param | Type | Description |
| --- | --- | --- |
| video_id | `string` | The id of the video |
| client? | `InnerTubeClient` | `WEB`, `ANDROID`, `YTMUSIC_ANDROID`, `YTMUSIC`, `TV_EMBEDDED` |
| client? | `InnerTubeClient` | InnerTube client to use. |

<a name="search"></a>
### `search(query, filters?)`
Expand Down Expand Up @@ -688,7 +688,7 @@ import { Innertube } from 'youtubei.js';
const videoInfo = await yt.actions.execute('/player', {
// You can add any additional payloads here, and they'll merge with the default payload sent to InnerTube.
videoId,
client: 'YTMUSIC', // InnerTube client options: ANDROID, YTMUSIC, YTMUSIC_ANDROID, WEB, or TV_EMBEDDED.
client: 'YTMUSIC', // InnerTube client to use.
parse: true // tells YouTube.js to parse the response (not sent to InnerTube).
});

Expand Down
2 changes: 1 addition & 1 deletion src/Innertube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import type Format from './parser/classes/misc/Format.js';

export type InnertubeConfig = SessionOptions;

export type InnerTubeClient = 'WEB' | 'iOS' | 'ANDROID' | 'YTMUSIC_ANDROID' | 'YTMUSIC' | 'YTSTUDIO_ANDROID' | 'TV_EMBEDDED' | 'YTKIDS';
export type InnerTubeClient = 'IOS' | 'WEB' | 'ANDROID' | 'YTMUSIC' | 'YTMUSIC_ANDROID' | 'YTSTUDIO_ANDROID' | 'TV_EMBEDDED' | 'YTKIDS';

export type SearchFilters = Partial<{
upload_date: 'all' | 'hour' | 'today' | 'week' | 'month' | 'year';
Expand Down
4 changes: 3 additions & 1 deletion src/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const OAUTH = Object.freeze({
})
});
export const CLIENTS = Object.freeze({
iOS: {
IOS: {
NAME_ID: '5',
NAME: 'iOS',
VERSION: '18.06.35',
Expand Down Expand Up @@ -81,3 +81,5 @@ export const INNERTUBE_HEADERS_BASE = Object.freeze({
'accept-encoding': 'gzip, deflate',
'content-type': 'application/json'
});

export const SUPPORTED_CLIENTS = [ 'IOS', 'WEB', 'YTKIDS', 'YTMUSIC', 'ANDROID', 'YTSTUDIO_ANDROID', 'YTMUSIC_ANDROID', 'TV_EMBEDDED' ];
24 changes: 16 additions & 8 deletions src/utils/HTTPClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export default class HTTPClient {
const n_body = {
...json,
// Deep copy since we're gonna be modifying it
context: JSON.parse(JSON.stringify(this.#session.context))
context: JSON.parse(JSON.stringify(this.#session.context)) as Context
};

this.#adjustContext(n_body.context, n_body.client);
Expand All @@ -111,7 +111,7 @@ export default class HTTPClient {
request_headers.set('User-Agent', Constants.CLIENTS.ANDROID.USER_AGENT);
request_headers.set('X-GOOG-API-FORMAT-VERSION', '2');
} else if (n_body.context.client.clientName === 'iOS') {
request_headers.set('User-Agent', Constants.CLIENTS.iOS.USER_AGENT);
request_headers.set('User-Agent', Constants.CLIENTS.IOS.USER_AGENT);
}

is_web_kids = n_body.context.client.clientName === 'WEB_KIDS';
Expand Down Expand Up @@ -165,7 +165,15 @@ export default class HTTPClient {
throw new InnertubeError(`Request to ${response.url} failed with status ${response.status}`, await response.text());
}

#adjustContext(ctx: Context, client: string): void {
#adjustContext(ctx: Context, client?: string): void {
if (!client)
return;

if (!Constants.SUPPORTED_CLIENTS.includes(client.toUpperCase()))
throw new InnertubeError(`Invalid client: ${client}`, {
available_innertube_clients: Constants.SUPPORTED_CLIENTS
});

if (
client === 'ANDROID' ||
client === 'YTMUSIC_ANDROID' ||
Expand All @@ -179,12 +187,12 @@ export default class HTTPClient {
ctx.client.platform = 'MOBILE';
}

switch (client) {
case 'iOS':
switch (client.toUpperCase()) {
case 'IOS':
ctx.client.deviceMake = 'Apple';
ctx.client.deviceModel = Constants.CLIENTS.iOS.DEVICE_MODEL;
ctx.client.clientVersion = Constants.CLIENTS.iOS.VERSION;
ctx.client.clientName = Constants.CLIENTS.iOS.NAME;
ctx.client.deviceModel = Constants.CLIENTS.IOS.DEVICE_MODEL;
ctx.client.clientVersion = Constants.CLIENTS.IOS.VERSION;
ctx.client.clientName = Constants.CLIENTS.IOS.NAME;
ctx.client.platform = 'MOBILE';
ctx.client.osName = 'iOS';
delete ctx.client.browserName;
Expand Down

0 comments on commit 4942992

Please sign in to comment.