youtubei 1.6.4 → 1.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/common/shared/HTTP/OAuth.js +16 -1
- package/dist/cjs/common/shared/HTTP/index.js +1 -0
- package/dist/cjs/youtube/Channel/ChannelParser.js +11 -6
- package/dist/cjs/youtube/Client/Client.js +7 -0
- package/dist/esm/common/shared/HTTP/OAuth.js +16 -1
- package/dist/esm/common/shared/HTTP/index.js +1 -0
- package/dist/esm/youtube/Channel/ChannelParser.js +12 -7
- package/dist/esm/youtube/Client/Client.js +11 -0
- package/dist/typings/common/shared/HTTP/HTTP.d.ts +2 -1
- package/dist/typings/common/shared/HTTP/OAuth.d.ts +20 -1
- package/dist/typings/common/shared/HTTP/index.d.ts +1 -0
- package/dist/typings/youtube/BaseChannel/BaseChannel.d.ts +4 -0
- package/dist/typings/youtube/Client/Client.d.ts +2 -1
- package/package.json +1 -1
|
@@ -15,8 +15,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.OAuth = void 0;
|
|
16
16
|
const crypto_1 = require("crypto");
|
|
17
17
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
18
|
+
/** OAuth Helper Class */
|
|
18
19
|
class OAuth {
|
|
19
|
-
static authorize() {
|
|
20
|
+
static authorize(manual) {
|
|
20
21
|
return __awaiter(this, void 0, void 0, function* () {
|
|
21
22
|
const body = {
|
|
22
23
|
client_id: this.CLIENT_ID,
|
|
@@ -34,6 +35,15 @@ class OAuth {
|
|
|
34
35
|
});
|
|
35
36
|
if (response.ok) {
|
|
36
37
|
const data = yield response.json();
|
|
38
|
+
if (manual) {
|
|
39
|
+
return {
|
|
40
|
+
deviceCode: data.device_code,
|
|
41
|
+
userCode: data.user_code,
|
|
42
|
+
expiresIn: data.expires_in,
|
|
43
|
+
interval: data.interval,
|
|
44
|
+
verificationUrl: data.verification_url,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
37
47
|
console.log(`[youtubei] Open ${data.verification_url} and enter ${data.user_code}`);
|
|
38
48
|
let authenticateResponse = null;
|
|
39
49
|
while (!authenticateResponse) {
|
|
@@ -58,6 +68,11 @@ class OAuth {
|
|
|
58
68
|
throw new Error("Authorization failed");
|
|
59
69
|
});
|
|
60
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Authenticate to obtain a token and refresh token using the code from the authorize method
|
|
73
|
+
*
|
|
74
|
+
* @param code code obtained from the authorize method
|
|
75
|
+
*/
|
|
61
76
|
static authenticate(code) {
|
|
62
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
63
78
|
const body = {
|
|
@@ -7,8 +7,8 @@ const PlaylistCompact_1 = require("../PlaylistCompact");
|
|
|
7
7
|
const VideoCompact_1 = require("../VideoCompact");
|
|
8
8
|
class ChannelParser {
|
|
9
9
|
static loadChannel(target, data) {
|
|
10
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
11
|
-
let channelId, title, avatar, subscriberCountText, videoCountText, tvBanner, mobileBanner, banner;
|
|
10
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
11
|
+
let channelId, title, handle, description, avatar, subscriberCountText, videoCountText, tvBanner, mobileBanner, banner;
|
|
12
12
|
const { c4TabbedHeaderRenderer, pageHeaderRenderer } = data.header;
|
|
13
13
|
if (c4TabbedHeaderRenderer) {
|
|
14
14
|
channelId = c4TabbedHeaderRenderer.channelId;
|
|
@@ -25,15 +25,20 @@ class ChannelParser {
|
|
|
25
25
|
data.contents.twoColumnBrowseResultsRenderer.tabs[0].tabRenderer.endpoint
|
|
26
26
|
.browseEndpoint.browseId;
|
|
27
27
|
title = pageHeaderRenderer.pageTitle;
|
|
28
|
-
const { metadata, image: imageModel, banner: bannerModel, } = pageHeaderRenderer.content.pageHeaderViewModel;
|
|
29
|
-
const metadataRow = metadata.contentMetadataViewModel.metadataRows.find((m) => m.metadataParts);
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const { metadata, image: imageModel, banner: bannerModel, description: descriptionModel, } = pageHeaderRenderer.content.pageHeaderViewModel;
|
|
29
|
+
const metadataRow = metadata.contentMetadataViewModel.metadataRows.find((m) => m.metadataParts && m.metadataParts.length == 2);
|
|
30
|
+
const handleRow = metadata.contentMetadataViewModel.metadataRows.find((m) => m.metadataParts && m.metadataParts.length == 1);
|
|
31
|
+
handle = (_j = handleRow === null || handleRow === void 0 ? void 0 : handleRow.metadataParts[0].text) === null || _j === void 0 ? void 0 : _j.content;
|
|
32
|
+
videoCountText = (_k = metadataRow.metadataParts.find((m) => m.text.styleRuns)) === null || _k === void 0 ? void 0 : _k.text.content;
|
|
33
|
+
subscriberCountText = (_l = metadataRow.metadataParts.find((m) => !m.text.styleRuns)) === null || _l === void 0 ? void 0 : _l.text.content;
|
|
32
34
|
avatar = imageModel.decoratedAvatarViewModel.avatar.avatarViewModel.image.sources;
|
|
33
35
|
banner = bannerModel === null || bannerModel === void 0 ? void 0 : bannerModel.imageBannerViewModel.image.sources;
|
|
36
|
+
description = descriptionModel === null || descriptionModel === void 0 ? void 0 : descriptionModel.descriptionPreviewViewModel.description.content;
|
|
34
37
|
}
|
|
35
38
|
target.id = channelId;
|
|
36
39
|
target.name = title;
|
|
40
|
+
target.handle = handle;
|
|
41
|
+
target.description = description;
|
|
37
42
|
target.thumbnails = new common_1.Thumbnails().load(avatar);
|
|
38
43
|
target.videoCount = videoCountText;
|
|
39
44
|
target.subscriberCount = subscriberCountText;
|
|
@@ -24,6 +24,13 @@ class Client {
|
|
|
24
24
|
this.options = Object.assign(Object.assign({ initialCookie: "", oauth: { enabled: false }, fetchOptions: {} }, options), { youtubeClientOptions: Object.assign({ hl: "en", gl: "US" }, options.youtubeClientOptions) });
|
|
25
25
|
this.http = new common_1.HTTP(Object.assign({ apiKey: constants_1.INNERTUBE_API_KEY, baseUrl: constants_1.BASE_URL, clientName: constants_1.INNERTUBE_CLIENT_NAME, clientVersion: constants_1.INNERTUBE_CLIENT_VERSION }, this.options));
|
|
26
26
|
}
|
|
27
|
+
get oauth() {
|
|
28
|
+
return {
|
|
29
|
+
token: this.http.oauth.token,
|
|
30
|
+
expiresAt: this.http.oauth.expiresAt,
|
|
31
|
+
refreshToken: this.http.oauth.refreshToken,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
27
34
|
/**
|
|
28
35
|
* Searches for videos / playlists / channels
|
|
29
36
|
*
|
|
@@ -36,10 +36,11 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
36
36
|
};
|
|
37
37
|
import { randomBytes } from "crypto";
|
|
38
38
|
import fetch from "node-fetch";
|
|
39
|
+
/** OAuth Helper Class */
|
|
39
40
|
var OAuth = /** @class */ (function () {
|
|
40
41
|
function OAuth() {
|
|
41
42
|
}
|
|
42
|
-
OAuth.authorize = function () {
|
|
43
|
+
OAuth.authorize = function (manual) {
|
|
43
44
|
return __awaiter(this, void 0, void 0, function () {
|
|
44
45
|
var body, response, data_1, authenticateResponse, err_1, message;
|
|
45
46
|
return __generator(this, function (_a) {
|
|
@@ -65,6 +66,15 @@ var OAuth = /** @class */ (function () {
|
|
|
65
66
|
return [4 /*yield*/, response.json()];
|
|
66
67
|
case 2:
|
|
67
68
|
data_1 = _a.sent();
|
|
69
|
+
if (manual) {
|
|
70
|
+
return [2 /*return*/, {
|
|
71
|
+
deviceCode: data_1.device_code,
|
|
72
|
+
userCode: data_1.user_code,
|
|
73
|
+
expiresIn: data_1.expires_in,
|
|
74
|
+
interval: data_1.interval,
|
|
75
|
+
verificationUrl: data_1.verification_url,
|
|
76
|
+
}];
|
|
77
|
+
}
|
|
68
78
|
console.log("[youtubei] Open " + data_1.verification_url + " and enter " + data_1.user_code);
|
|
69
79
|
authenticateResponse = null;
|
|
70
80
|
_a.label = 3;
|
|
@@ -101,6 +111,11 @@ var OAuth = /** @class */ (function () {
|
|
|
101
111
|
});
|
|
102
112
|
});
|
|
103
113
|
};
|
|
114
|
+
/**
|
|
115
|
+
* Authenticate to obtain a token and refresh token using the code from the authorize method
|
|
116
|
+
*
|
|
117
|
+
* @param code code obtained from the authorize method
|
|
118
|
+
*/
|
|
104
119
|
OAuth.authenticate = function (code) {
|
|
105
120
|
return __awaiter(this, void 0, void 0, function () {
|
|
106
121
|
var body, response, data;
|
|
@@ -17,9 +17,9 @@ var ChannelParser = /** @class */ (function () {
|
|
|
17
17
|
function ChannelParser() {
|
|
18
18
|
}
|
|
19
19
|
ChannelParser.loadChannel = function (target, data) {
|
|
20
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
21
|
-
var channelId, title, avatar, subscriberCountText, videoCountText, tvBanner, mobileBanner, banner;
|
|
22
|
-
var
|
|
20
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
21
|
+
var channelId, title, handle, description, avatar, subscriberCountText, videoCountText, tvBanner, mobileBanner, banner;
|
|
22
|
+
var _m = data.header, c4TabbedHeaderRenderer = _m.c4TabbedHeaderRenderer, pageHeaderRenderer = _m.pageHeaderRenderer;
|
|
23
23
|
if (c4TabbedHeaderRenderer) {
|
|
24
24
|
channelId = c4TabbedHeaderRenderer.channelId;
|
|
25
25
|
title = c4TabbedHeaderRenderer.title;
|
|
@@ -35,15 +35,20 @@ var ChannelParser = /** @class */ (function () {
|
|
|
35
35
|
data.contents.twoColumnBrowseResultsRenderer.tabs[0].tabRenderer.endpoint
|
|
36
36
|
.browseEndpoint.browseId;
|
|
37
37
|
title = pageHeaderRenderer.pageTitle;
|
|
38
|
-
var
|
|
39
|
-
var metadataRow = metadata.contentMetadataViewModel.metadataRows.find(function (m) { return m.metadataParts; });
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
var _o = pageHeaderRenderer.content.pageHeaderViewModel, metadata = _o.metadata, imageModel = _o.image, bannerModel = _o.banner, descriptionModel = _o.description;
|
|
39
|
+
var metadataRow = metadata.contentMetadataViewModel.metadataRows.find(function (m) { return m.metadataParts && m.metadataParts.length == 2; });
|
|
40
|
+
var handleRow = metadata.contentMetadataViewModel.metadataRows.find(function (m) { return m.metadataParts && m.metadataParts.length == 1; });
|
|
41
|
+
handle = (_j = handleRow === null || handleRow === void 0 ? void 0 : handleRow.metadataParts[0].text) === null || _j === void 0 ? void 0 : _j.content;
|
|
42
|
+
videoCountText = (_k = metadataRow.metadataParts.find(function (m) { return m.text.styleRuns; })) === null || _k === void 0 ? void 0 : _k.text.content;
|
|
43
|
+
subscriberCountText = (_l = metadataRow.metadataParts.find(function (m) { return !m.text.styleRuns; })) === null || _l === void 0 ? void 0 : _l.text.content;
|
|
42
44
|
avatar = imageModel.decoratedAvatarViewModel.avatar.avatarViewModel.image.sources;
|
|
43
45
|
banner = bannerModel === null || bannerModel === void 0 ? void 0 : bannerModel.imageBannerViewModel.image.sources;
|
|
46
|
+
description = descriptionModel === null || descriptionModel === void 0 ? void 0 : descriptionModel.descriptionPreviewViewModel.description.content;
|
|
44
47
|
}
|
|
45
48
|
target.id = channelId;
|
|
46
49
|
target.name = title;
|
|
50
|
+
target.handle = handle;
|
|
51
|
+
target.description = description;
|
|
47
52
|
target.thumbnails = new Thumbnails().load(avatar);
|
|
48
53
|
target.videoCount = videoCountText;
|
|
49
54
|
target.subscriberCount = subscriberCountText;
|
|
@@ -76,6 +76,17 @@ var Client = /** @class */ (function () {
|
|
|
76
76
|
this.options = __assign(__assign({ initialCookie: "", oauth: { enabled: false }, fetchOptions: {} }, options), { youtubeClientOptions: __assign({ hl: "en", gl: "US" }, options.youtubeClientOptions) });
|
|
77
77
|
this.http = new HTTP(__assign({ apiKey: INNERTUBE_API_KEY, baseUrl: BASE_URL, clientName: INNERTUBE_CLIENT_NAME, clientVersion: INNERTUBE_CLIENT_VERSION }, this.options));
|
|
78
78
|
}
|
|
79
|
+
Object.defineProperty(Client.prototype, "oauth", {
|
|
80
|
+
get: function () {
|
|
81
|
+
return {
|
|
82
|
+
token: this.http.oauth.token,
|
|
83
|
+
expiresAt: this.http.oauth.expiresAt,
|
|
84
|
+
refreshToken: this.http.oauth.refreshToken,
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
enumerable: false,
|
|
88
|
+
configurable: true
|
|
89
|
+
});
|
|
79
90
|
/**
|
|
80
91
|
* Searches for videos / playlists / channels
|
|
81
92
|
*
|
|
@@ -3,9 +3,10 @@ export declare type OAuthOptions = {
|
|
|
3
3
|
enabled: boolean;
|
|
4
4
|
refreshToken?: string;
|
|
5
5
|
};
|
|
6
|
-
declare type OAuthProps = {
|
|
6
|
+
export declare type OAuthProps = {
|
|
7
7
|
token: string | null;
|
|
8
8
|
expiresAt: Date | null;
|
|
9
|
+
refreshToken?: string;
|
|
9
10
|
};
|
|
10
11
|
declare type HTTPOptions = {
|
|
11
12
|
apiKey: string;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export interface AuthorizeResponse {
|
|
2
|
+
deviceCode: string;
|
|
3
|
+
userCode: string;
|
|
4
|
+
expiresIn: number;
|
|
5
|
+
interval: number;
|
|
6
|
+
verificationUrl: string;
|
|
7
|
+
}
|
|
1
8
|
export interface RefreshResponse {
|
|
2
9
|
accessToken: string;
|
|
3
10
|
expiresIn: number;
|
|
@@ -11,11 +18,23 @@ export interface AuthenticateResponse {
|
|
|
11
18
|
scope: string;
|
|
12
19
|
tokenType: string;
|
|
13
20
|
}
|
|
21
|
+
/** OAuth Helper Class */
|
|
14
22
|
export declare class OAuth {
|
|
15
23
|
private static CLIENT_ID;
|
|
16
24
|
private static CLIENT_SECRET;
|
|
17
25
|
private static SCOPE;
|
|
26
|
+
/**
|
|
27
|
+
* Start the authorization process
|
|
28
|
+
*
|
|
29
|
+
* @param manual If true, returns the raw response instead of printing out the code and automatically do a authentication pooling
|
|
30
|
+
*/
|
|
18
31
|
static authorize(): Promise<AuthenticateResponse>;
|
|
19
|
-
|
|
32
|
+
static authorize(manual: true): Promise<AuthorizeResponse>;
|
|
33
|
+
/**
|
|
34
|
+
* Authenticate to obtain a token and refresh token using the code from the authorize method
|
|
35
|
+
*
|
|
36
|
+
* @param code code obtained from the authorize method
|
|
37
|
+
*/
|
|
38
|
+
static authenticate(code: string): Promise<AuthenticateResponse>;
|
|
20
39
|
static refreshToken(refreshToken: string): Promise<RefreshResponse>;
|
|
21
40
|
}
|
|
@@ -16,6 +16,10 @@ export declare class BaseChannel extends Base implements BaseChannelProperties {
|
|
|
16
16
|
id: string;
|
|
17
17
|
/** The channel's name */
|
|
18
18
|
name: string;
|
|
19
|
+
/** The channel's handle start with @ */
|
|
20
|
+
handle: string;
|
|
21
|
+
/** The channel's description */
|
|
22
|
+
description?: string;
|
|
19
23
|
/** Thumbnails of this Channel */
|
|
20
24
|
thumbnails?: Thumbnails;
|
|
21
25
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestInit } from "node-fetch";
|
|
2
|
-
import { HTTP, OAuthOptions } from "../../common";
|
|
2
|
+
import { HTTP, OAuthOptions, OAuthProps } from "../../common";
|
|
3
3
|
import { Caption } from "../Caption";
|
|
4
4
|
import { Channel } from "../Channel";
|
|
5
5
|
import { LiveVideo } from "../LiveVideo";
|
|
@@ -22,6 +22,7 @@ export declare class Client {
|
|
|
22
22
|
/** @hidden */
|
|
23
23
|
options: ClientOptions;
|
|
24
24
|
constructor(options?: Partial<ClientOptions>);
|
|
25
|
+
get oauth(): OAuthProps;
|
|
25
26
|
/**
|
|
26
27
|
* Searches for videos / playlists / channels
|
|
27
28
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "youtubei",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.6",
|
|
4
4
|
"description": "Simple package to get information from youtube such as videos, playlists, channels, video information & comments, related videos, up next video, and more!",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|