feat: add Studio#setThumbnail() method (#111)

* feat: add support for protobuf payloads to `Actions#execute()`

* chore: compile proto definitions file

* feat(wip): add `Studio` class and implement `Studio#setThumbnail()` method

* fix: check if parameters are missing
This commit is contained in:
LuanRT
2022-07-23 02:45:47 -03:00
committed by GitHub
parent 8ed6cc9e24
commit a2103963b4
7 changed files with 3136 additions and 2865 deletions

View File

@@ -63,11 +63,11 @@ class Actions {
/**
* Mimmics the Axios API using Fetch's Response object.
*/
async #wrap(response: Response) {
async #wrap(response: Response, protobuf?: boolean) {
return {
success: response.ok,
status_code: response.status,
data: await response.json()
data: protobuf ? await response.text() : JSON.parse(await response.text())
};
}
@@ -673,35 +673,43 @@ class Actions {
* @param action - endpoint
* @param args - call arguments
*/
async execute(action: string, args: { [key: string]: any; parse: true; }) : Promise<ParsedResponse>;
async execute(action: string, args: { [key: string]: any; parse?: false; }) : Promise<ActionsResponse>;
async execute(action: string, args: { [key: string]: any; parse?: boolean; }): Promise<ParsedResponse | ActionsResponse> {
const data = { ...args };
async execute(action: string, args: { [key: string]: any; parse: true; protobuf?: false; serialized_data?: any }) : Promise<ParsedResponse>;
async execute(action: string, args: { [key: string]: any; parse?: false; protobuf?: true; serialized_data?: any }) : Promise<ActionsResponse>;
async execute(action: string, args: { [key: string]: any; parse?: boolean; protobuf?: boolean; serialized_data?: any }): Promise<ParsedResponse | ActionsResponse> {
let data;
if (Reflect.has(data, 'parse'))
delete data.parse;
if (!args.protobuf) {
data = { ...args };
if (Reflect.has(data, 'request'))
delete data.request;
if (Reflect.has(data, 'parse'))
delete data.parse;
if (Reflect.has(data, 'clientActions'))
delete data.clientActions;
if (Reflect.has(data, 'request'))
delete data.request;
if (Reflect.has(data, 'action')) {
data.actions = [ data.action ];
delete data.action;
}
if (Reflect.has(data, 'clientActions'))
delete data.clientActions;
if (Reflect.has(data, 'token')) {
data.continuation = data.token;
delete data.token;
if (Reflect.has(data, 'action')) {
data.actions = [ data.action ];
delete data.action;
}
if (Reflect.has(data, 'token')) {
data.continuation = data.token;
delete data.token;
}
} else {
data = args.serialized_data;
}
const response = await this.#session.http.fetch(action, {
method: 'POST',
body: JSON.stringify(data),
body: args.protobuf ? data : JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
'Content-Type': args.protobuf ?
'application/x-protobuf' :
'application/json'
}
});
@@ -709,7 +717,7 @@ class Actions {
return Parser.parseResponse(await response.json());
}
return this.#wrap(response);
return this.#wrap(response, args.protobuf);
}
#needsLogin(id: string) {

36
src/core/Studio.ts Normal file
View File

@@ -0,0 +1,36 @@
import Proto from '../proto';
import Session from './Session';
import { AxioslikeResponse } from './Actions';
import { MissingParamError } from '../utils/Utils';
class Studio {
#session;
constructor(session: Session) {
this.#session = session;
}
/**
* Uploads a custom thumbnail and sets it for a video.
* @example
* ```ts
* const buffer = fs.readFileSync('./my_awesome_thumbnail.jpg');
* const response = await yt.studio.setThumbnail(video_id, buffer);
* ```
*/
async setThumbnail(video_id: string, buffer: Uint8Array): Promise<AxioslikeResponse> {
if (!video_id || !buffer)
throw new MissingParamError('One or more parameters are missing.');
const payload = Proto.encodeCustomThumbnailPayload(video_id, buffer);
const response = await this.#session.actions.execute('/video_manager/metadata_update', {
protobuf: true,
serialized_data: payload
});
return response;
}
}
export default Studio;