// Api request lib import fetch, { Headers } from "node-fetch"; import { URL, URLSearchParams } from "url"; namespace PeerTubeRequester { export type Config = { domainName: string | URL; username: string; password: string; }; } type UploadInstruction = { [key: string]: string; channelId: string; targetUrl: string; }; class PeerTubeRequester { readonly domainName: URL; readonly username: string; readonly password: string; constructor(readonly config: PeerTubeRequester.Config) { this.domainName = new URL("/", config.domainName); this.username = config.username; this.password = config.password; } private async requestAuthToken(): Promise { let response = await fetch( new URL(`/api/v1/oauth-clients/local`, this.domainName) ); if (!response.ok) { throw new Error(response.statusText); // CRASH } const { client_id: clientId, client_secret: clientSecret } = await response.json(); const clientInfo: { [key: string]: string } = { clientId, clientSecret, grantType: "password", responseType: "code", username: this.username, password: this.password, }; let myParams = new URLSearchParams(); for (const key in clientInfo) myParams.append(key, clientInfo[key]); response = await fetch(new URL(`/api/v1/users/token`, this.domainName), { method: "post", body: myParams, }); if (!response.ok) { throw new Error(response.statusText); // CRASH } const { access_token: accessToken } = await response.json(); return accessToken; } async uploadFromUrl(message: UploadInstruction): Promise { const accessToken = await this.requestAuthToken(); const myUploadForm = new URLSearchParams(); const myHeader = new Headers(); myHeader.append("Authorization", `Bearer ${accessToken}`); for (const key in message) myUploadForm.append(key, message[key]); const response = await fetch( new URL("/api/v1/videos/imports", this.domainName), { method: "post", headers: myHeader, body: myUploadForm, } ); if (!response.ok) { switch (response.status) { case 400: throw new Error( `Bad or malformed request. Probably because your target URL (from Youtube?) was not accepted by the API.\ The target URL you attempted to pass: ${message.targetUrl}. Response from the server: ${response.statusText}` ); break; case 403: throw new Error(response.statusText); break; case 409: throw new Error( `Oops, your instance did not allowed the HTTPS import.\ Contact your administrator. ${response.statusText}` ); break; default: throw new Error( `Oh, you encountered an undocumented issues.\ Please create an issue to the plugin project. ERROR: ${response.statusText}` ); break; } } } } export { PeerTubeRequester };