Skip to content

Commit 2be4343

Browse files
authored
Migrate setCookie from /mobileapi/userinfo to /v1/users/authenticated; add getUserFunds method (#824)
* feat(breaking)!: add getUserFunds(); migrate setCookie() from getCurrentUser() to getAuthenticatedUser(); polyfill and deprecate getCurrentUser() + add console warnings for getCurrentUser usage BREAKING CHANGE: getCurrentUser's /mobileinfo api endpoint is being deprecated by Roblox on August 27th (https://devforum.roblox.com/t/official-list-of-deprecated-web-endpoints/62889/66), setCookie will now have a new response type * misc: promisify secondary calls, remove github PR hyperlink, fix setOptions typing * lint: apply linting rules
1 parent 1aa2d50 commit 2be4343

File tree

8 files changed

+95
-24
lines changed

8 files changed

+95
-24
lines changed

lib/client/setCookie.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const options = require('../options.js')
2-
const getCurrentUser = require('../util/getCurrentUser.js').func
2+
const getAuthenticatedUser = require('../util/getAuthenticatedUser.js').func
33

44
exports.required = ['cookie']
55
exports.optional = ['validate']
@@ -11,7 +11,7 @@ exports.optional = ['validate']
1111
* @alias setCookie
1212
* @param {string} cookie - The cookie to sign in with.
1313
* @param {boolean=} [validate=true] - Whether to validate the cookie or not.
14-
* @returns {Promise<LoggedInUserData>}
14+
* @returns {Promise<AuthenticatedUserData>}
1515
* @example const noblox = require("noblox.js")
1616
* noblox.setCookie("cookie").then(function() {
1717
* //your code here
@@ -28,7 +28,7 @@ exports.func = async function (args) {
2828
return false
2929
}
3030
try {
31-
const res = await getCurrentUser({ jar: { session: args.cookie } })
31+
const res = await getAuthenticatedUser({ jar: { session: args.cookie } })
3232
options.jar.session = args.cookie
3333
return res
3434
} catch (error) {

lib/economy/getUserFunds.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Includes
2+
const http = require('../util/http.js').func
3+
4+
// Args
5+
exports.required = ['userId']
6+
exports.optional = ['jar']
7+
8+
// Docs
9+
/**
10+
* 🔓 Gets the amount of robux for the authenticated user.
11+
* @category User
12+
* @param {number} userId - Must match the userId of the authenticated user
13+
* @alias getUserFunds
14+
* @returns {Promise<number>}
15+
* @example const noblox = require("noblox.js")
16+
* // Login using your cookie
17+
* const currentUser = await noblox.setCookie(process.env.ROBLOXCOOKIE)
18+
* const robux = await noblox.getUserFunds(currentUser.id)
19+
*/
20+
21+
// Define
22+
function getUserFunds (userId, jar) {
23+
return http({
24+
url: `//economy.roblox.com/v1/users/${userId}/currency`,
25+
options: {
26+
jar,
27+
resolveWithFullResponse: true
28+
}
29+
})
30+
.then(({ statusCode, body }) => {
31+
const { robux, errors } = JSON.parse(body)
32+
if (statusCode === 200) {
33+
return robux
34+
} else if (statusCode === 400 || statusCode === 403) {
35+
throw new Error(`${errors[0].message} | userId: ${userId}`)
36+
} else {
37+
throw new Error(`An unknown error occurred with getUserFunds() | [${statusCode}] userId: ${userId}`)
38+
}
39+
})
40+
}
41+
42+
exports.func = function ({ userId, jar }) {
43+
return getUserFunds(userId, jar)
44+
}

lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ noblox.getGroupRevenueSummary = require('./economy/getGroupRevenueSummary.js')
7171
noblox.getGroupTransactions = require('./economy/getGroupTransactions.js')
7272
noblox.getResaleData = require('./economy/getResaleData.js')
7373
noblox.getResellers = require('./economy/getResellers.js')
74+
noblox.getUserFunds = require('./economy/getUserFunds.js')
7475
noblox.getUserTransactions = require('./economy/getUserTransactions.js')
7576
noblox.onGroupTransaction = require('./economy/onGroupTransaction.js')
7677
noblox.acceptFriendRequest = require('./friends/acceptFriendRequest.js')

lib/util/getCurrentUser.js

+28-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// Includes
2-
const http = require('./http.js').func
2+
const settings = require('../../settings.json')
3+
4+
const noblox = require('../index.js')
35

4-
// Args
56
exports.optional = ['option', 'jar']
67

78
// Docs
@@ -12,6 +13,7 @@ exports.optional = ['option', 'jar']
1213
* @param {string=} option - A specific option to return.
1314
* @returns {LoggedInUserData}
1415
* @example const noblox = require("noblox.js")
16+
* @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
1517
* // Login using your cookie.
1618
* const user = await noblox.getCurrentUser()
1719
**/
@@ -20,23 +22,35 @@ exports.optional = ['option', 'jar']
2022
exports.func = async function (args) {
2123
const jar = args.jar
2224
const option = args.option
23-
const httpOpt = {
24-
url: '//www.roblox.com/mobileapi/userinfo',
25-
options: {
26-
resolveWithFullResponse: true,
27-
method: 'GET',
28-
followRedirect: true,
29-
jar
30-
}
25+
if (settings.show_deprecation_warnings) {
26+
console.warn('[DEPRECATED]: getCurrentUser() is deprecated by Roblox; use getAuthenticatedUser(), getPremium(), getThumbnails(), or getUserFunds() instead!')
27+
console.warn(' > Opt out of these warnings using noblox.setOptions({ show_deprecation_warnings: false })')
3128
}
32-
const res = await http(httpOpt)
33-
if (res.statusCode !== 200) {
34-
throw new Error('You are not logged in.')
29+
30+
const currentUser = await noblox.getAuthenticatedUser(jar)
31+
const [premiumStatus, thumbnailResponse, robuxBalance] = await Promise.all(
32+
[
33+
noblox.getPremium(currentUser.id, jar),
34+
noblox.getPlayerThumbnail(currentUser.id, '352x352', 'png', false, 'Body', jar),
35+
noblox.getUserFunds(currentUser.id, jar)
36+
]
37+
)
38+
39+
const json = {
40+
UserID: currentUser.id,
41+
UserName: currentUser.name,
42+
RobuxBalance: robuxBalance,
43+
ThumbnailUrl: thumbnailResponse[0].imageUrl,
44+
IsAnyBuildersClubMember: false,
45+
IsPremium: premiumStatus,
46+
DEPRECATION_WARNING: '[DEPRECATED]: noblox.getCurrentUser() is deprecated; use getAuthenticatedUser(), getPremium(), getThumbnails(), or getUserFunds() instead!'
3547
}
36-
const json = JSON.parse(res.body)
48+
3749
if (!option) {
3850
return json
3951
}
52+
53+
// Support queried rgequests `getCurrentUser('UserID') -> only UserID`
4054
const searchKey = Object.keys(json).filter((key) => {
4155
return option.toLowerCase() === key.toLowerCase()
4256
})[0]

lib/util/setOptions.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const settings = require('../../settings.json')
66
* altering the settings.json file. Objects passed to this function should match the format of the settings.json file.
77
* Unknown keys, or malformed options will be rejected with an error.
88
* @category Utility
9-
* @param {NobloxOptions} newOptions - The new options to set, structured as per [settings.json](https://github.com/noblox/noblox.js/blob/master/settings.json)
9+
* @param {Partial<NobloxOptions>} newOptions - The new options to set, structured as per [settings.json](https://github.com/noblox/noblox.js/blob/master/settings.json)
1010
* @returns void
1111
* @see [settings.json](https://github.com/noblox/noblox.js/blob/master/settings.json) - default package settings
1212
* @example const noblox = require("noblox.js")

settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
{
2+
"show_deprecation_warnings": true,
3+
"show_deprecation_warnings_desc": "Prints console warnings for functions that are being polyfilled by newer methods due to upstream Roblox API changes",
4+
25
"session_only": true,
36
"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.",
47

typings/index.d.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ declare module "noblox.js" {
1717
* NobloxOptions for setOptions, based from settings.json
1818
*/
1919
interface NobloxOptions {
20+
/** Prints console warnings for functions that are being polyfilled by newer methods due to upstream Roblox API changes */
21+
show_deprecation_warnings: boolean;
22+
2023
/** 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) */
2124
session_only: boolean;
2225

@@ -996,9 +999,8 @@ declare module "noblox.js" {
996999
UserID: number,
9971000
UserName: string,
9981001
RobuxBalance: number,
999-
TicketsBalance: number,
10001002
ThumbnailUrl: string,
1001-
IsAnyBuildersClubMember: boolean,
1003+
IsAnyBuildersClubMember: false,
10021004
IsPremium: boolean
10031005
}
10041006

@@ -1670,7 +1672,7 @@ declare module "noblox.js" {
16701672
* 🔐 Allows the user to login with a provided cookie string, bypassing the username/password captcha issues.
16711673
* 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).
16721674
*/
1673-
function setCookie<B extends boolean = true>(cookie: string, shouldValidate?: B): B extends false ? boolean : Promise<LoggedInUserData>
1675+
function setCookie<B extends boolean = true>(cookie: string, shouldValidate?: B): B extends false ? boolean : Promise<AuthenticatedUserData>
16741676

16751677
/// DataStores
16761678

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

1775+
/**
1776+
* 🔐 Returns the current user's robux balance
1777+
*/
1778+
function getUserFunds(userId?: number, jar?: CookieJar): Promise<number>;
1779+
17731780
/// Friends
17741781

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

23022309
// Events
23032310

typings/jsDocs.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ type CookieJar = {
1414
* NobloxOptions for setOptions, based from settings.json
1515
*/
1616
type NobloxOptions = {
17+
/** Prints console warnings for functions that are being polyfilled by newer methods due to upstream Roblox API changes */
18+
show_deprecation_warnings: boolean;
19+
1720
/** 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) */
1821
session_only: boolean;
1922

@@ -1374,9 +1377,8 @@ type LoggedInUserData = {
13741377
UserID: number,
13751378
UserName: string,
13761379
RobuxBalance: number,
1377-
TicketsBalance: number,
13781380
ThumbnailUrl: string,
1379-
IsAnyBuildersClubMember: boolean,
1381+
IsAnyBuildersClubMember: false,
13801382
IsPremium: boolean
13811383
}
13821384

0 commit comments

Comments
 (0)