Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate setCookie from /mobileapi/userinfo to /v1/users/authenticated; add getUserFunds method #824

Merged
merged 3 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/client/setCookie.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const options = require('../options.js')
const getCurrentUser = require('../util/getCurrentUser.js').func
const getAuthenticatedUser = require('../util/getAuthenticatedUser.js').func

exports.required = ['cookie']
exports.optional = ['validate']
Expand All @@ -11,7 +11,7 @@ exports.optional = ['validate']
* @alias setCookie
* @param {string} cookie - The cookie to sign in with.
* @param {boolean=} [validate=true] - Whether to validate the cookie or not.
* @returns {Promise<LoggedInUserData>}
* @returns {Promise<AuthenticatedUserData>}
* @example const noblox = require("noblox.js")
* noblox.setCookie("cookie").then(function() {
* //your code here
Expand All @@ -28,7 +28,7 @@ exports.func = async function (args) {
return false
}
try {
const res = await getCurrentUser({ jar: { session: args.cookie } })
const res = await getAuthenticatedUser({ jar: { session: args.cookie } })
options.jar.session = args.cookie
return res
} catch (error) {
Expand Down
44 changes: 44 additions & 0 deletions lib/economy/getUserFunds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Includes
const http = require('../util/http.js').func

// Args
exports.required = ['userId']
exports.optional = ['jar']

// Docs
/**
* 🔓 Gets the amount of robux for the authenticated user.
* @category User
* @param {number} userId - Must match the userId of the authenticated user
* @alias getUserFunds
* @returns {Promise<number>}
* @example const noblox = require("noblox.js")
* // Login using your cookie
* const currentUser = await noblox.setCookie(process.env.ROBLOXCOOKIE)
* const robux = await noblox.getUserFunds(currentUser.id)
*/

// Define
function getUserFunds (userId, jar) {
return http({
url: `//economy.roblox.com/v1/users/${userId}/currency`,
options: {
jar,
resolveWithFullResponse: true
}
})
.then(({ statusCode, body }) => {
const { robux, errors } = JSON.parse(body)
if (statusCode === 200) {
return robux
} else if (statusCode === 400 || statusCode === 403) {
throw new Error(`${errors[0].message} | userId: ${userId}`)
} else {
throw new Error(`An unknown error occurred with getUserFunds() | [${statusCode}] userId: ${userId}`)
}
})
}

exports.func = function ({ userId, jar }) {
return getUserFunds(userId, jar)
}
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ noblox.getGroupRevenueSummary = require('./economy/getGroupRevenueSummary.js')
noblox.getGroupTransactions = require('./economy/getGroupTransactions.js')
noblox.getResaleData = require('./economy/getResaleData.js')
noblox.getResellers = require('./economy/getResellers.js')
noblox.getUserFunds = require('./economy/getUserFunds.js')
noblox.getUserTransactions = require('./economy/getUserTransactions.js')
noblox.onGroupTransaction = require('./economy/onGroupTransaction.js')
noblox.acceptFriendRequest = require('./friends/acceptFriendRequest.js')
Expand Down
42 changes: 28 additions & 14 deletions lib/util/getCurrentUser.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Includes
const http = require('./http.js').func
const settings = require('../../settings.json')

const noblox = require('../index.js')

// Args
exports.optional = ['option', 'jar']

// Docs
Expand All @@ -12,6 +13,7 @@ exports.optional = ['option', 'jar']
* @param {string=} option - A specific option to return.
* @returns {LoggedInUserData}
* @example const noblox = require("noblox.js")
* @deprecated getCurrentUser() is deprecated; see getAuthenticatedUser(), getPremium(), getThumbnails(), getUserFunds() instead | August 27, 2024 - https://devforum.roblox.com/t/official-list-of-deprecated-web-endpoints/62889/66
* // Login using your cookie.
* const user = await noblox.getCurrentUser()
**/
Expand All @@ -20,23 +22,35 @@ exports.optional = ['option', 'jar']
exports.func = async function (args) {
const jar = args.jar
const option = args.option
const httpOpt = {
url: '//www.roblox.com/mobileapi/userinfo',
options: {
resolveWithFullResponse: true,
method: 'GET',
followRedirect: true,
jar
}
if (settings.show_deprecation_warnings) {
console.warn('[DEPRECATED]: getCurrentUser() is deprecated by Roblox; use getAuthenticatedUser(), getPremium(), getThumbnails(), or getUserFunds() instead!')
console.warn(' > Opt out of these warnings using noblox.setOptions({ show_deprecation_warnings: false })')
}
const res = await http(httpOpt)
if (res.statusCode !== 200) {
throw new Error('You are not logged in.')

const currentUser = await noblox.getAuthenticatedUser(jar)
const [premiumStatus, thumbnailResponse, robuxBalance] = await Promise.all(
[
noblox.getPremium(currentUser.id, jar),
noblox.getPlayerThumbnail(currentUser.id, '352x352', 'png', false, 'Body', jar),
noblox.getUserFunds(currentUser.id, jar)
]
)

const json = {
UserID: currentUser.id,
UserName: currentUser.name,
RobuxBalance: robuxBalance,
ThumbnailUrl: thumbnailResponse[0].imageUrl,
IsAnyBuildersClubMember: false,
IsPremium: premiumStatus,
DEPRECATION_WARNING: '[DEPRECATED]: noblox.getCurrentUser() is deprecated; use getAuthenticatedUser(), getPremium(), getThumbnails(), or getUserFunds() instead!'
}
const json = JSON.parse(res.body)

if (!option) {
return json
}

// Support queried rgequests `getCurrentUser('UserID') -> only UserID`
const searchKey = Object.keys(json).filter((key) => {
return option.toLowerCase() === key.toLowerCase()
})[0]
Expand Down
2 changes: 1 addition & 1 deletion lib/util/setOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const settings = require('../../settings.json')
* altering the settings.json file. Objects passed to this function should match the format of the settings.json file.
* Unknown keys, or malformed options will be rejected with an error.
* @category Utility
* @param {NobloxOptions} newOptions - The new options to set, structured as per [settings.json](https://github.com/noblox/noblox.js/blob/master/settings.json)
* @param {Partial<NobloxOptions>} newOptions - The new options to set, structured as per [settings.json](https://github.com/noblox/noblox.js/blob/master/settings.json)
* @returns void
* @see [settings.json](https://github.com/noblox/noblox.js/blob/master/settings.json) - default package settings
* @example const noblox = require("noblox.js")
Expand Down
3 changes: 3 additions & 0 deletions settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"show_deprecation_warnings": true,
"show_deprecation_warnings_desc": "Prints console warnings for functions that are being polyfilled by newer methods due to upstream Roblox API changes",

"session_only": true,
"session_only_desc": "Minimizes data usage and speed up requests by only saving session cookies, disable if you need other cookies to be saved as well.",

Expand Down
15 changes: 11 additions & 4 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ declare module "noblox.js" {
* NobloxOptions for setOptions, based from settings.json
*/
interface NobloxOptions {
/** Prints console warnings for functions that are being polyfilled by newer methods due to upstream Roblox API changes */
show_deprecation_warnings: boolean;

/** Minimizes data usage and speed up requests by only saving session cookies, disable if you need other cookies to be saved as well. (Default: true) */
session_only: boolean;

Expand Down Expand Up @@ -996,9 +999,8 @@ declare module "noblox.js" {
UserID: number,
UserName: string,
RobuxBalance: number,
TicketsBalance: number,
ThumbnailUrl: string,
IsAnyBuildersClubMember: boolean,
IsAnyBuildersClubMember: false,
IsPremium: boolean
}

Expand Down Expand Up @@ -1670,7 +1672,7 @@ declare module "noblox.js" {
* 🔐 Allows the user to login with a provided cookie string, bypassing the username/password captcha issues.
* By default, the provided cookie will be validated by making a HTTP request. To disable this behaviour, pass false as the second optional parameter (shouldValidate).
*/
function setCookie<B extends boolean = true>(cookie: string, shouldValidate?: B): B extends false ? boolean : Promise<LoggedInUserData>
function setCookie<B extends boolean = true>(cookie: string, shouldValidate?: B): B extends false ? boolean : Promise<AuthenticatedUserData>

/// DataStores

Expand Down Expand Up @@ -1770,6 +1772,11 @@ declare module "noblox.js" {
*/
function getUserTransactions(transactionType?: "Sale" | "Purchase" | "AffiliateSale" | "DevEx" | "GroupPayout" | "AdImpressionPayout", limit?: number, sortOrder?: SortOrder, jar?: CookieJar): Promise<TransactionItem[]>;

/**
* 🔐 Returns the current user's robux balance
*/
function getUserFunds(userId?: number, jar?: CookieJar): Promise<number>;

/// Friends

/**
Expand Down Expand Up @@ -2297,7 +2304,7 @@ declare module "noblox.js" {
* @param newOptions - The new options to set, structured as per settings.json
* @see https://github.com/noblox/noblox.js/blob/master/settings.json
*/
function setOptions(newOptions: NobloxOptions): void
function setOptions(newOptions: Partial<NobloxOptions>): void

// Events

Expand Down
6 changes: 4 additions & 2 deletions typings/jsDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ type CookieJar = {
* NobloxOptions for setOptions, based from settings.json
*/
type NobloxOptions = {
/** Prints console warnings for functions that are being polyfilled by newer methods due to upstream Roblox API changes */
show_deprecation_warnings: boolean;

/** Minimizes data usage and speed up requests by only saving session cookies, disable if you need other cookies to be saved as well. (Default: true) */
session_only: boolean;

Expand Down Expand Up @@ -1374,9 +1377,8 @@ type LoggedInUserData = {
UserID: number,
UserName: string,
RobuxBalance: number,
TicketsBalance: number,
ThumbnailUrl: string,
IsAnyBuildersClubMember: boolean,
IsAnyBuildersClubMember: false,
IsPremium: boolean
}

Expand Down
Loading