noblox.js-async 0.0.1-security → 4.6.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of noblox.js-async might be problematic. Click here for more details.

Files changed (259) hide show
  1. package/.eslintrc.js +21 -0
  2. package/.github/FUNDING.yml +3 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  5. package/.github/workflows/doc-publish.yml +33 -0
  6. package/.github/workflows/npmpublish.yml +70 -0
  7. package/.travis.yml +13 -0
  8. package/CODE_OF_CONDUCT.md +76 -0
  9. package/LICENSE +21 -0
  10. package/README.md +166 -3
  11. package/examples/cleanPlayers.js +130 -0
  12. package/examples/cleanWall.js +110 -0
  13. package/examples/revertRanks.js +100 -0
  14. package/examples/savePlayers.js +119 -0
  15. package/examples/saveWall.js +96 -0
  16. package/img/moderatedThumbnails/moderatedThumbnail_100x100.png +0 -0
  17. package/img/moderatedThumbnails/moderatedThumbnail_110x110.png +0 -0
  18. package/img/moderatedThumbnails/moderatedThumbnail_140x140.png +0 -0
  19. package/img/moderatedThumbnails/moderatedThumbnail_150x150.png +0 -0
  20. package/img/moderatedThumbnails/moderatedThumbnail_150x200.png +0 -0
  21. package/img/moderatedThumbnails/moderatedThumbnail_180x180.png +0 -0
  22. package/img/moderatedThumbnails/moderatedThumbnail_250x250.png +0 -0
  23. package/img/moderatedThumbnails/moderatedThumbnail_30x30.png +0 -0
  24. package/img/moderatedThumbnails/moderatedThumbnail_352x352.png +0 -0
  25. package/img/moderatedThumbnails/moderatedThumbnail_420x420.png +0 -0
  26. package/img/moderatedThumbnails/moderatedThumbnail_48x48.png +0 -0
  27. package/img/moderatedThumbnails/moderatedThumbnail_50x50.png +0 -0
  28. package/img/moderatedThumbnails/moderatedThumbnail_60x60.png +0 -0
  29. package/img/moderatedThumbnails/moderatedThumbnail_720x720.png +0 -0
  30. package/img/moderatedThumbnails/moderatedThumbnail_75x75.png +0 -0
  31. package/img/noblox-js-small.png +0 -0
  32. package/img/noblox-js.png +0 -0
  33. package/img/thumbnailSizes.png +0 -0
  34. package/jsDocsConfig.json +55 -0
  35. package/lib/accountinformation/getUserSocialLinks.js +42 -0
  36. package/lib/accountsettings/block.js +58 -0
  37. package/lib/accountsettings/unblock.js +58 -0
  38. package/lib/asset/deleteFromInventory.js +69 -0
  39. package/lib/asset/getGamePassProductInfo.js +51 -0
  40. package/lib/asset/getProductInfo.js +56 -0
  41. package/lib/asset/uploadAnimation.js +103 -0
  42. package/lib/asset/uploadItem.js +83 -0
  43. package/lib/asset/uploadModel.js +90 -0
  44. package/lib/avatar/avatarRules.js +38 -0
  45. package/lib/avatar/currentlyWearing.js +32 -0
  46. package/lib/avatar/getAvatar.js +35 -0
  47. package/lib/avatar/getCurrentAvatar.js +37 -0
  48. package/lib/avatar/getRecentItems.js +37 -0
  49. package/lib/avatar/outfitDetails.js +32 -0
  50. package/lib/avatar/outfits.js +37 -0
  51. package/lib/avatar/redrawAvatar.js +48 -0
  52. package/lib/avatar/removeAssetId.js +55 -0
  53. package/lib/avatar/setAvatarBodyColors.js +60 -0
  54. package/lib/avatar/setAvatarScales.js +60 -0
  55. package/lib/avatar/setPlayerAvatarType.js +50 -0
  56. package/lib/avatar/setWearingAssets.js +50 -0
  57. package/lib/avatar/wearAssetId.js +55 -0
  58. package/lib/badges/getAwardedTimestamps.js +52 -0
  59. package/lib/badges/getBadgeInfo.js +43 -0
  60. package/lib/badges/getGameBadges.js +62 -0
  61. package/lib/badges/getPlayerBadges.js +28 -0
  62. package/lib/badges/updateBadgeInfo.js +80 -0
  63. package/lib/cache/add.js +14 -0
  64. package/lib/cache/addIf.js +26 -0
  65. package/lib/cache/clear.js +8 -0
  66. package/lib/cache/get.js +28 -0
  67. package/lib/cache/index.js +17 -0
  68. package/lib/cache/new.js +12 -0
  69. package/lib/cache/wrap.js +25 -0
  70. package/lib/chat/addUsersToConversation.js +61 -0
  71. package/lib/chat/chatSettings.js +33 -0
  72. package/lib/chat/getChatMessages.js +40 -0
  73. package/lib/chat/getConversations.js +43 -0
  74. package/lib/chat/getRolloutSettings.js +35 -0
  75. package/lib/chat/getUnreadConversationCount.js +33 -0
  76. package/lib/chat/getUnreadMessages.js +38 -0
  77. package/lib/chat/getUserConversations.js +37 -0
  78. package/lib/chat/markChatAsRead.js +52 -0
  79. package/lib/chat/markChatAsSeen.js +50 -0
  80. package/lib/chat/multiGetLatestMessages.js +37 -0
  81. package/lib/chat/onNewConversation.js +50 -0
  82. package/lib/chat/onNewMessage.js +53 -0
  83. package/lib/chat/onNewMessageBySelf.js +50 -0
  84. package/lib/chat/onUserOnline.js +50 -0
  85. package/lib/chat/onUserTyping.js +54 -0
  86. package/lib/chat/removeFromGroupConversation.js +62 -0
  87. package/lib/chat/renameGroupConversation.js +57 -0
  88. package/lib/chat/sendChatMessage.js +57 -0
  89. package/lib/chat/setChatUserTyping.js +61 -0
  90. package/lib/chat/start121Conversation.js +50 -0
  91. package/lib/chat/startCloudEditConversation.js +50 -0
  92. package/lib/chat/startGroupConversation.js +62 -0
  93. package/lib/client/onNotification.js +70 -0
  94. package/lib/client/setAPIKey.js +18 -0
  95. package/lib/client/setCookie.js +38 -0
  96. package/lib/datastores/deleteDatastoreEntry.js +66 -0
  97. package/lib/datastores/getDatastoreEntry.js +98 -0
  98. package/lib/datastores/getDatastoreEntryVersions.js +83 -0
  99. package/lib/datastores/getDatastoreKeys.js +73 -0
  100. package/lib/datastores/getDatastores.js +72 -0
  101. package/lib/datastores/incrementDatastoreEntry.js +93 -0
  102. package/lib/datastores/setDatastoreEntry.js +90 -0
  103. package/lib/develop/canManage.js +44 -0
  104. package/lib/develop/configureItem.js +142 -0
  105. package/lib/develop/updateUniverse.js +53 -0
  106. package/lib/develop/updateUniverseAccess.js +55 -0
  107. package/lib/economy/buy.js +99 -0
  108. package/lib/economy/getGroupFunds.js +43 -0
  109. package/lib/economy/getGroupRevenueSummary.js +48 -0
  110. package/lib/economy/getGroupTransactions.js +32 -0
  111. package/lib/economy/getResaleData.js +54 -0
  112. package/lib/economy/getResellers.js +35 -0
  113. package/lib/economy/getUserTransactions.js +34 -0
  114. package/lib/economy/onGroupTransaction.js +74 -0
  115. package/lib/friends/acceptFriendRequest.js +59 -0
  116. package/lib/friends/declineAllFriendRequests.js +57 -0
  117. package/lib/friends/declineFriendRequest.js +59 -0
  118. package/lib/friends/getFollowers.js +61 -0
  119. package/lib/friends/getFollowings.js +61 -0
  120. package/lib/friends/getFriendRequests.js +56 -0
  121. package/lib/friends/getFriends.js +53 -0
  122. package/lib/friends/onFriendRequest.js +58 -0
  123. package/lib/friends/removeFriend.js +58 -0
  124. package/lib/friends/sendFriendRequest.js +59 -0
  125. package/lib/friends/unfollow.js +58 -0
  126. package/lib/games/addDeveloperProduct.js +65 -0
  127. package/lib/games/checkDeveloperProductName.js +39 -0
  128. package/lib/games/configureGamePass.js +146 -0
  129. package/lib/games/getDeveloperProducts.js +51 -0
  130. package/lib/games/getGameInstances.js +31 -0
  131. package/lib/games/getGamePasses.js +39 -0
  132. package/lib/games/getGameRevenue.js +49 -0
  133. package/lib/games/getGameSocialLinks.js +45 -0
  134. package/lib/games/getGroupGames.js +30 -0
  135. package/lib/games/getPlaceInfo.js +48 -0
  136. package/lib/games/getUniverseInfo.js +51 -0
  137. package/lib/games/updateDeveloperProduct.js +69 -0
  138. package/lib/groups/changeRank.js +59 -0
  139. package/lib/groups/deleteWallPost.js +64 -0
  140. package/lib/groups/deleteWallPostsByUser.js +59 -0
  141. package/lib/groups/demote.js +25 -0
  142. package/lib/groups/exile.js +59 -0
  143. package/lib/groups/getAuditLog.js +67 -0
  144. package/lib/groups/getGroup.js +57 -0
  145. package/lib/groups/getGroupSocialLinks.js +44 -0
  146. package/lib/groups/getGroups.js +88 -0
  147. package/lib/groups/getJoinRequest.js +52 -0
  148. package/lib/groups/getJoinRequests.js +58 -0
  149. package/lib/groups/getPlayers.js +108 -0
  150. package/lib/groups/getRankInGroup.js +52 -0
  151. package/lib/groups/getRankNameInGroup.js +52 -0
  152. package/lib/groups/getRole.js +64 -0
  153. package/lib/groups/getRolePermissions.js +51 -0
  154. package/lib/groups/getRoles.js +56 -0
  155. package/lib/groups/getShout.js +49 -0
  156. package/lib/groups/getWall.js +59 -0
  157. package/lib/groups/groupPayout.js +103 -0
  158. package/lib/groups/handleJoinRequest.js +60 -0
  159. package/lib/groups/leaveGroup.js +60 -0
  160. package/lib/groups/onAuditLog.js +62 -0
  161. package/lib/groups/onJoinRequest.js +63 -0
  162. package/lib/groups/onJoinRequestHandle.js +105 -0
  163. package/lib/groups/onShout.js +57 -0
  164. package/lib/groups/onWallPost.js +58 -0
  165. package/lib/groups/promote.js +25 -0
  166. package/lib/groups/searchGroups.js +32 -0
  167. package/lib/groups/setGroupDescription.js +65 -0
  168. package/lib/groups/setGroupName.js +66 -0
  169. package/lib/groups/setRank.js +79 -0
  170. package/lib/groups/shout.js +65 -0
  171. package/lib/index.js +30 -0
  172. package/lib/internal/levelOneCopy.js +16 -0
  173. package/lib/internal/queue.js +61 -0
  174. package/lib/internal/timeout.js +30 -0
  175. package/lib/internal/wrap.js +78 -0
  176. package/lib/inventory/getCollectibles.js +31 -0
  177. package/lib/inventory/getInventory.js +32 -0
  178. package/lib/inventory/getInventoryById.js +31 -0
  179. package/lib/inventory/getOwnership.js +54 -0
  180. package/lib/inventory/getUAIDs.js +47 -0
  181. package/lib/itemconfiguration/getGroupAssets.js +32 -0
  182. package/lib/options.js +26 -0
  183. package/lib/party/onPartyDeleted.js +53 -0
  184. package/lib/party/onPartyInvite.js +53 -0
  185. package/lib/party/onPartyJoinedGame.js +53 -0
  186. package/lib/party/onPartyLeftGame.js +53 -0
  187. package/lib/party/onPartySelfJoined.js +53 -0
  188. package/lib/party/onPartySelfLeft.js +53 -0
  189. package/lib/party/onPartyUserJoined.js +53 -0
  190. package/lib/party/onPartyUserLeft.js +53 -0
  191. package/lib/premiumfeatures/getPremium.js +51 -0
  192. package/lib/presence/getPresences.js +63 -0
  193. package/lib/privatemessages/getMessages.js +60 -0
  194. package/lib/privatemessages/message.js +80 -0
  195. package/lib/privatemessages/onMessage.js +88 -0
  196. package/lib/thumbnails/getLogo.js +60 -0
  197. package/lib/thumbnails/getPlayerThumbnail.js +121 -0
  198. package/lib/thumbnails/getThumbnails.js +93 -0
  199. package/lib/trades/acceptTrade.js +58 -0
  200. package/lib/trades/canTradeWith.js +48 -0
  201. package/lib/trades/counterTrade.js +84 -0
  202. package/lib/trades/declineTrade.js +58 -0
  203. package/lib/trades/getTradeInfo.js +52 -0
  204. package/lib/trades/getTrades.js +37 -0
  205. package/lib/trades/sendTrade.js +82 -0
  206. package/lib/users/getBlurb.js +36 -0
  207. package/lib/users/getIdFromUsername.js +53 -0
  208. package/lib/users/getPlayerInfo.js +100 -0
  209. package/lib/users/getUsernameFromId.js +44 -0
  210. package/lib/users/onBlurbChange.js +46 -0
  211. package/lib/util/clearSession.js +32 -0
  212. package/lib/util/generalRequest.js +61 -0
  213. package/lib/util/getAction.js +45 -0
  214. package/lib/util/getCurrentUser.js +44 -0
  215. package/lib/util/getGeneralToken.js +52 -0
  216. package/lib/util/getHash.js +29 -0
  217. package/lib/util/getInputs.js +37 -0
  218. package/lib/util/getPageResults.js +89 -0
  219. package/lib/util/getSenderUserId.js +30 -0
  220. package/lib/util/getSession.js +38 -0
  221. package/lib/util/getVerification.js +60 -0
  222. package/lib/util/getVerificationInputs.js +31 -0
  223. package/lib/util/http.js +110 -0
  224. package/lib/util/jar.js +24 -0
  225. package/lib/util/refreshCookie.js +52 -0
  226. package/lib/util/relog.js +81 -0
  227. package/lib/util/setOptions.js +54 -0
  228. package/lib/util/shortPoll.js +102 -0
  229. package/lib/util/threaded.js +80 -0
  230. package/package.json +91 -3
  231. package/postinstall.js +1 -0
  232. package/settings.json +107 -0
  233. package/test/accountinformation.test.js +27 -0
  234. package/test/accountsettings.test.js +27 -0
  235. package/test/asset.test.js +81 -0
  236. package/test/assets/Great-White-Shark-Fin.rbxm +0 -0
  237. package/test/assets/KeyframeSequence.rbxm +0 -0
  238. package/test/avatar.test.js +164 -0
  239. package/test/badges.test.js +96 -0
  240. package/test/chat.test.js +104 -0
  241. package/test/datastore.test.js +105 -0
  242. package/test/develop.test.js +53 -0
  243. package/test/economy.test.js +137 -0
  244. package/test/friends.test.js +128 -0
  245. package/test/games.test.js +212 -0
  246. package/test/groups.test.js +311 -0
  247. package/test/inventory.test.js +98 -0
  248. package/test/itemconfiguration.test.js +24 -0
  249. package/test/premiumfeatures.test.js +17 -0
  250. package/test/presence.test.js +25 -0
  251. package/test/privatemessages.test.js +33 -0
  252. package/test/thumbnails.test.js +53 -0
  253. package/test/users.test.js +68 -0
  254. package/tutorials/Authentication.md +75 -0
  255. package/tutorials/Event Emitters.md +26 -0
  256. package/tutorials/Promises.md +86 -0
  257. package/tutorials/VPS Authentication.md +72 -0
  258. package/typings/index.d.ts +2525 -0
  259. package/typings/jsDocs.ts +1927 -0
@@ -0,0 +1,60 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+
4
+ // Args
5
+ exports.required = ['group']
6
+ exports.optional = ['size', 'circular', 'format']
7
+
8
+ // Docs
9
+ /**
10
+ * ✅ Get the group's logo.
11
+ * @category Group
12
+ * @alias getLogo
13
+ * @param {number} group - The id of the group.
14
+ * @param {GroupIconSize=} [size=150x150] - The size of the logo.
15
+ * @param {boolean=} [circular=false] - Get the circular version of the logo.
16
+ * @param {GroupIconFormat=} [format=Png] - The file format of the logo.
17
+ * @returns {Promise<string>}
18
+ * @example const noblox = require("noblox.js")
19
+ * const logo = await noblox.getLogo(1)
20
+ **/
21
+
22
+ // Define
23
+ function getLogo (group, size, circular, format) {
24
+ const httpOpt = {
25
+ url: '//thumbnails.roblox.com/v1/groups/icons',
26
+ options: {
27
+ qs: {
28
+ groupIds: group,
29
+ size: size || '150x150',
30
+ format: format || 'Png',
31
+ isCircular: circular
32
+ },
33
+ json: true
34
+ }
35
+ }
36
+ return http(httpOpt)
37
+ .then(function (body) {
38
+ const error = body.errors && body.errors[0]
39
+
40
+ if (error) {
41
+ if (error.message === 'NotFound') {
42
+ throw new Error('An invalid UserID or GroupID was provided.')
43
+ } else {
44
+ throw new Error(error.message)
45
+ }
46
+ }
47
+
48
+ const thumbnailData = body.data[0]
49
+
50
+ if (thumbnailData.state !== 'Completed') {
51
+ throw new Error('The requested image has not been approved. Status: ' + thumbnailData.state)
52
+ }
53
+
54
+ return thumbnailData.imageUrl
55
+ })
56
+ }
57
+
58
+ exports.func = function (args) {
59
+ return getLogo(args.group)
60
+ }
@@ -0,0 +1,121 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const { thumbnail: settings } = require('../../settings.json')
4
+
5
+ // Args
6
+ exports.required = ['userIds']
7
+ exports.optional = ['size', 'format', 'isCircular', 'cropType', 'retryCount']
8
+
9
+ // Variables
10
+ const eligibleSizes = {
11
+ body: {
12
+ sizes: ['30x30', '48x48', '60x60', '75x75', '100x100', '110x110', '140x140', '150x150', '150x200', '180x180', '250x250', '352x352', '420x420', '720x720'],
13
+ endpoint: 'avatar'
14
+ },
15
+ bust: {
16
+ sizes: ['48x48', '50x50', '60x60', '75x75', '100x100', '150x150', '180x180', '352x352', '420x420'],
17
+ endpoint: 'avatar-bust'
18
+ },
19
+ headshot: {
20
+ sizes: ['48x48', '50x50', '60x60', '75x75', '100x100', '110x110', '150x150', '180x180', '352x352', '420x420', '720x720'],
21
+ endpoint: 'avatar-headshot'
22
+ }
23
+ }
24
+
25
+ // Docs
26
+ /**
27
+ * ✅ Get a user's thumbnail.
28
+ * @category User
29
+ * @alias getPlayerThumbnail
30
+ * @param {number | Array<number>} userIds - The id or an array ids of thumbnails to be retrieved; 100
31
+ * @param {number | string=} [size=720x720] - The [size of the image to be returned]{@link https://noblox.js.org/thumbnailSizes.png}; defaults highest resolution
32
+ * @param {'png' | 'jpeg'=} [format=png] - The file format of the returned thumbnails
33
+ * @param {boolean=} [isCircular=false] - Return the circular version of the thumbnails
34
+ * @param {'Body' | 'Bust' | 'Headshot'=} [cropType=Body] - The style of thumbnail that will be returned
35
+ * @returns {Promise<PlayerThumbnailData[]>}
36
+ * @example const noblox = require("noblox.js")
37
+ * let thumbnail_default = await noblox.getPlayerThumbnail(2416399685)
38
+ * let thumbnail_circHeadshot = await noblox.getPlayerThumbnail(2416399685, 420, "png", true, "Headshot")
39
+ * let thumbnails_body = await noblox.getPlayerThumbnail([2416399685, 234567, 345678], "150x200", "jpeg", false, "Body")
40
+ **/
41
+
42
+ // Define
43
+ function getPlayerThumbnail (userIds, size, format = 'png', isCircular = false, cropType = 'body', retryCount = settings.maxRetries) {
44
+ // Validate userIds
45
+ if (Array.isArray(userIds)) {
46
+ if (userIds.some(isNaN)) {
47
+ throw new Error('userIds must be a number or an array of numbers')
48
+ }
49
+ userIds = [...new Set(userIds)] // get rid of duplicates, endpoint response does this anyway
50
+ if (userIds.length > 100) {
51
+ throw new Error(`too many userIds provided (${userIds.length}); maximum 100`)
52
+ }
53
+ } else {
54
+ if (isNaN(userIds)) {
55
+ throw new Error('userId is not a number')
56
+ }
57
+ userIds = [userIds]
58
+ }
59
+
60
+ // Validate cropType
61
+ cropType = cropType.toLowerCase()
62
+ if (!Object.keys(eligibleSizes).includes(cropType)) {
63
+ throw new Error(`Invalid cropping type provided: ${cropType} | Use: ${Object.keys(eligibleSizes).join(', ')}`)
64
+ }
65
+ const { sizes, endpoint } = eligibleSizes[cropType]
66
+
67
+ // Validate size
68
+ size = size || sizes[sizes.length - 1]
69
+ if (typeof size === 'number') {
70
+ size = `${size}x${size}`
71
+ }
72
+ if (!sizes.includes(size)) {
73
+ throw new Error(`Invalid size parameter provided: ${size} | [${cropType.toUpperCase()}] Use: ${sizes.join(', ')}`)
74
+ }
75
+
76
+ // Validate format
77
+ if (format.toLowerCase() !== 'png' && format.toLowerCase() !== 'jpeg') {
78
+ throw new Error(`Invalid image type provided: ${format} | Use: png, jpeg`)
79
+ }
80
+
81
+ return http({
82
+ url: `https://thumbnails.roblox.com/v1/users/${endpoint}?userIds=${userIds.join(',')}&size=${size}&format=${format}&isCircular=${!!isCircular}`,
83
+ options: {
84
+ resolveWithFullResponse: true,
85
+ followRedirect: true
86
+ }
87
+ })
88
+ .then(async ({ statusCode, body }) => {
89
+ let { data, errors } = JSON.parse(body)
90
+ if (statusCode === 200) {
91
+ if (retryCount > 0) {
92
+ const pendingThumbnails = data.filter(obj => { return obj.state === 'Pending' }).map(obj => obj.targetId) // Get 'Pending' thumbnails as array of userIds
93
+ if (pendingThumbnails.length > 0) {
94
+ await timeout(settings.retryDelay) // small delay helps cache populate on Roblox's end; default 500ms
95
+ const updatedPending = await getPlayerThumbnail(pendingThumbnails, size, format, isCircular, cropType, --retryCount) // Recursively retry for # of maxRetries attempts; default 2
96
+ data = data.map(obj => updatedPending.find(o => o.targetId === obj.targetId) || obj) // Update primary array's values
97
+ }
98
+ }
99
+ data = data.map(obj => {
100
+ if (obj.state !== 'Completed') {
101
+ const settingsUrl = settings.failedUrl[obj.state.toLowerCase()] // user defined settings.json default image URL for blocked or pending thumbnails; default ""
102
+ obj.imageUrl = settingsUrl || `https://noblox.js.org/moderatedThumbnails/moderatedThumbnail_${size}.png`
103
+ }
104
+ return obj
105
+ })
106
+ return data
107
+ } else if (statusCode === 400) {
108
+ throw new Error(`Error Code ${errors.code}: ${errors.message} | endpoint: ${endpoint}, userIds: ${userIds.join(',')}, size: ${size}, isCircular: ${!!isCircular}`)
109
+ } else {
110
+ throw new Error(`An unknown error occurred with getPlayerThumbnail() | endpoint: ${endpoint}, userIds: ${userIds.join(',')}, size: ${size}, isCircular: ${!!isCircular}`)
111
+ }
112
+ })
113
+ }
114
+
115
+ function timeout (ms) {
116
+ return new Promise(resolve => { setTimeout(resolve, ms) })
117
+ }
118
+
119
+ exports.func = function ({ userIds, size, format, isCircular, cropType, retryCount }) {
120
+ return getPlayerThumbnail(userIds, size, format, isCircular, cropType, retryCount)
121
+ }
@@ -0,0 +1,93 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const { thumbnail: settings } = require('../../settings.json')
4
+
5
+ // Args
6
+ exports.required = ['thumbnailRequests']
7
+ exports.optional = []
8
+
9
+ // Docs
10
+ /**
11
+ * ✅ Get thumbnails for assets/players.
12
+ * @category Assets
13
+ * @alias getThumbnails
14
+ * @param {Array<ThumbnailRequest>} thumbnailRequests - The id or an array ids of thumbnails to be retrieved; 100
15
+ * @returns {Promise<ThumbnailData[]>}
16
+ * @example const noblox = require("noblox.js")
17
+ * const playerThumbnails = noblox.getThumbnails([
18
+ * {
19
+ * type: "AvatarHeadShot",
20
+ * token: "270FF19ECB1AFCF25383A6F37C6AD307",
21
+ * format: "png",
22
+ * size: "150x150"
23
+ * }, {
24
+ * type: "AvatarBust",
25
+ * targetId: 55549140,
26
+ * isCircular: true,
27
+ * format: "png",
28
+ * size: "150x150"
29
+ * }
30
+ * ])
31
+ **/
32
+
33
+ // Define
34
+ function getThumbnails (requests, retryCount = settings.maxRetries) {
35
+ if (!Array.isArray(requests)) {
36
+ throw new Error('thumbnailRequests are not an array')
37
+ }
38
+
39
+ requests = [...new Set(requests)]
40
+ if (requests.length > 100) {
41
+ throw new Error(`Too many thumbnailRequests provided (${requests.length}); maximum 100`)
42
+ }
43
+
44
+ for (const request of requests) {
45
+ if (!request.size || !request.type) {
46
+ throw new Error('thumbnailRequest must have a size and type')
47
+ } else if (request.format && (request.format.toLowerCase() !== 'png' && request.format.toLowerCase() !== 'jpeg')) {
48
+ throw new Error(`Invalid image type provided: ${request.format} | Use: png, jpeg`)
49
+ }
50
+ }
51
+
52
+ return http({
53
+ url: 'https://thumbnails.roblox.com/v1/batch',
54
+ options: {
55
+ method: 'POST',
56
+ json: requests,
57
+ resolveWithFullResponse: true,
58
+ followRedirect: true
59
+ }
60
+ })
61
+ .then(async ({ statusCode, body }) => {
62
+ let { data, errors } = body
63
+ if (statusCode === 200) {
64
+ if (retryCount > 0) {
65
+ const pendingThumbnails = data.filter(obj => { return obj.state === 'Pending' }).map(obj => obj.targetId) // Get 'Pending' thumbnails as array of userIds
66
+ if (pendingThumbnails.length > 0) {
67
+ await timeout(settings.retryDelay) // small delay helps cache populate on Roblox's end; default 500ms
68
+ const updatedPending = await getThumbnails(pendingThumbnails, --retryCount) // Recursively retry for # of maxRetries attempts; default 2
69
+ data = data.map(obj => updatedPending.find(o => o.targetId === obj.targetId) || obj) // Update primary array's values
70
+ }
71
+ }
72
+ data = data.map(obj => {
73
+ if (obj.state !== 'Completed') {
74
+ obj.imageUrl = settings.failedUrl[obj.state.toLowerCase()] || obj.imageUrl
75
+ }
76
+ return obj
77
+ })
78
+ return data
79
+ } else if (statusCode === 400) {
80
+ throw new Error(`Error Code ${errors.code}: ${errors.message} | requests: ${JSON.stringify(requests)}`)
81
+ } else {
82
+ throw new Error(`An unknown error occurred with getThumbnails() | requests: ${JSON.stringify(requests)}`)
83
+ }
84
+ })
85
+ }
86
+
87
+ function timeout (ms) {
88
+ return new Promise(resolve => { setTimeout(resolve, ms) })
89
+ }
90
+
91
+ exports.func = function ({ thumbnailRequests }) {
92
+ return getThumbnails(thumbnailRequests)
93
+ }
@@ -0,0 +1,58 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const getGeneralToken = require('../util/getGeneralToken.js').func
4
+
5
+ // Args
6
+ exports.required = ['tradeId']
7
+ exports.optional = ['jar']
8
+
9
+ // Docs
10
+ /**
11
+ * 🔐 Accept an active trade.
12
+ * @category Trade
13
+ * @alias acceptTrade
14
+ * @param {number} tradeId - The tradeId to accept.
15
+ * @returns {Promise<void>}
16
+ * @example const noblox = require("noblox.js")
17
+ * // Login using your cookie
18
+ * noblox.acceptTrade(1234)
19
+ **/
20
+
21
+ // Define
22
+ function acceptTrade (tradeId, jar, xcsrf) {
23
+ return new Promise((resolve, reject) => {
24
+ http({
25
+ url: '//trades.roblox.com/v1/trades/' + tradeId + '/accept',
26
+ options: {
27
+ method: 'POST',
28
+ resolveWithFullResponse: true,
29
+ jar: jar,
30
+ headers: {
31
+ 'X-CSRF-TOKEN': xcsrf,
32
+ 'Content-Type': 'application/json'
33
+ }
34
+ }
35
+ }).then((res) => {
36
+ if (res.statusCode === 200) {
37
+ resolve()
38
+ } else {
39
+ const body = JSON.parse(res.body) || {}
40
+
41
+ if (body.errors && body.errors.length > 0) {
42
+ const errors = body.errors.map((e) => {
43
+ return e.message
44
+ })
45
+ reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
46
+ }
47
+ }
48
+ }).catch(error => reject(error))
49
+ })
50
+ }
51
+
52
+ exports.func = function (args) {
53
+ const jar = args.jar
54
+ return getGeneralToken({ jar: jar })
55
+ .then(function (xcsrf) {
56
+ return acceptTrade(args.tradeId, jar, xcsrf)
57
+ })
58
+ }
@@ -0,0 +1,48 @@
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
+ * 🔐 Check if the signed in user can trade with another user.
11
+ * @category Trade
12
+ * @alias canTradeWith
13
+ * @param {number} userId - The id of the user.
14
+ * @returns {Promise<CanTradeResponse>}
15
+ * @example const noblox = require("noblox.js")
16
+ * // Login using your cookie
17
+ * const canTrade = await noblox.canTradeWith(1234)
18
+ **/
19
+
20
+ // Define
21
+ function canTradeWith (jar, userId) {
22
+ return new Promise((resolve, reject) => {
23
+ http({
24
+ url: '//trades.roblox.com/v1/users/' + userId + '/can-trade-with',
25
+ options: {
26
+ method: 'GET',
27
+ resolveWithFullResponse: true,
28
+ jar: jar
29
+ }
30
+ }).then((res) => {
31
+ if (res.statusCode === 200) {
32
+ resolve(JSON.parse(res.body))
33
+ } else {
34
+ const body = JSON.parse(res.body) || {}
35
+ if (body.errors && body.errors.length > 0) {
36
+ const errors = body.errors.map((e) => {
37
+ return e.message
38
+ })
39
+ reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
40
+ }
41
+ }
42
+ }).catch(error => reject(error))
43
+ })
44
+ }
45
+
46
+ exports.func = (args) => {
47
+ return canTradeWith(args.jar, args.userId)
48
+ }
@@ -0,0 +1,84 @@
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 = ['tradeId', 'targetUserId', 'sendingOffer', 'receivingOffer']
8
+ exports.optional = ['jar']
9
+
10
+ // Docs
11
+ /**
12
+ * 🔐 Counter an active incoming trade.
13
+ * @category Trade
14
+ * @alias counterTrade
15
+ * @param {number} tradeId - The id of the active trade
16
+ * @param {number} targetUserId - The user to send the trade to.
17
+ * @param {TradeOffer} sendingOffer - The offer to send to the other user.
18
+ * @param {TradeOffer} recievingOffer - The offer you are requesting from the other user.
19
+ * @returns {Promise<SendTradeResponse>}
20
+ * @example const noblox = require("noblox.js")
21
+ * // Login using your cookie
22
+ * noblox.counterTrade(1234, 80231025, { userAssetIds: [23289506393] }, { userAssetIds: [32924150919] })
23
+ **/
24
+
25
+ // Define
26
+ function counterTrade (tradeId, targetUserId, sendingOffer, receivingOffer, jar, xcsrf, loggedInUser) {
27
+ return new Promise((resolve, reject) => {
28
+ if (!sendingOffer.userAssetIds || !receivingOffer.userAssetIds) {
29
+ reject(new Error('Both offers must includes userAssetIds.'))
30
+ }
31
+
32
+ if (!sendingOffer.robux) sendingOffer.robux = 0
33
+ if (!receivingOffer.robux) receivingOffer.robux = 0
34
+
35
+ http({
36
+ url: '//trades.roblox.com/v1/trades/' + tradeId + '/counter',
37
+ options: {
38
+ method: 'POST',
39
+ resolveWithFullResponse: true,
40
+ jar: jar,
41
+ headers: {
42
+ 'X-CSRF-TOKEN': xcsrf,
43
+ 'Content-Type': 'application/json'
44
+ },
45
+ body: JSON.stringify({
46
+ offers: [
47
+ {
48
+ userId: targetUserId,
49
+ ...receivingOffer
50
+ },
51
+ {
52
+ userId: loggedInUser,
53
+ ...sendingOffer
54
+ }
55
+ ]
56
+ })
57
+ }
58
+ }).then((res) => {
59
+ if (res.statusCode === 200) {
60
+ resolve(JSON.parse(res.body))
61
+ } else {
62
+ const body = JSON.parse(res.body) || {}
63
+
64
+ if (body.errors && body.errors.length > 0) {
65
+ const errors = body.errors.map((e) => {
66
+ return e.message
67
+ })
68
+ reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
69
+ }
70
+ }
71
+ }).catch(error => reject(error))
72
+ })
73
+ }
74
+
75
+ exports.func = function (args) {
76
+ const jar = args.jar
77
+ return Promise.all([
78
+ getGeneralToken({ jar: jar }),
79
+ getCurrentUser({ jar: jar, option: 'UserID' })
80
+ ])
81
+ .then(function (resolvedPromises) {
82
+ return counterTrade(args.tradeId, args.targetUserId, args.sendingOffer, args.receivingOffer, jar, resolvedPromises[0], resolvedPromises[1])
83
+ })
84
+ }
@@ -0,0 +1,58 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const getGeneralToken = require('../util/getGeneralToken.js').func
4
+
5
+ // Args
6
+ exports.required = ['tradeId']
7
+ exports.optional = ['jar']
8
+
9
+ // Docs
10
+ /**
11
+ * 🔐 Decline an active trade.
12
+ * @category Trade
13
+ * @alias declineTrade
14
+ * @param {number} tradeId - The tradeId to decline.
15
+ * @returns {Promise<void>}
16
+ * @example const noblox = require("noblox.js")
17
+ * // Login using your cookie
18
+ * noblox.declineTrade(1234)
19
+ **/
20
+
21
+ // Define
22
+ function declineTrade (tradeId, jar, xcsrf) {
23
+ return new Promise((resolve, reject) => {
24
+ http({
25
+ url: '//trades.roblox.com/v1/trades/' + tradeId + '/decline',
26
+ options: {
27
+ method: 'POST',
28
+ resolveWithFullResponse: true,
29
+ jar: jar,
30
+ headers: {
31
+ 'X-CSRF-TOKEN': xcsrf,
32
+ 'Content-Type': 'application/json'
33
+ }
34
+ }
35
+ }).then((res) => {
36
+ if (res.statusCode === 200) {
37
+ resolve()
38
+ } else {
39
+ const body = JSON.parse(res.body) || {}
40
+
41
+ if (body.errors && body.errors.length > 0) {
42
+ const errors = body.errors.map((e) => {
43
+ return e.message
44
+ })
45
+ reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
46
+ }
47
+ }
48
+ }).catch(error => reject(error))
49
+ })
50
+ }
51
+
52
+ exports.func = function (args) {
53
+ const jar = args.jar
54
+ return getGeneralToken({ jar: jar })
55
+ .then(function (xcsrf) {
56
+ return declineTrade(args.tradeId, jar, xcsrf)
57
+ })
58
+ }
@@ -0,0 +1,52 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+
4
+ // Args
5
+ exports.required = ['tradeId']
6
+ exports.optional = ['jar']
7
+
8
+ // Docs
9
+ /**
10
+ * 🔐 Get detailed information for a specific trade.
11
+ * @category Trade
12
+ * @alias getTradeInfo
13
+ * @param {number} tradeId - The id of the trade.
14
+ * @returns {Promise<TradeInfo>}
15
+ * @example const noblox = require("noblox.js")
16
+ * // Login using your cookie
17
+ * const tradeInfo = await noblox.getTradeInfo(1234)
18
+ **/
19
+
20
+ // Define
21
+ const getTradeInfo = (jar, tradeId) => {
22
+ return new Promise((resolve, reject) => {
23
+ http({
24
+ url: '//trades.roblox.com/v1/trades/' + tradeId,
25
+ options: {
26
+ method: 'GET',
27
+ resolveWithFullResponse: true,
28
+ jar: jar
29
+ }
30
+ }).then((res) => {
31
+ if (res.statusCode === 200) {
32
+ const body = JSON.parse(res.body)
33
+ body.created = new Date(body.created)
34
+ if (body.expiration) body.expiration = new Date(body.expiration)
35
+
36
+ resolve(body)
37
+ } else {
38
+ const body = JSON.parse(res.body) || {}
39
+ if (body.errors && body.errors.length > 0) {
40
+ const errors = body.errors.map((e) => {
41
+ return e.message
42
+ })
43
+ reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
44
+ }
45
+ }
46
+ }).catch(error => reject(error))
47
+ })
48
+ }
49
+
50
+ exports.func = (args) => {
51
+ return getTradeInfo(args.jar, args.tradeId)
52
+ }
@@ -0,0 +1,37 @@
1
+ // Includes
2
+ const getPageResults = require('../util/getPageResults.js').func
3
+
4
+ // Args
5
+ exports.required = ['tradeStatusType']
6
+ exports.optional = ['sortOrder', 'limit', 'jar']
7
+
8
+ // Docs
9
+ /**
10
+ * 🔐 Get the trades for a specific category.
11
+ * @category Trade
12
+ * @alias getTrades
13
+ * @param {string} tradeStatusType - The status of the trades to get [Inbound, Outbound, Complete, Inactive].
14
+ * @param {SortOrder=} [sortOrder=Asc] - The order that the data will be returned in (Asc or Desc)
15
+ * @param {Limit=} [limit=10] - The number of assets returned in each request (10, 25, 50, or 100)
16
+ * @returns {Promise<TradeAsset[]>}
17
+ * @example const noblox = require("noblox.js")
18
+ * // Login using your cookie
19
+ * const trades = await noblox.getTrades("Inbound")
20
+ **/
21
+
22
+ // Define
23
+ exports.func = function (args) {
24
+ return getPageResults({
25
+ jar: args.jar,
26
+ url: `//trades.roblox.com/v1/trades/${args.tradeStatusType}`,
27
+ sortOrder: args.sortOrder,
28
+ limit: args.limit
29
+ }).then(function (results) {
30
+ results.forEach(result => {
31
+ result.created = new Date(result.created)
32
+ if (result.expiration) result.expiration = new Date(result.expiration)
33
+ })
34
+
35
+ return results
36
+ })
37
+ }