roblox-audio-scheduler
Version:
Schedule when to upload an audio.
206 lines (176 loc) • 6.24 kB
text/typescript
// Dependencies
import got, { Got } from "got/dist/source";
import FormData from "form-data"
// Simple wait function
function wait(ms: number) {
return new Promise( resolve => setTimeout(resolve, ms) );
}
// Interface
export interface IAudioUploadConfig {
name: string,
file: string,
groupId?: number,
paymentSource: string,
estimatedFileSize?: number,
estimatedDuration?: number
}
export interface IAudioUploadData {
audio: Buffer,
name: string,
groupId?: number
}
export interface IAudioUploadData2 {
audio: Buffer,
name: string,
filetype: "mp3" | "ogg",
groupId?: string
}
// Class
export class AudioSchedule {
// Vars
cookie: string = "";
csrf: string = "";
HttpClient: Got = got;
// Initialiser
async init(cookie: string){
this.cookie = cookie;
this.csrf = await this.getCSRF(this.cookie);
this.HttpClient = got.extend({
prefixUrl: "https://publish.roblox.com/v1/",
headers: {
Cookie: `.ROBLOSECURITY=${cookie};`,
"X-CSRF-TOKEN": this.csrf,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 OPR/72.0.3815.473"
}
});
return this;
}
// Get __RequestVerificationToken
async getRequestVerificationToken(cookie: string){
// Get Response
const response = await got.get("https://roblox.com/build/upload", {
ignoreInvalidCookies: false,
headers: {
"Host": "www.roblox.com",
Cookie: `.ROBLOSECURITY=${cookie};`,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 OPR/72.0.3815.473"
}
});
// Match the token and return it
const result = response.body.match(/<input name=__RequestVerificationToken type=hidden value=(.+?)>/)
if (result){
return result[1]
}
}
// Get CSRF
async getCSRF(cookie: string){
// Get Response
const response = await got.post("https://auth.roblox.com/v2/logout", {
throwHttpErrors: false,
headers: {
Cookie: `.ROBLOSECURITY=${cookie};`
}
});
// Return CSRF
if (response.headers["x-csrf-token"]){
return response.headers["x-csrf-token"].toString();
} else {
throw("Invalid Cookie.");
}
}
// Upload Audio via ROBLOX website
async audioNew(data: IAudioUploadData2){ // this is a bit broken and idk how to fix it
// Checking
const canUpload = (await this.verify({
audio: data.audio,
name: data.name
})).canAfford
if (canUpload == false){
throw("Cannot afford to upload this audio.")
}
// Get verification token
const RequestVerificationToken = await this.getRequestVerificationToken(this.cookie)
// Form Data
const form = new FormData()
form.append("__RequestVerificationToken", RequestVerificationToken)
form.append("assetTypeId", "3")
form.append("isOggUploadEnabled", "True")
form.append("groupId", data.groupId || "")
form.append("onVerificationPage", "False")
form.append("captchaEnabled", "False")
form.append("captchaToken", "")
form.append("captchaProvider", "")
form.append(`Content-Disposition: form-data; name="file"; filename="${data.name}.${data.filetype}"\nContent-Type: audio/${data.filetype == "ogg" && "ogg" || "mpeg"}`, data.audio)
// Response
const response = await got.post("https://www.roblox.com/build/upload", {
headers: {
Cookie: `.ROBLOXSECURITY=${this.cookie}`
},
body: form,
});
const result = response.body.match(/uploadedId=(.+?)">here</)
if (result){
return result[1]
}
}
// Upload Audio
async audio(data: IAudioUploadData){
// Checking
const canUpload = (await this.verify(data)).canAfford
if (canUpload == false){
throw("Cannot afford to upload this audio.")
}
// Config
var config: IAudioUploadConfig = {
name: data.name,
file: data.audio.toString("base64"),
paymentSource: "User",
estimatedFileSize: data.audio.length
};
if (data.groupId){
config.groupId = data.groupId
}
// Response
const response = await this.HttpClient.post("audio", {
throwHttpErrors: false,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(config)
});
return JSON.parse(response.body);
}
// Verify
async verify(data: IAudioUploadData){
// Config
const config = {
name: "string",
file: "string",
paymentSource: "User",
fileSize: data.audio.length
}
// Response
const response = await this.HttpClient.post("audio/verify", {
throwHttpErrors: false,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(config)
});
return JSON.parse(response.body);
}
// Schedule audio
async scheduleAudio(data: IAudioUploadData, time: Date){
// Checking
if (this.csrf == ""){
throw("Make sure your cookie is valid!");
}
// Calculating how long to wait then waiting
const waitTime = time.getTime() - Date.now();
await wait(waitTime);
// Uploading audio
const response = await this.audio(data);
// Return
return response
}
}