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.

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 +168 -0
  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 +94 -0
  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
+ }