mirror of
https://github.com/LuanRT/YouTube.js.git
synced 2026-06-17 03:22:15 +00:00
121 lines
3.7 KiB
JavaScript
121 lines
3.7 KiB
JavaScript
'use strict';
|
|
|
|
const Axios = require('axios');
|
|
const Utils = require('./Utils');
|
|
const Constants = require('./Constants');
|
|
|
|
/** @namespace */
|
|
class Request {
|
|
/**
|
|
* @param {import('../Innertube')} session
|
|
*/
|
|
constructor(session) {
|
|
this.session = session;
|
|
|
|
this.instance = Axios.create({
|
|
...session.axios.defaults,
|
|
baseURL: Constants.URLS.API.PRODUCTION + session.version,
|
|
headers: Constants.INNERTUBE_HEADERS_BASE,
|
|
params: { key: session.key, prettyPrint: false },
|
|
validateStatus: () => true,
|
|
timeout: 15000
|
|
});
|
|
|
|
this.#setupInterceptor();
|
|
|
|
return this.instance;
|
|
}
|
|
|
|
#setupInterceptor() {
|
|
this.instance.interceptors.request.use((config) => {
|
|
const is_json_payload = typeof config.data == 'object';
|
|
|
|
config.headers['user-agent'] = Utils.getRandomUserAgent('desktop').userAgent;
|
|
config.headers['accept-language'] = `en-${this.session.config.gl || 'US'}`;
|
|
config.headers['x-goog-visitor-id'] = this.session.context.client.visitorData || '';
|
|
config.headers['x-youtube-client-version'] = this.session.context.client.clientVersion;
|
|
|
|
if (is_json_payload) {
|
|
config.data = {
|
|
context: JSON.parse(JSON.stringify(this.session.context)), // deep copies the context object
|
|
...config.data
|
|
};
|
|
|
|
this.#adjustContext(config.data.context, config.data.client);
|
|
|
|
config.headers['x-youtube-client-version'] = config.data.context.client.clientVersion;
|
|
config.headers['x-origin'] = config.data.context.client.originalUrl;
|
|
config.headers['origin'] = config.data.context.client.originalUrl;
|
|
|
|
delete config.data.client;
|
|
}
|
|
|
|
if (this.session.logged_in) {
|
|
const cookie = this.session.config.cookie;
|
|
|
|
const token = cookie &&
|
|
this.session.auth_apisid ||
|
|
this.session.access_token;
|
|
|
|
config.headers.cookie = cookie || '';
|
|
config.headers.authorization = cookie && token || `Bearer ${token}`;
|
|
|
|
!cookie && (delete config.params.key);
|
|
}
|
|
|
|
this.session.config.debug &&
|
|
console.info('\n', '[' + config.method.toUpperCase() + ']', '>', config.baseURL + config.url, '\n', config?.data, '\n');
|
|
|
|
return config;
|
|
}, (error) => {
|
|
throw new Utils.InnertubeError(error.message, error);
|
|
});
|
|
|
|
/**
|
|
* Standardizes the API response and catches all errors.
|
|
*/
|
|
this.instance.interceptors.response.use((res) => {
|
|
const response = {
|
|
success: res.status === 200,
|
|
status_code: res.status,
|
|
data: res.data
|
|
};
|
|
|
|
if (res.status !== 200)
|
|
throw new Utils.InnertubeError(`Request to ${res.config.url} failed with status code ${res.status} ${res.statusText}`, response);
|
|
|
|
return response;
|
|
});
|
|
|
|
this.instance.interceptors.response.use(undefined, (error) => {
|
|
if (error.info) return Promise.reject(error);
|
|
throw new Utils.InnertubeError('Could not complete this operation', error.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Adjusts the context according to the given client.
|
|
*
|
|
* @param {object} ctx
|
|
* @param {string} client
|
|
* @todo refactor this?
|
|
* @returns {void}
|
|
*/
|
|
#adjustContext(ctx, client) {
|
|
switch (client) {
|
|
case 'YTMUSIC':
|
|
ctx.client.clientVersion = Constants.CLIENTS.YTMUSIC.VERSION;
|
|
ctx.client.clientName = Constants.CLIENTS.YTMUSIC.NAME;
|
|
break;
|
|
case 'ANDROID':
|
|
ctx.client.clientVersion = Constants.CLIENTS.ANDROID.VERSION;
|
|
ctx.client.clientFormFactor = 'SMALL_FORM_FACTOR';
|
|
ctx.client.clientName = Constants.CLIENTS.ANDROID.NAME;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = Request; |