110 lines
3.1 KiB
TypeScript
110 lines
3.1 KiB
TypeScript
// Api request lib
|
|
import fetch, { FetchError, Headers } from "node-fetch";
|
|
import { URL, URLSearchParams } from "url";
|
|
|
|
namespace PeerTubeRequester {
|
|
export type Config = {
|
|
domain_name: string | URL;
|
|
username: string;
|
|
password: string;
|
|
};
|
|
}
|
|
|
|
type UploadInstruction = {
|
|
[key: string]: string;
|
|
channelId: string;
|
|
targetUrl: string;
|
|
};
|
|
|
|
class PeerTubeRequester {
|
|
readonly domain_name: URL;
|
|
readonly username: string;
|
|
readonly password: string;
|
|
|
|
constructor(readonly config: PeerTubeRequester.Config) {
|
|
this.domain_name = new URL("/", config.domain_name);
|
|
this.username = config.username;
|
|
this.password = config.password;
|
|
}
|
|
|
|
private async requestAuthToken(): Promise<void> {
|
|
let response = await fetch(
|
|
new URL(`/api/v1/oauth-clients/local`, this.domain_name)
|
|
);
|
|
if (!response.ok) {
|
|
throw new Error(response.statusText); // CRASH
|
|
}
|
|
const { client_id, client_secret } = await response.json();
|
|
|
|
const client_info: { [key: string]: string } = {
|
|
client_id,
|
|
client_secret,
|
|
grant_type: "password",
|
|
response_type: "code",
|
|
username: this.username,
|
|
password: this.password,
|
|
};
|
|
|
|
let myParams = new URLSearchParams();
|
|
for (const key in client_info) myParams.append(key, client_info[key]);
|
|
|
|
response = await fetch(new URL(`/api/v1/users/token`, this.domain_name), {
|
|
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<void> {
|
|
const accessToken = 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.domain_name),
|
|
{
|
|
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 };
|