// Includes
const http = require('../util/http').func
const getGeneralToken = require('../util/getGeneralToken').func
// Args
exports.required = ['gamePassId', 'name']
exports.optional = ['description', 'price', 'icon', 'jar']
// Docs
/**
* 🔐 Modifies an existing game pass.
* @category Game
* @alias configureGamePass
* @param {number} gamePassId - The id of the game pass.
* @param {string} name - The name of the game pass; skips name, description, and icon if set to "".
* @param {string=} description - The description of the game pass; description is updated when name is modified.
* @param {number|boolean=} price - The price of the game pass in Robux; sets to 'Off Sale' if 0, false, or a negative value; skips if true.
* @param {ReadStream=} icon - The read stream for the game pass icon being uploaded; .png, .jpg, .gif
* @returns {Promise<GamePassResponse>}
* @example const noblox = require("noblox.js")
* const fs = require("fs")
* // Login using your cookie
* noblox.configureGamePass(12345678, "Game Pass Title", "Game Pass Description", 1234, fs.createReadStream("./Image.png"))
**/
// Define
function configureGamePass (gamePassId, name, description, price, icon, jar, token) {
return new Promise((resolve, reject) => {
const file = icon && {
value: icon,
options: {
filename: 'icon.png',
contentType: 'image/png'
}
}
const httpOpt = {
url: '//www.roblox.com/game-pass/update',
options: {
method: 'POST',
jar: jar,
headers: {
'X-CSRF-TOKEN': token,
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryKMFaNaAn4j7XeMO'
},
resolveWithFullResponse: true,
formData: {
id: gamePassId,
name,
description,
file
}
}
}
// Skip updating name and description if name is empty.
if (!name) {
resolve({
gamePassId,
...price
})
}
return http(httpOpt).then(function (res) {
const json = JSON.parse(res.body)
if (json.isValid) {
resolve({
gamePassId,
name,
description: description || '',
...price,
iconChanged: !!file // Boolean Cast
})
} else {
const priceComment = (typeof (price) === 'number') ? ` | NOTE: Price has successfully been changed to ${price}R.` : ''
if (res.statusCode === 403) {
reject(new Error(`You do not have permission to edit this game pass.${priceComment}`))
} else if (json.error) {
reject(new Error(json.error + priceComment)) // 'The name or description contains inappropriate text.' or 'Text filtering service is unavailable at this time.'
} else {
reject(new Error(`An unexpected error occurred with status code ${res.statusCode}.${priceComment}`))
}
}
}).catch(error => reject(error))
})
}
// Configuring the name/description and Robux must be done in separate calls, albeit to the same end-point.
function configureRobux (args, token) {
const httpOpt = {
url: '//www.roblox.com/game-pass/update',
options: {
method: 'POST',
jar: args.jar,
headers: {
'X-CSRF-TOKEN': token
},
resolveWithFullResponse: true,
json: {
id: args.gamePassId,
price: Math.floor(args.price || 0), // Prevent Decimals
isForSale: !!Math.max(args.price, 0) // Boolean Cast
}
}
}
return http(httpOpt).then(function (res) {
if (res.body.isValid) {
// Passing price as an object, so they can be omitted if configureRobux is not run.
return configureGamePass(
args.gamePassId,
args.name,
args.description,
{
price: Math.max(Math.floor(args.price || 0), 0),
isForSale: !!Math.max(args.price, 0)
},
args.icon,
args.jar,
token
)
} else {
if (res.statusCode === 403) {
throw new Error('You do not have permission to edit this game pass.')
} else if (res.body.error) {
throw new Error(res.body.error)
} else {
throw new Error(`An unexpected error occurred with status code ${res.statusCode}.`)
}
}
})
}
exports.func = function (args) {
const jar = args.jar
return getGeneralToken({
jar
}).then(function (token) {
// Needs to catch falsy input of `false` and `0` as they should change the gamepass to offsale; price updating will be skipped if undefined.
if (typeof (args.price) === 'boolean' || typeof (args.price) === 'number') {
return configureRobux(args, token)
} else {
return configureGamePass(args.gamePassId, args.name, args.description, undefined, args.icon, jar, token)
}
})
}
Source