From 0e90f87df980637dcb89c18347d584dafc8bfb30 Mon Sep 17 00:00:00 2001 From: ChrisChrome Date: Thu, 5 Sep 2024 13:36:49 -0600 Subject: [PATCH] Add a lil discord bot into the mix! --- commands.json | 9 ++ index.js | 215 ++++++++++++++++++++++++++++++++++- package-lock.json | 282 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + 4 files changed, 505 insertions(+), 3 deletions(-) create mode 100644 commands.json diff --git a/commands.json b/commands.json new file mode 100644 index 0000000..9d877db --- /dev/null +++ b/commands.json @@ -0,0 +1,9 @@ +[ + { + "name": "getaudio", + "description": "Get a raw audio from roblox", + "type": 1, + "integration_types": [0,1], + "contexts": [0, 1, 2] + } +] \ No newline at end of file diff --git a/index.js b/index.js index d91a201..4a1cf8d 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,18 @@ require("dotenv").config() +const colors = require("colors") const express = require("express") +const Discord = require("discord.js") +const discord = new Discord.Client({ + intents: [] +}) +const { + REST, + Routes +} = require('discord.js'); +const { title, send } = require("process"); +const rest = new REST({ + version: '10' +}).setToken(process.env.DISCORD_TOKEN); const codes = require("./codes.json"); const app = express() const fs = require("fs"); @@ -12,6 +25,114 @@ if (!fs.existsSync("./blacklist.json")) { fs.writeFileSync("./blacklist.json", "[]"); } +const bulk = async (assetIds, inputCookie) => { + // Impliment a rate limit of 25 requests per minute + if (!assetIds || !Array.isArray(assetIds)) { + return { + error: "Invalid data format", + status: "error" + }; + } + + // Build the batch request body + const batchRequests = assetIds.map(item => { + const assetId = item; + + if (!assetId) { + return { + assetId, + requestId: assetId, + status: "failure", + additional: "Missing assetId." + }; + } + + return { + assetId, + requestId: assetId + }; + }); + + // If body.cookie is provided, use it, else use process.env.COOKIE + const cookie = inputCookie || process.env.COOKIE; + + const options = { + method: 'POST', + headers: { + authority: 'assetdelivery.roblox.com', + accept: '', + 'accept-language': 'en-US,en;q=0.9', + 'cache-control': 'no-cache', + 'content-type': 'application/json', + origin: 'https://create.roblox.com', + pragma: 'no-cache', + referer: 'https://create.roblox.com/', + 'roblox-browser-asset-request': 'true', + 'roblox-place-id': '0', // Use a default or placeholder value if needed + 'sec-ch-ua': '"Opera GX";v="105", "Chromium";v="119", "Not?A_Brand";v="24"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0', + Cookie: `.ROBLOSECURITY=${cookie};` + }, + body: JSON.stringify(batchRequests) + }; + + try { + let response = await fetch("https://assetdelivery.roblox.com/v1/assets/batch", options); + let json = await response.json(); + //console.log(JSON.stringify(json, null, 2)); + // Build the response object + const responses = assetIds.reduce((acc, item, index) => { + const assetId = item; + if (json[index].errors) { + const errorCode = json[index].errors[0].code; + acc[assetId] = { + status: "failure", + code: errorCode, + message: codes[errorCode].message, + additional: codes[errorCode].description + }; + } else if (json[index].assetTypeId !== 3) { + // Return 415, the asset isnt audio + acc[assetId] = { + status: "failure", + code: 415, + message: codes[415].message, + additional: codes[415].description + }; + } else { + acc[assetId] = { + status: "success", + url: json[index].location + }; + } + return acc; + }, {}); + + return { + type: "batching-response", + data: responses + }; + + } catch (error) { + return { + type: "batching-response", + data: assetIds.reduce((acc, item) => { + acc[item] = { + status: "failure", + url: "", + additional: "Request failed" + }; + return acc; + }, {}) + }; + } +} + app.use((req, res, next) => { // Blacklist handler const blacklist = JSON.parse(fs.readFileSync("./blacklist.json", "utf-8")); if (blacklist.includes(req.ip)) { @@ -177,7 +298,95 @@ app.post("/", async (req, res) => { } }); +discord.on("ready", async () => { + console.log(`${colors.cyan("[Discord]")} Logged in as ${discord.user.displayName}`); -app.listen(port, () => { - console.log(`Listening on ${port}`); -}); \ No newline at end of file + const commands = require("./commands.json"); + //Register commands + await (async () => { + try { + console.log(`${colors.cyan("[Discord]")} Registering Commands...`) + //Global + await rest.put(Routes.applicationCommands(discord.user.id), { body: commands }) + console.log(`${colors.cyan("[Discord]")} Successfully registered commands.`); + } catch (error) { + console.error(error); + } + })(); + + app.listen(port, () => { + console.log(`${colors.cyan("[EXPRESS]")} Listening on ${port}`); + }); +}) + +discord.on("interactionCreate", async (interaction) => { + // When someone runs the /getaudio command, respond with a modal asking for the asset id and optional cookie + switch (interaction.type) { + case Discord.InteractionType.ApplicationCommand: + await interaction.showModal({ + //type: Discord.ComponentType.ActionRow, + title: "Get Audio", + custom_id: "getaudio", + components: [ + { + type: Discord.ComponentType.ActionRow, + components: [ + { + label: "Asset ID", + custom_id: "assetId", + type: Discord.ComponentType.TextInput, + style: Discord.TextInputStyle.Short, + required: true, + placeholder: "Asset ID", + maxLength: 15 + } + ] + }, + { + type: Discord.ComponentType.ActionRow, + components: [ + { + label: "Optional ROBLOSECURITY", + custom_id: "cookie", + type: Discord.ComponentType.TextInput, + style: Discord.TextInputStyle.Short, + required: false, + placeholder: "ROBLOSECURITY cookie", + maxLength: 100 + } + ] + } + ] + }) + break; + case Discord.InteractionType.ModalSubmit: + assetId = interaction.fields.getTextInputValue("assetId"); + cookie = interaction.fields.getTextInputValue("cookie"); + bulk([new String(new Number(assetId))], cookie ? cookie : null).then((data) => { + if (data.data[assetId].status == "failure") { + return interaction.reply({ + embeds: [{ + title: "Error", + color: 0xff0000, + description: `${data.data[assetId].message} - ${data.data[assetId].additional}` + }] + }); + } else { + return interaction.reply({ + files: [{ + attachment: data.data[assetId].url, + name: `${assetId}.ogg` + }], + embeds: [{ + title: "Success", + color: 0x00ff00, + description: `Downloaded audio file for asset ${assetId}` + }] + }) + } + }); + break; + } +}); + +discord.login(process.env.DISCORD_TOKEN) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6c2a2f6..592a382 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,191 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "colors": "^1.4.0", + "discord.js": "^14.16.1", "dotenv": "^16.4.5", "express": "^4.19.2" } }, + "node_modules/@discordjs/builders": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.9.0.tgz", + "integrity": "sha512-0zx8DePNVvQibh5ly5kCEei5wtPBIUbSoE9n+91Rlladz4tgtFbJ36PZMxxZrTEOQ7AHMZ/b0crT/0fCy6FTKg==", + "dependencies": { + "@discordjs/formatters": "^0.5.0", + "@discordjs/util": "^1.1.1", + "@sapphire/shapeshift": "^4.0.0", + "discord-api-types": "0.37.97", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.4", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/collection": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/formatters": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.5.0.tgz", + "integrity": "sha512-98b3i+Y19RFq1Xke4NkVY46x8KjJQjldHUuEbCqMvp1F5Iq9HgnGpu91jOi/Ufazhty32eRsKnnzS8n4c+L93g==", + "dependencies": { + "discord-api-types": "0.37.97" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.4.0.tgz", + "integrity": "sha512-Xb2irDqNcq+O8F0/k/NaDp7+t091p+acb51iA4bCKfIn+WFWd6HrNvcsSbMMxIR9NjcMZS6NReTKygqiQN+ntw==", + "dependencies": { + "@discordjs/collection": "^2.1.1", + "@discordjs/util": "^1.1.1", + "@sapphire/async-queue": "^1.5.3", + "@sapphire/snowflake": "^3.5.3", + "@vladfrangu/async_event_emitter": "^2.4.6", + "discord-api-types": "0.37.97", + "magic-bytes.js": "^1.10.0", + "tslib": "^2.6.3", + "undici": "6.19.8" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", + "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/util": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.1.tgz", + "integrity": "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/ws": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.1.1.tgz", + "integrity": "sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==", + "dependencies": { + "@discordjs/collection": "^2.1.0", + "@discordjs/rest": "^2.3.0", + "@discordjs/util": "^1.1.0", + "@sapphire/async-queue": "^1.5.2", + "@types/ws": "^8.5.10", + "@vladfrangu/async_event_emitter": "^2.2.4", + "discord-api-types": "0.37.83", + "tslib": "^2.6.2", + "ws": "^8.16.0" + }, + "engines": { + "node": ">=16.11.0" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/ws/node_modules/@discordjs/collection": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", + "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/ws/node_modules/discord-api-types": { + "version": "0.37.83", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.83.tgz", + "integrity": "sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==" + }, + "node_modules/@sapphire/async-queue": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.3.tgz", + "integrity": "sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/shapeshift": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-4.0.0.tgz", + "integrity": "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v16" + } + }, + "node_modules/@sapphire/snowflake": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz", + "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@types/node": { + "version": "22.5.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vladfrangu/async_event_emitter": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.6.tgz", + "integrity": "sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -84,6 +265,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -165,6 +354,36 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/discord-api-types": { + "version": "0.37.97", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.97.tgz", + "integrity": "sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==" + }, + "node_modules/discord.js": { + "version": "14.16.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.16.1.tgz", + "integrity": "sha512-/diX4shp3q1F3EySGQbQl10el+KIpffLSOJdtM35gGV7zw2ED7rKbASKJT7UIR9L/lTd0KtNenZ/h739TN7diA==", + "dependencies": { + "@discordjs/builders": "^1.9.0", + "@discordjs/collection": "1.5.3", + "@discordjs/formatters": "^0.5.0", + "@discordjs/rest": "^2.4.0", + "@discordjs/util": "^1.1.1", + "@discordjs/ws": "1.1.1", + "@sapphire/snowflake": "3.5.3", + "discord-api-types": "0.37.97", + "fast-deep-equal": "3.1.3", + "lodash.snakecase": "4.1.1", + "tslib": "^2.6.3", + "undici": "6.19.8" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -270,6 +489,11 @@ "node": ">= 0.10.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -437,6 +661,21 @@ "node": ">= 0.10" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" + }, + "node_modules/magic-bytes.js": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz", + "integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -730,6 +969,16 @@ "node": ">=0.6" } }, + "node_modules/ts-mixer": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -743,6 +992,19 @@ "node": ">= 0.6" } }, + "node_modules/undici": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", + "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -769,6 +1031,26 @@ "engines": { "node": ">= 0.8" } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index 166b1d3..9f7dffa 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "license": "ISC", "description": "", "dependencies": { + "colors": "^1.4.0", + "discord.js": "^14.16.1", "dotenv": "^16.4.5", "express": "^4.19.2" }