const { SlashCommandBuilder } = require('@discordjs/builders'); const noblox = require("noblox.js"); const { cookies, commands } = require("../config/config.js") async function execute(interaction) { const game = interaction.options.getString("game"); const cookie = cookies[game]; if (cookie === undefined) { await interaction.reply({content: "Invalid game specified!", ephemeral: true}); return; } const id = interaction.options.getInteger("asset_id"); await noblox.setCookie(cookie).then(async () => { let info; // validate that this is a model try { info = await getProductInfo(id); if (info.AssetTypeId != 10) { await interaction.reply({content: `(id: ${id}) is not a valid model ID.`, ephemeral: true}); return; } } catch (error) { console.log(error); await interaction.reply({content: `There is a problem with this asset ID (id: ${id}).`, ephemeral: true}); return; } buy(undefined, await noblox.getGeneralToken(), info, 0).then(async () => { await interaction.reply( ` Now that your map (id: ${id}) has been taken by the ${game} maptest bot you can load it into the ${game} maptest place. To load your map, join the game and say \`\`\` !map ${id} \`\`\`Read what it says. If your map successfully loaded type !rtv and then choose your map. If it did not load successfully, you can expand the chat to view the full error message by clicking and dragging on the edge of the chat. ` ); }) .catch(async (error) => { if (error.message == "You already own this item.") { await interaction.reply({content: "The bot has already taken this model!", ephemeral: true}); } else { await interaction.reply({content: `An error occured trying to take the model (id: ${id}). Make sure it is uncopylocked!`, ephemeral: true}); console.log(`Could not take asset ID ${id}: `); console.log(error); } }); }); } module.exports = { data: new SlashCommandBuilder() .setName('take') .setDescription('Takes an asset ID') .addStringOption(option => option.setName("game") .setDescription("Select the maptest game") .setRequired(true) .addChoices(commands)) .addIntegerOption(option => option.setName("asset_id") .setDescription("The asset ID of the model") .setRequired(true)) , execute }; async function buy (jar, token, product, price) { const robux = product.PriceInRobux || 0 const productId = product.ProductId if (price) { if (typeof price === 'number') { if (robux !== price) { throw new Error('Price requirement not met. Requested price: ' + price + ' Actual price: ' + robux) } } else if (typeof price === 'object') { const high = price.high const low = price.low if (high) { if (robux > high) { throw new Error('Price requirement not met. Requested price: <=' + high + ' Actual price: ' + robux) } } if (low) { if (robux < low) { throw new Error('Price requirement not met. Requested price: >=' + low + ' Actual price: ' + robux) } } } } const httpOpt = { url: '//economy.roblox.com/v1/purchases/products/' + productId, options: { method: 'POST', jar: jar, headers: { 'X-CSRF-TOKEN': token }, json: { expectedCurrency: 1, expectedPrice: robux, expectedSellerId: product.Creator.Id } } } const json = await noblox.http(httpOpt); let err = json.errorMsg; if (json.reason === 'InsufficientFunds') { err = 'You need ' + json.shortfallPrice + ' more robux to purchase this item.'; } else if (json.errorMsg) { err = json.errorMsg; } if (!err) { return { productId, price: robux }; } else { throw new Error(err); } } function getProductInfo (asset) { return new Promise(async (resolve, reject) => { const httpOpt = { url: `//economy.roblox.com/v2/assets/${asset}/details`, options: { resolveWithFullResponse: true, method: 'GET' } } try { const res = await noblox.http(httpOpt); if (res.statusCode === 200) { resolve(JSON.parse(res.body)); } else { // Sourced from: https://stackoverflow.com/a/32278428 const isAnObject = (val_1) => !!(val_1 instanceof Array || val_1 instanceof Object); const body = isAnObject(res.body) ? JSON.parse(res.body) : {}; if (body.errors && body.errors.length > 0) { const errors = body.errors.map((e) => { return e.message; }); reject(new Error(`${res.statusCode} ${errors.join(', ')}`)); } else { reject(new Error(`${res.statusCode} ${res.body}`)); } } } catch (error) { return reject(error); } }) }