noblox.ts 4.10.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of noblox.ts might be problematic. Click here for more details.
- package/.eslintrc.js +21 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- package/.github/workflows/doc-publish.yml +33 -0
- package/.github/workflows/npmpublish.yml +70 -0
- package/.travis.yml +13 -0
- package/CODE_OF_CONDUCT.md +76 -0
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/examples/cleanPlayers.js +130 -0
- package/examples/cleanWall.js +110 -0
- package/examples/revertRanks.js +100 -0
- package/examples/savePlayers.js +119 -0
- package/examples/saveWall.js +96 -0
- package/img/moderatedThumbnails/moderatedThumbnail_100x100.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_110x110.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_140x140.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_150x150.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_150x200.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_180x180.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_250x250.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_30x30.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_352x352.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_420x420.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_48x48.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_50x50.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_60x60.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_720x720.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_75x75.png +0 -0
- package/img/noblox-js-small.png +0 -0
- package/img/noblox-js.png +0 -0
- package/img/thumbnailSizes.png +0 -0
- package/jsDocsConfig.json +55 -0
- package/lib/accountinformation/getUserSocialLinks.js +42 -0
- package/lib/accountsettings/block.js +58 -0
- package/lib/accountsettings/unblock.js +58 -0
- package/lib/asset/deleteFromInventory.js +69 -0
- package/lib/asset/getGamePassProductInfo.js +51 -0
- package/lib/asset/getProductInfo.js +56 -0
- package/lib/asset/uploadAnimation.js +103 -0
- package/lib/asset/uploadItem.js +83 -0
- package/lib/asset/uploadModel.js +90 -0
- package/lib/avatar/avatarRules.js +38 -0
- package/lib/avatar/currentlyWearing.js +32 -0
- package/lib/avatar/getAvatar.js +35 -0
- package/lib/avatar/getCurrentAvatar.js +37 -0
- package/lib/avatar/getRecentItems.js +37 -0
- package/lib/avatar/outfitDetails.js +32 -0
- package/lib/avatar/outfits.js +37 -0
- package/lib/avatar/redrawAvatar.js +48 -0
- package/lib/avatar/removeAssetId.js +55 -0
- package/lib/avatar/setAvatarBodyColors.js +60 -0
- package/lib/avatar/setAvatarScales.js +60 -0
- package/lib/avatar/setPlayerAvatarType.js +50 -0
- package/lib/avatar/setWearingAssets.js +50 -0
- package/lib/avatar/wearAssetId.js +55 -0
- package/lib/badges/getAwardedTimestamps.js +52 -0
- package/lib/badges/getBadgeInfo.js +43 -0
- package/lib/badges/getGameBadges.js +62 -0
- package/lib/badges/getPlayerBadges.js +28 -0
- package/lib/badges/updateBadgeInfo.js +80 -0
- package/lib/cache/add.js +14 -0
- package/lib/cache/addIf.js +26 -0
- package/lib/cache/clear.js +8 -0
- package/lib/cache/get.js +28 -0
- package/lib/cache/index.js +17 -0
- package/lib/cache/new.js +12 -0
- package/lib/cache/wrap.js +25 -0
- package/lib/chat/addUsersToConversation.js +61 -0
- package/lib/chat/chatSettings.js +33 -0
- package/lib/chat/getChatMessages.js +40 -0
- package/lib/chat/getConversations.js +43 -0
- package/lib/chat/getRolloutSettings.js +35 -0
- package/lib/chat/getUnreadConversationCount.js +33 -0
- package/lib/chat/getUnreadMessages.js +38 -0
- package/lib/chat/getUserConversations.js +37 -0
- package/lib/chat/markChatAsRead.js +52 -0
- package/lib/chat/markChatAsSeen.js +50 -0
- package/lib/chat/multiGetLatestMessages.js +37 -0
- package/lib/chat/onNewConversation.js +50 -0
- package/lib/chat/onNewMessage.js +53 -0
- package/lib/chat/onNewMessageBySelf.js +50 -0
- package/lib/chat/onUserOnline.js +50 -0
- package/lib/chat/onUserTyping.js +54 -0
- package/lib/chat/removeFromGroupConversation.js +62 -0
- package/lib/chat/renameGroupConversation.js +57 -0
- package/lib/chat/sendChatMessage.js +57 -0
- package/lib/chat/setChatUserTyping.js +61 -0
- package/lib/chat/start121Conversation.js +50 -0
- package/lib/chat/startCloudEditConversation.js +50 -0
- package/lib/chat/startGroupConversation.js +62 -0
- package/lib/client/onNotification.js +70 -0
- package/lib/client/setAPIKey.js +18 -0
- package/lib/client/setCookie.js +38 -0
- package/lib/datastores/deleteDatastoreEntry.js +66 -0
- package/lib/datastores/getDatastoreEntry.js +98 -0
- package/lib/datastores/getDatastoreEntryVersions.js +83 -0
- package/lib/datastores/getDatastoreKeys.js +73 -0
- package/lib/datastores/getDatastores.js +72 -0
- package/lib/datastores/incrementDatastoreEntry.js +93 -0
- package/lib/datastores/setDatastoreEntry.js +90 -0
- package/lib/develop/canManage.js +44 -0
- package/lib/develop/configureItem.js +142 -0
- package/lib/develop/updateUniverse.js +53 -0
- package/lib/develop/updateUniverseAccess.js +55 -0
- package/lib/economy/buy.js +99 -0
- package/lib/economy/getGroupFunds.js +43 -0
- package/lib/economy/getGroupRevenueSummary.js +48 -0
- package/lib/economy/getGroupTransactions.js +32 -0
- package/lib/economy/getResaleData.js +54 -0
- package/lib/economy/getResellers.js +35 -0
- package/lib/economy/getUserTransactions.js +34 -0
- package/lib/economy/onGroupTransaction.js +74 -0
- package/lib/friends/acceptFriendRequest.js +59 -0
- package/lib/friends/declineAllFriendRequests.js +57 -0
- package/lib/friends/declineFriendRequest.js +59 -0
- package/lib/friends/getFollowers.js +61 -0
- package/lib/friends/getFollowings.js +61 -0
- package/lib/friends/getFriendRequests.js +56 -0
- package/lib/friends/getFriends.js +53 -0
- package/lib/friends/onFriendRequest.js +58 -0
- package/lib/friends/removeFriend.js +58 -0
- package/lib/friends/sendFriendRequest.js +59 -0
- package/lib/friends/unfollow.js +58 -0
- package/lib/games/addDeveloperProduct.js +65 -0
- package/lib/games/checkDeveloperProductName.js +39 -0
- package/lib/games/configureGamePass.js +146 -0
- package/lib/games/getDeveloperProducts.js +51 -0
- package/lib/games/getGameInstances.js +31 -0
- package/lib/games/getGamePasses.js +39 -0
- package/lib/games/getGameRevenue.js +49 -0
- package/lib/games/getGameSocialLinks.js +45 -0
- package/lib/games/getGroupGames.js +30 -0
- package/lib/games/getPlaceInfo.js +48 -0
- package/lib/games/getUniverseInfo.js +51 -0
- package/lib/games/updateDeveloperProduct.js +69 -0
- package/lib/groups/changeRank.js +59 -0
- package/lib/groups/deleteWallPost.js +64 -0
- package/lib/groups/deleteWallPostsByUser.js +59 -0
- package/lib/groups/demote.js +25 -0
- package/lib/groups/exile.js +59 -0
- package/lib/groups/getAuditLog.js +67 -0
- package/lib/groups/getGroup.js +57 -0
- package/lib/groups/getGroupSocialLinks.js +44 -0
- package/lib/groups/getGroups.js +88 -0
- package/lib/groups/getJoinRequest.js +52 -0
- package/lib/groups/getJoinRequests.js +58 -0
- package/lib/groups/getPlayers.js +108 -0
- package/lib/groups/getRankInGroup.js +52 -0
- package/lib/groups/getRankNameInGroup.js +52 -0
- package/lib/groups/getRole.js +64 -0
- package/lib/groups/getRolePermissions.js +51 -0
- package/lib/groups/getRoles.js +56 -0
- package/lib/groups/getShout.js +49 -0
- package/lib/groups/getWall.js +59 -0
- package/lib/groups/groupPayout.js +103 -0
- package/lib/groups/handleJoinRequest.js +60 -0
- package/lib/groups/leaveGroup.js +60 -0
- package/lib/groups/onAuditLog.js +62 -0
- package/lib/groups/onJoinRequest.js +63 -0
- package/lib/groups/onJoinRequestHandle.js +105 -0
- package/lib/groups/onShout.js +57 -0
- package/lib/groups/onWallPost.js +58 -0
- package/lib/groups/promote.js +25 -0
- package/lib/groups/searchGroups.js +32 -0
- package/lib/groups/setGroupDescription.js +65 -0
- package/lib/groups/setGroupName.js +66 -0
- package/lib/groups/setRank.js +79 -0
- package/lib/groups/shout.js +65 -0
- package/lib/index.js +30 -0
- package/lib/internal/levelOneCopy.js +16 -0
- package/lib/internal/queue.js +61 -0
- package/lib/internal/timeout.js +30 -0
- package/lib/internal/wrap.js +78 -0
- package/lib/inventory/getCollectibles.js +31 -0
- package/lib/inventory/getInventory.js +32 -0
- package/lib/inventory/getInventoryById.js +31 -0
- package/lib/inventory/getOwnership.js +54 -0
- package/lib/inventory/getUAIDs.js +47 -0
- package/lib/itemconfiguration/getGroupAssets.js +32 -0
- package/lib/options.js +26 -0
- package/lib/party/onPartyDeleted.js +53 -0
- package/lib/party/onPartyInvite.js +53 -0
- package/lib/party/onPartyJoinedGame.js +53 -0
- package/lib/party/onPartyLeftGame.js +53 -0
- package/lib/party/onPartySelfJoined.js +53 -0
- package/lib/party/onPartySelfLeft.js +53 -0
- package/lib/party/onPartyUserJoined.js +53 -0
- package/lib/party/onPartyUserLeft.js +53 -0
- package/lib/premiumfeatures/getPremium.js +51 -0
- package/lib/presence/getPresences.js +63 -0
- package/lib/privatemessages/getMessages.js +60 -0
- package/lib/privatemessages/message.js +80 -0
- package/lib/privatemessages/onMessage.js +88 -0
- package/lib/thumbnails/getLogo.js +60 -0
- package/lib/thumbnails/getPlayerThumbnail.js +121 -0
- package/lib/thumbnails/getThumbnails.js +93 -0
- package/lib/trades/acceptTrade.js +58 -0
- package/lib/trades/canTradeWith.js +48 -0
- package/lib/trades/counterTrade.js +84 -0
- package/lib/trades/declineTrade.js +58 -0
- package/lib/trades/getTradeInfo.js +52 -0
- package/lib/trades/getTrades.js +37 -0
- package/lib/trades/sendTrade.js +82 -0
- package/lib/users/getBlurb.js +36 -0
- package/lib/users/getIdFromUsername.js +53 -0
- package/lib/users/getPlayerInfo.js +100 -0
- package/lib/users/getUsernameFromId.js +44 -0
- package/lib/users/onBlurbChange.js +46 -0
- package/lib/util/clearSession.js +32 -0
- package/lib/util/generalRequest.js +61 -0
- package/lib/util/getAction.js +45 -0
- package/lib/util/getCurrentUser.js +44 -0
- package/lib/util/getGeneralToken.js +52 -0
- package/lib/util/getHash.js +29 -0
- package/lib/util/getInputs.js +37 -0
- package/lib/util/getPageResults.js +89 -0
- package/lib/util/getSenderUserId.js +30 -0
- package/lib/util/getSession.js +38 -0
- package/lib/util/getVerification.js +60 -0
- package/lib/util/getVerificationInputs.js +31 -0
- package/lib/util/http.js +110 -0
- package/lib/util/jar.js +24 -0
- package/lib/util/refreshCookie.js +52 -0
- package/lib/util/relog.js +81 -0
- package/lib/util/setOptions.js +54 -0
- package/lib/util/shortPoll.js +102 -0
- package/lib/util/threaded.js +80 -0
- package/package.json +94 -0
- package/postinstall.js +1 -0
- package/settings.json +107 -0
- package/test/accountinformation.test.js +27 -0
- package/test/accountsettings.test.js +27 -0
- package/test/asset.test.js +81 -0
- package/test/assets/Great-White-Shark-Fin.rbxm +0 -0
- package/test/assets/KeyframeSequence.rbxm +0 -0
- package/test/avatar.test.js +164 -0
- package/test/badges.test.js +96 -0
- package/test/chat.test.js +104 -0
- package/test/datastore.test.js +105 -0
- package/test/develop.test.js +53 -0
- package/test/economy.test.js +137 -0
- package/test/friends.test.js +128 -0
- package/test/games.test.js +212 -0
- package/test/groups.test.js +311 -0
- package/test/inventory.test.js +98 -0
- package/test/itemconfiguration.test.js +24 -0
- package/test/premiumfeatures.test.js +17 -0
- package/test/presence.test.js +25 -0
- package/test/privatemessages.test.js +33 -0
- package/test/thumbnails.test.js +53 -0
- package/test/users.test.js +68 -0
- package/tutorials/Authentication.md +75 -0
- package/tutorials/Event Emitters.md +26 -0
- package/tutorials/Promises.md +86 -0
- package/tutorials/VPS Authentication.md +72 -0
- package/typings/index.d.ts +2525 -0
- package/typings/jsDocs.ts +1927 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const getGeneralToken = require('../util/getGeneralToken.js').func
|
4
|
+
const getCurrentUser = require('../util/getCurrentUser.js').func
|
5
|
+
|
6
|
+
// Args
|
7
|
+
exports.required = ['targetUserId', 'sendingOffer', 'receivingOffer']
|
8
|
+
exports.optional = ['jar']
|
9
|
+
|
10
|
+
// Docs
|
11
|
+
/**
|
12
|
+
* 🔐 Send a trade to another user.
|
13
|
+
* @category Trade
|
14
|
+
* @alias sendTrade
|
15
|
+
* @param {number} targetUserId - The user to send the trade to.
|
16
|
+
* @param {TradeOffer} sendingOffer - The offer to send to the other user.
|
17
|
+
* @param {TradeOffer} recievingOffer - The offer you are requesting from the other user.
|
18
|
+
* @returns {Promise<SendTradeResponse>}
|
19
|
+
* @example const noblox = require("noblox.js")
|
20
|
+
* noblox.sendTrade(80231025, { userAssetIds: [23289506393] }, { userAssetIds: [32924150919] })
|
21
|
+
**/
|
22
|
+
|
23
|
+
// Define
|
24
|
+
function sendTrade (targetUserId, sendingOffer, receivingOffer, jar, xcsrf, loggedInUser) {
|
25
|
+
return new Promise((resolve, reject) => {
|
26
|
+
if (!sendingOffer.userAssetIds || !receivingOffer.userAssetIds) {
|
27
|
+
reject(new Error('Both offers must includes userAssetIds.'))
|
28
|
+
}
|
29
|
+
|
30
|
+
if (!sendingOffer.robux) sendingOffer.robux = 0
|
31
|
+
if (!receivingOffer.robux) receivingOffer.robux = 0
|
32
|
+
|
33
|
+
http({
|
34
|
+
url: '//trades.roblox.com/v1/trades/send',
|
35
|
+
options: {
|
36
|
+
method: 'POST',
|
37
|
+
resolveWithFullResponse: true,
|
38
|
+
jar: jar,
|
39
|
+
headers: {
|
40
|
+
'X-CSRF-TOKEN': xcsrf,
|
41
|
+
'Content-Type': 'application/json'
|
42
|
+
},
|
43
|
+
body: JSON.stringify({
|
44
|
+
offers: [
|
45
|
+
{
|
46
|
+
userId: targetUserId,
|
47
|
+
...receivingOffer
|
48
|
+
},
|
49
|
+
{
|
50
|
+
userId: loggedInUser,
|
51
|
+
...sendingOffer
|
52
|
+
}
|
53
|
+
]
|
54
|
+
})
|
55
|
+
}
|
56
|
+
}).then((res) => {
|
57
|
+
if (res.statusCode === 200) {
|
58
|
+
resolve(JSON.parse(res.body))
|
59
|
+
} else {
|
60
|
+
const body = JSON.parse(res.body) || {}
|
61
|
+
|
62
|
+
if (body.errors && body.errors.length > 0) {
|
63
|
+
const errors = body.errors.map((e) => {
|
64
|
+
return e.message
|
65
|
+
})
|
66
|
+
reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}).catch(error => reject(error))
|
70
|
+
})
|
71
|
+
}
|
72
|
+
|
73
|
+
exports.func = function (args) {
|
74
|
+
const jar = args.jar
|
75
|
+
return Promise.all([
|
76
|
+
getGeneralToken({ jar: jar }),
|
77
|
+
getCurrentUser({ jar: jar, option: 'UserID' })
|
78
|
+
])
|
79
|
+
.then(function (resolvedPromises) {
|
80
|
+
return sendTrade(args.targetUserId, args.sendingOffer, args.receivingOffer, jar, resolvedPromises[0], resolvedPromises[1])
|
81
|
+
})
|
82
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['userId']
|
6
|
+
|
7
|
+
// Docs
|
8
|
+
/**
|
9
|
+
* ✅ Get a user's blurb - a user's description.
|
10
|
+
* @category User
|
11
|
+
* @deprecated Obsolete function, will be deleted in future version. Use getPlayerInfo instead.
|
12
|
+
* @alias getBlurb
|
13
|
+
* @param {number} userId - The id of the user's blurb that is being retrieved.
|
14
|
+
* @returns {Promise<string>}
|
15
|
+
* @example const noblox = require("noblox.js")
|
16
|
+
* let blurb = await noblox.getBlurb({ userId: 123456 })
|
17
|
+
**/
|
18
|
+
|
19
|
+
// Define
|
20
|
+
exports.func = function (args) {
|
21
|
+
return http({
|
22
|
+
url: `//users.roblox.com/v1/users/${args.userId}`,
|
23
|
+
options: {
|
24
|
+
resolveWithFullResponse: true,
|
25
|
+
followRedirect: false
|
26
|
+
}
|
27
|
+
})
|
28
|
+
.then(function (res) {
|
29
|
+
if (res.statusCode === 200) {
|
30
|
+
const parsedBody = JSON.parse(res.body)
|
31
|
+
return parsedBody.description
|
32
|
+
} else {
|
33
|
+
throw new Error('User does not exist')
|
34
|
+
}
|
35
|
+
})
|
36
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const cache = require('../cache')
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['username']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* ✅ Get a user's id from their username.
|
11
|
+
* @category User
|
12
|
+
* @alias getIdFromUsername
|
13
|
+
* @param {string | string[]} usernames - The username or usernames of the account(s) whose id(s) is being fetched.
|
14
|
+
* @returns {Promise<number> | Promise<number[]>}
|
15
|
+
* @example const noblox = require("noblox.js")
|
16
|
+
* let ids = await noblox.getIdFromUsername(["ROBLOX", "Qxest", "builderman"])
|
17
|
+
**/
|
18
|
+
|
19
|
+
// Define
|
20
|
+
function getIdFromUsername (usernames) {
|
21
|
+
usernames = Array.isArray(usernames) ? usernames : [usernames] // cast usernames to array if necessary
|
22
|
+
|
23
|
+
const httpOpt = {
|
24
|
+
url: 'https://users.roblox.com/v1/usernames/users',
|
25
|
+
options: {
|
26
|
+
method: 'POST',
|
27
|
+
json: {
|
28
|
+
usernames,
|
29
|
+
excludeBannedUsers: false
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
return http(httpOpt)
|
34
|
+
.then(function (body) {
|
35
|
+
const data = body.data
|
36
|
+
|
37
|
+
let results = usernames.map((username) => {
|
38
|
+
return data.find((result) => result.requestedUsername === username)
|
39
|
+
})
|
40
|
+
|
41
|
+
results = results.map((result) => result !== undefined ? result.id : null)
|
42
|
+
|
43
|
+
return results.length > 1 ? results : results[0]
|
44
|
+
})
|
45
|
+
}
|
46
|
+
|
47
|
+
exports.func = function (args) {
|
48
|
+
const usernames = Array.isArray(args.username) ? args.username : [args.username] // cast usernames to array if necessary
|
49
|
+
// Case does not affect the result and should not affect the cache
|
50
|
+
return cache.wrap('IDFromName', usernames.map(username => username.toLowerCase()), function () {
|
51
|
+
return getIdFromUsername(usernames)
|
52
|
+
})
|
53
|
+
}
|
@@ -0,0 +1,100 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const getPageResults = require('../util/getPageResults.js').func
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['userId']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* ✅ Get a user's information.
|
11
|
+
* @category User
|
12
|
+
* @alias getPlayerInfo
|
13
|
+
* @param { number } userId - The id of the user.
|
14
|
+
* @returns {Promise<PlayerInfo>}
|
15
|
+
* @example const noblox = require("noblox.js")
|
16
|
+
* let information = await noblox.getPlayerInfo({userId: 123456})
|
17
|
+
**/
|
18
|
+
|
19
|
+
// Define
|
20
|
+
function getPlayerInfo (userId) {
|
21
|
+
return new Promise((resolve, reject) => {
|
22
|
+
const requests = [
|
23
|
+
constructRequest(`//users.roblox.com/v1/users/${userId}`),
|
24
|
+
constructRequest(`//friends.roblox.com/v1/users/${userId}/friends/count`),
|
25
|
+
constructRequest(`//friends.roblox.com/v1/users/${userId}/followings/count`),
|
26
|
+
constructRequest(`//friends.roblox.com/v1/users/${userId}/followers/count`),
|
27
|
+
getPageResults({ url: `//users.roblox.com/v1/users/${userId}/username-history`, query: {}, limit: 1000 })
|
28
|
+
].map(promise => promise.then(
|
29
|
+
val => ({ status: 'fulfilled', value: val }),
|
30
|
+
rej => ({ status: 'rejected', reason: rej })
|
31
|
+
))
|
32
|
+
|
33
|
+
Promise.all(requests).then((promiseResponses) => {
|
34
|
+
const responses = promiseResponses.map(response => response.value)
|
35
|
+
const usersResponse = responses[0]
|
36
|
+
const userBody = usersResponse ? usersResponse.body : {}
|
37
|
+
const failedResponse = promiseResponses.find(presponse => presponse.status === 'rejected') || responses.find(response => !response || (!(response instanceof Array) && (response.statusCode !== 200 || !response.body)))
|
38
|
+
|
39
|
+
if (userBody.isBanned) {
|
40
|
+
const joinDate = new Date(userBody.created)
|
41
|
+
const blurb = userBody.description
|
42
|
+
const isBanned = userBody.isBanned
|
43
|
+
const username = userBody.name
|
44
|
+
const displayName = userBody.displayName
|
45
|
+
|
46
|
+
resolve({
|
47
|
+
username: username,
|
48
|
+
joinDate: joinDate,
|
49
|
+
blurb: blurb,
|
50
|
+
isBanned: isBanned,
|
51
|
+
displayName: displayName
|
52
|
+
})
|
53
|
+
} else if (failedResponse) {
|
54
|
+
reject(new Error('User does not exist.'))
|
55
|
+
} else {
|
56
|
+
const responseBodies = responses.map(res => res.body)
|
57
|
+
const oldNames = responses[4].map(nameObject => nameObject.name) || []
|
58
|
+
const friendCount = responseBodies[1].count
|
59
|
+
const followerCount = responseBodies[3].count
|
60
|
+
const followingCount = responseBodies[2].count
|
61
|
+
const joinDate = new Date(userBody.created)
|
62
|
+
const blurb = userBody.description
|
63
|
+
const isBanned = userBody.isBanned
|
64
|
+
const username = userBody.name
|
65
|
+
const displayName = userBody.displayName
|
66
|
+
|
67
|
+
const currentTime = new Date()
|
68
|
+
const age = Math.round(Math.abs((joinDate.getTime() - currentTime.getTime()) / (24 * 60 * 60 * 1000)))
|
69
|
+
|
70
|
+
resolve({
|
71
|
+
username,
|
72
|
+
displayName,
|
73
|
+
blurb,
|
74
|
+
joinDate,
|
75
|
+
age,
|
76
|
+
friendCount,
|
77
|
+
followerCount,
|
78
|
+
followingCount,
|
79
|
+
oldNames,
|
80
|
+
isBanned
|
81
|
+
})
|
82
|
+
}
|
83
|
+
})
|
84
|
+
})
|
85
|
+
}
|
86
|
+
|
87
|
+
function constructRequest (url) {
|
88
|
+
return http({
|
89
|
+
url: url,
|
90
|
+
options: {
|
91
|
+
resolveWithFullResponse: true,
|
92
|
+
followRedirect: false,
|
93
|
+
json: true
|
94
|
+
}
|
95
|
+
})
|
96
|
+
}
|
97
|
+
|
98
|
+
exports.func = (args) => {
|
99
|
+
return getPlayerInfo(args.userId)
|
100
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const cache = require('../cache')
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['id']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* ✅ Get a user's username from their user id.
|
11
|
+
* @category User
|
12
|
+
* @alias getUsernameFromId
|
13
|
+
* @param {number} id - The id of the user.
|
14
|
+
* @returns {Promise<string>}
|
15
|
+
* @example const noblox = require("noblox.js")
|
16
|
+
* let username = await noblox.getUsernameFromId(123456)
|
17
|
+
**/
|
18
|
+
|
19
|
+
// Define
|
20
|
+
function getUsernameFromId (id) {
|
21
|
+
const httpOpt = {
|
22
|
+
url: `//users.roblox.com/v1/users/${id}`,
|
23
|
+
options: {
|
24
|
+
resolveWithFullResponse: true,
|
25
|
+
method: 'GET'
|
26
|
+
}
|
27
|
+
}
|
28
|
+
return http(httpOpt)
|
29
|
+
.then(function (res) {
|
30
|
+
if (res.statusCode === 200) {
|
31
|
+
const json = JSON.parse(res.body)
|
32
|
+
return json.name
|
33
|
+
} else {
|
34
|
+
throw new Error('User does not exist')
|
35
|
+
}
|
36
|
+
})
|
37
|
+
}
|
38
|
+
|
39
|
+
exports.func = function (args) {
|
40
|
+
const id = args.id
|
41
|
+
return cache.wrap('NameFromID', id, function () {
|
42
|
+
return getUsernameFromId(id)
|
43
|
+
})
|
44
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
// Includes
|
2
|
+
const shortPoll = require('../util/shortPoll.js').func
|
3
|
+
const getBlurb = require('./getBlurb.js').func
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['userId']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* ✅ An event for when a user's blurb changes.
|
11
|
+
* @category User
|
12
|
+
* @alias onBlurbChange
|
13
|
+
* @param {number} userId - The id of the user.
|
14
|
+
* @returns An EventEmitter that emits when a user's blurb changes.
|
15
|
+
* @example const noblox = require("noblox.js")
|
16
|
+
* const blurbEvent = noblox.onBlurbChange(1)
|
17
|
+
* blurbEvent.on("data", function(data) {
|
18
|
+
* console.log("User's blurb changed!", data)
|
19
|
+
* })
|
20
|
+
* blurbEvent.on("error", function(err) {
|
21
|
+
* console.error("Something went wrong: ", err)
|
22
|
+
* // Handle error as needed
|
23
|
+
* })
|
24
|
+
**/
|
25
|
+
|
26
|
+
// Define
|
27
|
+
exports.func = function (args) {
|
28
|
+
return shortPoll({
|
29
|
+
getLatest: function (latest) {
|
30
|
+
return getBlurb({ userId: args.userId })
|
31
|
+
.then(function (blurb) {
|
32
|
+
const given = []
|
33
|
+
if (blurb !== latest) {
|
34
|
+
latest = blurb
|
35
|
+
given.push(blurb)
|
36
|
+
}
|
37
|
+
|
38
|
+
return {
|
39
|
+
latest: latest,
|
40
|
+
data: given
|
41
|
+
}
|
42
|
+
})
|
43
|
+
},
|
44
|
+
delay: 'onBlurbChange'
|
45
|
+
})
|
46
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
// Includes
|
2
|
+
const settings = require('../../settings.json')
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['jar']
|
6
|
+
|
7
|
+
// Docs
|
8
|
+
/**
|
9
|
+
* 🔐 Remove .ROBLOSECURITY cookie from jar.
|
10
|
+
* @category Utility
|
11
|
+
* @alias clearSession
|
12
|
+
* @param {CookieJar} jar - The CookieJar containing the .ROBLOSECURITY cookie.
|
13
|
+
* @returns {Promise<string>}
|
14
|
+
* @example const noblox = require("noblox.js")
|
15
|
+
* noblox.clearSession()
|
16
|
+
**/
|
17
|
+
|
18
|
+
// Define
|
19
|
+
exports.func = function (args) {
|
20
|
+
const jar = args.jar
|
21
|
+
if (settings.session_only) {
|
22
|
+
jar.session = ''
|
23
|
+
} else {
|
24
|
+
const cookies = jar._jar.store.idx['roblox.com']
|
25
|
+
if (cookies) {
|
26
|
+
const cookie = cookies['/']
|
27
|
+
if (cookie && cookie['.ROBLOSECURITY']) {
|
28
|
+
delete cookies['/']['.ROBLOSECURITY']
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('./http.js').func
|
3
|
+
const getVerification = require('./getVerification.js').func
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['url', 'events']
|
7
|
+
exports.optional = ['http', 'ignoreCache', 'getBody', 'jar']
|
8
|
+
|
9
|
+
// Docs
|
10
|
+
/**
|
11
|
+
* 🔐 Get the verification inputs and send a request.
|
12
|
+
* @category Utility
|
13
|
+
* @alias generalRequest
|
14
|
+
* @param {string} url - The url to post to.
|
15
|
+
* @param {object} events - Form data to send with the request.
|
16
|
+
* @param {boolean=} [ignoreCache=false] - Whether to ignore the cache or not.
|
17
|
+
* @param {boolean=} [getBody=false] - Whether to return the original body before the POST request.
|
18
|
+
* @param {CookieJar=} jar - The CookieJar containing the .ROBLOSECURITY cookie.
|
19
|
+
* @returns {Promise<Object>}
|
20
|
+
* @example const noblox = require("noblox.js")
|
21
|
+
* // Login using your cookie.
|
22
|
+
* noblox.generalRequest("//www.roblox.com/Groups/Group.aspx?gid=1", { __EVENTTARGET: 'JoinGroupDiv', __EVENTARGUMENT: 'Click' })
|
23
|
+
**/
|
24
|
+
|
25
|
+
// Define
|
26
|
+
function general (jar, url, inputs, events, customOpt, body) {
|
27
|
+
for (const input in events) {
|
28
|
+
inputs[input] = events[input]
|
29
|
+
}
|
30
|
+
const httpOpt = {
|
31
|
+
url: url,
|
32
|
+
options: {
|
33
|
+
resolveWithFullResponse: true,
|
34
|
+
method: 'POST',
|
35
|
+
form: inputs,
|
36
|
+
jar: jar
|
37
|
+
}
|
38
|
+
}
|
39
|
+
if (customOpt) {
|
40
|
+
if (customOpt.url) {
|
41
|
+
delete customOpt.url
|
42
|
+
}
|
43
|
+
Object.assign(httpOpt.options, customOpt)
|
44
|
+
}
|
45
|
+
return http(httpOpt).then(function (res) {
|
46
|
+
return {
|
47
|
+
res: res,
|
48
|
+
body: body
|
49
|
+
}
|
50
|
+
})
|
51
|
+
}
|
52
|
+
|
53
|
+
exports.func = function (args) {
|
54
|
+
const jar = args.jar
|
55
|
+
const url = args.url
|
56
|
+
const custom = args.http
|
57
|
+
return getVerification({ url: custom ? (custom.url || url) : url, jar: jar, ignoreCache: args.ignoreCache, getBody: args.getBody })
|
58
|
+
.then(function (response) {
|
59
|
+
return general(jar, url, response.inputs, args.events, args.http, response.body)
|
60
|
+
})
|
61
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
// Args
|
2
|
+
exports.required = ['row']
|
3
|
+
|
4
|
+
// Define
|
5
|
+
const regex = [
|
6
|
+
/rank from (.+) to (.+)\.$/,
|
7
|
+
/deleted post "(.+)" by user .+\.$/,
|
8
|
+
/changed the group status to: (.*)$/
|
9
|
+
]
|
10
|
+
// This is no longer used within the library and is maintained only for the purposes of backwards compatibility
|
11
|
+
// TODO: Remove this in next Semver major version
|
12
|
+
|
13
|
+
// Docs
|
14
|
+
/**
|
15
|
+
* ✅ Get the action row for the audit log text. Supported: change rank, delete post, change group status.
|
16
|
+
* @category Utility
|
17
|
+
* @alias getAction
|
18
|
+
* @deprecated
|
19
|
+
* @param {string} row - The audit log action row.
|
20
|
+
* @returns {AuditItem}
|
21
|
+
**/
|
22
|
+
|
23
|
+
exports.func = function (args) {
|
24
|
+
const row = args.row
|
25
|
+
const text = row.text()
|
26
|
+
const params = []
|
27
|
+
for (let i = 0; i < regex.length; i++) {
|
28
|
+
const match = text.match(regex[i])
|
29
|
+
if (match) {
|
30
|
+
for (let j = 1; j < match.length; j++) {
|
31
|
+
params.push(match[j])
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
const target = row.find('a').last().attr('href')
|
36
|
+
let found = target.match(/\?ID=(\d+)$/)
|
37
|
+
if (!found) {
|
38
|
+
found = target.match(/^games\/(\d+)\//)
|
39
|
+
}
|
40
|
+
found = found && parseInt(found[1], 10)
|
41
|
+
return {
|
42
|
+
target: found,
|
43
|
+
params: params
|
44
|
+
}
|
45
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('./http.js').func
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.optional = ['option', 'jar']
|
6
|
+
|
7
|
+
// Docs
|
8
|
+
/**
|
9
|
+
* 🔐 Get the current logged in user.
|
10
|
+
* @category Utility
|
11
|
+
* @alias getCurrentUser
|
12
|
+
* @param {string=} option - A specific option to return.
|
13
|
+
* @returns {LoggedInUserData}
|
14
|
+
* @example const noblox = require("noblox.js")
|
15
|
+
* // Login using your cookie.
|
16
|
+
* const user = await noblox.getCurrentUser()
|
17
|
+
**/
|
18
|
+
|
19
|
+
// Define
|
20
|
+
exports.func = async function (args) {
|
21
|
+
const jar = args.jar
|
22
|
+
const option = args.option
|
23
|
+
const httpOpt = {
|
24
|
+
url: '//www.roblox.com/mobileapi/userinfo',
|
25
|
+
options: {
|
26
|
+
resolveWithFullResponse: true,
|
27
|
+
method: 'GET',
|
28
|
+
followRedirect: false,
|
29
|
+
jar: jar
|
30
|
+
}
|
31
|
+
}
|
32
|
+
const res = await http(httpOpt)
|
33
|
+
if (res.statusCode !== 200) {
|
34
|
+
throw new Error('You are not logged in.')
|
35
|
+
}
|
36
|
+
const json = JSON.parse(res.body)
|
37
|
+
if (!option) {
|
38
|
+
return json
|
39
|
+
}
|
40
|
+
const searchKey = Object.keys(json).filter((key) => {
|
41
|
+
return option.toLowerCase() === key.toLowerCase()
|
42
|
+
})[0]
|
43
|
+
return json[searchKey]
|
44
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
// Includes
|
2
|
+
const getHash = require('./getHash.js').func
|
3
|
+
const http = require('./http.js').func
|
4
|
+
const cache = require('../cache')
|
5
|
+
const options = require('../options.js')
|
6
|
+
|
7
|
+
// Args
|
8
|
+
exports.optional = ['jar']
|
9
|
+
|
10
|
+
// Docs
|
11
|
+
/**
|
12
|
+
* 🔐 Generate an X-CSRF-Token.
|
13
|
+
* @category Utility
|
14
|
+
* @alias getGeneralToken
|
15
|
+
* @param {CookieJar=} jar - The jar containing the .ROBLOSECURITY token.
|
16
|
+
* @returns {Promise<string>}
|
17
|
+
* @example const noblox = require("noblox.js")
|
18
|
+
* // Login using your cookie.
|
19
|
+
* const XCSRF = await noblox.getGeneralToken()
|
20
|
+
**/
|
21
|
+
|
22
|
+
// Define
|
23
|
+
function getGeneralToken (jar) {
|
24
|
+
if (!jar && !options.jar.session) {
|
25
|
+
throw new Error('Cannot get CSRF: You are not logged in.')
|
26
|
+
}
|
27
|
+
const httpOpt = {
|
28
|
+
// This will never actually sign you out because an X-CSRF-TOKEN isn't provided, only received
|
29
|
+
url: '//auth.roblox.com/v2/logout', // REQUIRES https. Thanks for letting me know, ROBLOX...
|
30
|
+
options: {
|
31
|
+
resolveWithFullResponse: true,
|
32
|
+
method: 'POST',
|
33
|
+
jar: jar
|
34
|
+
}
|
35
|
+
}
|
36
|
+
return http(httpOpt)
|
37
|
+
.then(function (res) {
|
38
|
+
const xcsrf = res.headers['x-csrf-token']
|
39
|
+
if (xcsrf) {
|
40
|
+
return xcsrf
|
41
|
+
} else {
|
42
|
+
throw new Error('Did not receive X-CSRF-TOKEN')
|
43
|
+
}
|
44
|
+
})
|
45
|
+
}
|
46
|
+
|
47
|
+
exports.func = function (args) {
|
48
|
+
const jar = args.jar
|
49
|
+
return cache.wrap('XCSRF', getHash({ jar: jar }), function () {
|
50
|
+
return getGeneralToken(jar)
|
51
|
+
})
|
52
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
// Dependencies
|
2
|
+
const crypto = require('crypto')
|
3
|
+
|
4
|
+
// Includes
|
5
|
+
const getSession = require('./getSession.js').func
|
6
|
+
|
7
|
+
// Args
|
8
|
+
exports.optional = ['jar']
|
9
|
+
|
10
|
+
// Docs
|
11
|
+
/**
|
12
|
+
* 🔐 Get a unique hash for the given jar. Used to cache items that depend on session.
|
13
|
+
* @category Utility
|
14
|
+
* @alias getHash
|
15
|
+
* @param {CookieJar} jar - The audit log action row.
|
16
|
+
* @returns {string}
|
17
|
+
* @example const noblox = require("noblox.js")
|
18
|
+
* // Login using your cookie.
|
19
|
+
* const hash = noblox.getHash()
|
20
|
+
**/
|
21
|
+
|
22
|
+
// Define
|
23
|
+
exports.func = function ({ jar }) {
|
24
|
+
if (typeof jar === 'string') {
|
25
|
+
jar = { session: jar }
|
26
|
+
}
|
27
|
+
const session = getSession({ jar })
|
28
|
+
return crypto.createHash('md5').update(session).digest('hex')
|
29
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
// Dependencies
|
2
|
+
const parser = require('cheerio')
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['html']
|
6
|
+
exports.optional = ['find']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* ✅ Get verification inputs on a page.
|
11
|
+
* @category Utility
|
12
|
+
* @alias getInputs
|
13
|
+
* @param {string} html - The html to get the inputs from.
|
14
|
+
* @param {Array<string>=} find - The inputs to find on the page
|
15
|
+
* @returns {Inputs}
|
16
|
+
* @example const noblox = require("noblox.js")
|
17
|
+
* const inputs = noblox.getInputs("htmlhere")
|
18
|
+
**/
|
19
|
+
|
20
|
+
// Define
|
21
|
+
exports.func = function (args) {
|
22
|
+
const $ = parser.load(args.html)
|
23
|
+
const inputs = {}
|
24
|
+
const find = args.find
|
25
|
+
if (find) {
|
26
|
+
for (let i = 0; i < find.length; i++) {
|
27
|
+
const get = find[i]
|
28
|
+
inputs[get] = $('input[name=' + get + ']').val()
|
29
|
+
}
|
30
|
+
} else {
|
31
|
+
$('input[name]').each(function (index, element) {
|
32
|
+
const here = $(this)
|
33
|
+
inputs[here.attr('name')] = here.val()
|
34
|
+
})
|
35
|
+
}
|
36
|
+
return inputs
|
37
|
+
}
|