noblox-asset.js 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  3. package/.github/workflows/doc-publish.yml +33 -0
  4. package/.github/workflows/npmpublish.yml +72 -0
  5. package/.github/workflows/run-tests.yml +49 -0
  6. package/CODE_OF_CONDUCT.md +76 -0
  7. package/LICENSE +21 -0
  8. package/README.md +182 -0
  9. package/eslint.config.mjs +34 -0
  10. package/examples/cleanPlayers.js +130 -0
  11. package/examples/cleanWall.js +110 -0
  12. package/examples/revertRanks.js +100 -0
  13. package/examples/savePlayers.js +119 -0
  14. package/examples/saveWall.js +96 -0
  15. package/img/moderatedThumbnails/moderatedThumbnail_100x100.png +0 -0
  16. package/img/moderatedThumbnails/moderatedThumbnail_110x110.png +0 -0
  17. package/img/moderatedThumbnails/moderatedThumbnail_140x140.png +0 -0
  18. package/img/moderatedThumbnails/moderatedThumbnail_150x150.png +0 -0
  19. package/img/moderatedThumbnails/moderatedThumbnail_150x200.png +0 -0
  20. package/img/moderatedThumbnails/moderatedThumbnail_180x180.png +0 -0
  21. package/img/moderatedThumbnails/moderatedThumbnail_250x250.png +0 -0
  22. package/img/moderatedThumbnails/moderatedThumbnail_30x30.png +0 -0
  23. package/img/moderatedThumbnails/moderatedThumbnail_352x352.png +0 -0
  24. package/img/moderatedThumbnails/moderatedThumbnail_420x420.png +0 -0
  25. package/img/moderatedThumbnails/moderatedThumbnail_48x48.png +0 -0
  26. package/img/moderatedThumbnails/moderatedThumbnail_50x50.png +0 -0
  27. package/img/moderatedThumbnails/moderatedThumbnail_60x60.png +0 -0
  28. package/img/moderatedThumbnails/moderatedThumbnail_720x720.png +0 -0
  29. package/img/moderatedThumbnails/moderatedThumbnail_75x75.png +0 -0
  30. package/img/noblox-js-small.png +0 -0
  31. package/img/noblox-js.png +0 -0
  32. package/img/thumbnailSizes.png +0 -0
  33. package/jsDocsConfig.json +55 -0
  34. package/lib/accountinformation/getUserSocialLinks.js +40 -0
  35. package/lib/accountsettings/block.js +53 -0
  36. package/lib/accountsettings/unblock.js +53 -0
  37. package/lib/asset/deleteFromInventory.js +56 -0
  38. package/lib/asset/getGamePassProductInfo.js +50 -0
  39. package/lib/asset/getProductInfo.js +46 -0
  40. package/lib/asset/uploadAnimation.js +103 -0
  41. package/lib/asset/uploadItem.js +83 -0
  42. package/lib/asset/uploadModel.js +90 -0
  43. package/lib/avatar/avatarRules.js +39 -0
  44. package/lib/avatar/currentlyWearing.js +33 -0
  45. package/lib/avatar/getAvatar.js +36 -0
  46. package/lib/avatar/getCurrentAvatar.js +38 -0
  47. package/lib/avatar/getRecentItems.js +36 -0
  48. package/lib/avatar/outfitDetails.js +33 -0
  49. package/lib/avatar/outfits.js +38 -0
  50. package/lib/avatar/redrawAvatar.js +47 -0
  51. package/lib/avatar/removeAssetId.js +51 -0
  52. package/lib/avatar/setAvatarBodyColors.js +61 -0
  53. package/lib/avatar/setAvatarScales.js +61 -0
  54. package/lib/avatar/setPlayerAvatarType.js +51 -0
  55. package/lib/avatar/setWearingAssets.js +51 -0
  56. package/lib/avatar/wearAssetId.js +51 -0
  57. package/lib/badges/getAwardedTimestamps.js +49 -0
  58. package/lib/badges/getBadgeInfo.js +44 -0
  59. package/lib/badges/getGameBadges.js +63 -0
  60. package/lib/badges/getPlayerBadges.js +28 -0
  61. package/lib/badges/updateBadgeInfo.js +75 -0
  62. package/lib/cache/add.js +14 -0
  63. package/lib/cache/addIf.js +26 -0
  64. package/lib/cache/clear.js +8 -0
  65. package/lib/cache/get.js +28 -0
  66. package/lib/cache/index.js +17 -0
  67. package/lib/cache/new.js +12 -0
  68. package/lib/cache/wrap.js +25 -0
  69. package/lib/chat/addUsersToConversation.js +58 -0
  70. package/lib/chat/chatSettings.js +34 -0
  71. package/lib/chat/getChatMessages.js +41 -0
  72. package/lib/chat/getConversations.js +44 -0
  73. package/lib/chat/getRolloutSettings.js +36 -0
  74. package/lib/chat/getUnreadConversationCount.js +34 -0
  75. package/lib/chat/getUnreadMessages.js +39 -0
  76. package/lib/chat/getUserConversations.js +38 -0
  77. package/lib/chat/markChatAsRead.js +53 -0
  78. package/lib/chat/markChatAsSeen.js +51 -0
  79. package/lib/chat/multiGetLatestMessages.js +38 -0
  80. package/lib/chat/onNewConversation.js +50 -0
  81. package/lib/chat/onNewMessage.js +53 -0
  82. package/lib/chat/onNewMessageBySelf.js +50 -0
  83. package/lib/chat/onUserOnline.js +50 -0
  84. package/lib/chat/onUserTyping.js +54 -0
  85. package/lib/chat/removeFromGroupConversation.js +59 -0
  86. package/lib/chat/renameGroupConversation.js +58 -0
  87. package/lib/chat/sendChatMessage.js +58 -0
  88. package/lib/chat/setChatUserTyping.js +58 -0
  89. package/lib/chat/start121Conversation.js +51 -0
  90. package/lib/chat/startCloudEditConversation.js +51 -0
  91. package/lib/chat/startGroupConversation.js +59 -0
  92. package/lib/client/onNotification.js +86 -0
  93. package/lib/client/setAPIKey.js +18 -0
  94. package/lib/client/setCookie.js +38 -0
  95. package/lib/datastores/deleteDatastoreEntry.js +56 -0
  96. package/lib/datastores/getDatastoreEntry.js +88 -0
  97. package/lib/datastores/getDatastoreEntryVersions.js +73 -0
  98. package/lib/datastores/getDatastoreKeys.js +63 -0
  99. package/lib/datastores/getDatastores.js +62 -0
  100. package/lib/datastores/incrementDatastoreEntry.js +83 -0
  101. package/lib/datastores/setDatastoreEntry.js +80 -0
  102. package/lib/develop/canManage.js +42 -0
  103. package/lib/develop/configureItem.js +210 -0
  104. package/lib/develop/updateUniverse.js +52 -0
  105. package/lib/develop/updateUniverseAccess.js +54 -0
  106. package/lib/economy/getGroupFunds.js +42 -0
  107. package/lib/economy/getGroupPayoutEligibility.js +55 -0
  108. package/lib/economy/getGroupRevenueSummary.js +42 -0
  109. package/lib/economy/getGroupTransactions.js +32 -0
  110. package/lib/economy/getResaleData.js +48 -0
  111. package/lib/economy/getResellers.js +35 -0
  112. package/lib/economy/getUserFunds.js +43 -0
  113. package/lib/economy/getUserTransactions.js +34 -0
  114. package/lib/economy/onGroupTransaction.js +74 -0
  115. package/lib/friends/acceptFriendRequest.js +54 -0
  116. package/lib/friends/declineAllFriendRequests.js +52 -0
  117. package/lib/friends/declineFriendRequest.js +54 -0
  118. package/lib/friends/getFollowerCount.js +35 -0
  119. package/lib/friends/getFollowers.js +56 -0
  120. package/lib/friends/getFollowingCount.js +35 -0
  121. package/lib/friends/getFollowings.js +56 -0
  122. package/lib/friends/getFriendCount.js +35 -0
  123. package/lib/friends/getFriendRequests.js +51 -0
  124. package/lib/friends/getFriends.js +48 -0
  125. package/lib/friends/onFriendRequest.js +58 -0
  126. package/lib/friends/removeFriend.js +53 -0
  127. package/lib/friends/sendFriendRequest.js +54 -0
  128. package/lib/friends/unfollow.js +53 -0
  129. package/lib/games/addDeveloperProduct.js +53 -0
  130. package/lib/games/configureGamePass.js +126 -0
  131. package/lib/games/getDeveloperProducts.js +44 -0
  132. package/lib/games/getGameInstances.js +31 -0
  133. package/lib/games/getGamePasses.js +39 -0
  134. package/lib/games/getGameRevenue.js +48 -0
  135. package/lib/games/getGameSocialLinks.js +42 -0
  136. package/lib/games/getGroupGames.js +30 -0
  137. package/lib/games/getPlaceInfo.js +47 -0
  138. package/lib/games/getUniverseInfo.js +50 -0
  139. package/lib/games/publishToTopic.js +52 -0
  140. package/lib/games/sendUserNotification.js +65 -0
  141. package/lib/games/updateDeveloperProduct.js +56 -0
  142. package/lib/groups/banFromGroup.js +47 -0
  143. package/lib/groups/changeRank.js +59 -0
  144. package/lib/groups/deleteWallPost.js +59 -0
  145. package/lib/groups/deleteWallPostsByUser.js +55 -0
  146. package/lib/groups/demote.js +25 -0
  147. package/lib/groups/exile.js +55 -0
  148. package/lib/groups/getAuditLog.js +64 -0
  149. package/lib/groups/getGroup.js +50 -0
  150. package/lib/groups/getGroupBans.js +37 -0
  151. package/lib/groups/getGroupSocialLinks.js +41 -0
  152. package/lib/groups/getGroups.js +82 -0
  153. package/lib/groups/getJoinRequest.js +47 -0
  154. package/lib/groups/getJoinRequests.js +53 -0
  155. package/lib/groups/getPlayers.js +103 -0
  156. package/lib/groups/getRankInGroup.js +45 -0
  157. package/lib/groups/getRankNameInGroup.js +44 -0
  158. package/lib/groups/getRole.js +64 -0
  159. package/lib/groups/getRolePermissions.js +48 -0
  160. package/lib/groups/getRoles.js +53 -0
  161. package/lib/groups/getShout.js +47 -0
  162. package/lib/groups/getWall.js +56 -0
  163. package/lib/groups/groupPayout.js +103 -0
  164. package/lib/groups/handleJoinRequest.js +57 -0
  165. package/lib/groups/handleJoinRequests.js +61 -0
  166. package/lib/groups/leaveGroup.js +56 -0
  167. package/lib/groups/onAuditLog.js +62 -0
  168. package/lib/groups/onJoinRequest.js +63 -0
  169. package/lib/groups/onJoinRequestHandle.js +105 -0
  170. package/lib/groups/onShout.js +57 -0
  171. package/lib/groups/onWallPost.js +58 -0
  172. package/lib/groups/promote.js +25 -0
  173. package/lib/groups/searchGroups.js +32 -0
  174. package/lib/groups/setGroupDescription.js +58 -0
  175. package/lib/groups/setGroupName.js +59 -0
  176. package/lib/groups/setRank.js +74 -0
  177. package/lib/groups/setRoleInfo.js +84 -0
  178. package/lib/groups/shout.js +58 -0
  179. package/lib/groups/unbanFromGroup.js +41 -0
  180. package/lib/index.js +212 -0
  181. package/lib/internal/levelOneCopy.js +16 -0
  182. package/lib/internal/queue.js +61 -0
  183. package/lib/internal/timeout.js +30 -0
  184. package/lib/internal/wrap.js +78 -0
  185. package/lib/inventory/getCollectibles.js +31 -0
  186. package/lib/inventory/getInventory.js +32 -0
  187. package/lib/inventory/getInventoryById.js +31 -0
  188. package/lib/inventory/getOwnership.js +47 -0
  189. package/lib/inventory/getUAIDs.js +47 -0
  190. package/lib/itemconfiguration/getGroupAssets.js +32 -0
  191. package/lib/options.js +26 -0
  192. package/lib/party/onPartyDeleted.js +53 -0
  193. package/lib/party/onPartyInvite.js +53 -0
  194. package/lib/party/onPartyJoinedGame.js +53 -0
  195. package/lib/party/onPartyLeftGame.js +53 -0
  196. package/lib/party/onPartySelfJoined.js +53 -0
  197. package/lib/party/onPartySelfLeft.js +53 -0
  198. package/lib/party/onPartyUserJoined.js +53 -0
  199. package/lib/party/onPartyUserLeft.js +53 -0
  200. package/lib/premiumfeatures/getPremium.js +46 -0
  201. package/lib/presence/getPresences.js +60 -0
  202. package/lib/privatemessages/getMessages.js +55 -0
  203. package/lib/privatemessages/message.js +75 -0
  204. package/lib/privatemessages/onMessage.js +89 -0
  205. package/lib/thumbnails/getLogo.js +56 -0
  206. package/lib/thumbnails/getPlayerThumbnail.js +120 -0
  207. package/lib/thumbnails/getThumbnails.js +92 -0
  208. package/lib/trades/acceptTrade.js +52 -0
  209. package/lib/trades/canTradeWith.js +43 -0
  210. package/lib/trades/counterTrade.js +78 -0
  211. package/lib/trades/declineTrade.js +52 -0
  212. package/lib/trades/getTradeInfo.js +47 -0
  213. package/lib/trades/getTrades.js +37 -0
  214. package/lib/trades/sendTrade.js +76 -0
  215. package/lib/users/getBlurb.js +37 -0
  216. package/lib/users/getIdFromUsername.js +56 -0
  217. package/lib/users/getPlayerInfo.js +128 -0
  218. package/lib/users/getUserInfo.js +35 -0
  219. package/lib/users/getUsernameFromId.js +45 -0
  220. package/lib/users/getUsernameHistory.js +42 -0
  221. package/lib/users/onBlurbChange.js +46 -0
  222. package/lib/users/searchUsers.js +41 -0
  223. package/lib/util/apiError.js +50 -0
  224. package/lib/util/clearSession.js +32 -0
  225. package/lib/util/generalRequest.js +61 -0
  226. package/lib/util/getAction.js +45 -0
  227. package/lib/util/getAuthenticatedUser.js +41 -0
  228. package/lib/util/getCurrentUser.js +58 -0
  229. package/lib/util/getGeneralToken.js +52 -0
  230. package/lib/util/getHash.js +29 -0
  231. package/lib/util/getInputs.js +37 -0
  232. package/lib/util/getPageResults.js +86 -0
  233. package/lib/util/getSenderUserId.js +30 -0
  234. package/lib/util/getSession.js +38 -0
  235. package/lib/util/getVerification.js +60 -0
  236. package/lib/util/getVerificationInputs.js +31 -0
  237. package/lib/util/http.js +138 -0
  238. package/lib/util/jar.js +25 -0
  239. package/lib/util/refreshCookie.js +52 -0
  240. package/lib/util/relog.js +81 -0
  241. package/lib/util/setOptions.js +54 -0
  242. package/lib/util/shortPoll.js +102 -0
  243. package/package.json +76 -0
  244. package/postinstall.mjs +1 -0
  245. package/settings.json +115 -0
  246. package/test/accountinformation.test.js +27 -0
  247. package/test/accountsettings.test.js +27 -0
  248. package/test/asset.test.js +81 -0
  249. package/test/assets/Great-White-Shark-Fin.rbxm +0 -0
  250. package/test/assets/KeyframeSequence.rbxm +0 -0
  251. package/test/avatar.test.js +164 -0
  252. package/test/badges.test.js +96 -0
  253. package/test/chat.test.js +104 -0
  254. package/test/datastore.test.js +105 -0
  255. package/test/develop.test.js +53 -0
  256. package/test/economy.test.js +143 -0
  257. package/test/friends.test.js +146 -0
  258. package/test/games.test.js +229 -0
  259. package/test/groups.test.js +405 -0
  260. package/test/inventory.test.js +98 -0
  261. package/test/itemconfiguration.test.js +24 -0
  262. package/test/premiumfeatures.test.js +17 -0
  263. package/test/presence.test.js +25 -0
  264. package/test/privatemessages.test.js +33 -0
  265. package/test/thumbnails.test.js +53 -0
  266. package/test/users.test.js +110 -0
  267. package/tutorials/Authentication.md +75 -0
  268. package/tutorials/Event Emitters.md +26 -0
  269. package/tutorials/Promises.md +86 -0
  270. package/tutorials/VPS Authentication.md +72 -0
  271. package/typings/index.d.ts +2639 -0
  272. package/typings/jsDocs.ts +1987 -0
@@ -0,0 +1,53 @@
1
+ const events = require('events')
2
+
3
+ const onNotification = require('../client/onNotification.js').func
4
+
5
+ exports.optional = ['jar']
6
+
7
+ // Docs
8
+ /**
9
+ * 🔐 An event for when someone joins a party.
10
+ * @category Party
11
+ * @alias onPartyUserJoined
12
+ * @returns An EventEmitter that emits when someone joins a party.
13
+ * @example const noblox = require("noblox.js")
14
+ * // Login using your cookie
15
+ * const partyJoined = noblox.onPartyUserJoined()
16
+ * partyJoined.on("data", function(data) {
17
+ * console.log("Someone joined a party! ", data)
18
+ * })
19
+ * partyJoined.on("error", function(err) {
20
+ * console.error("Something went wrong: ", err)
21
+ * // Handle error as needed
22
+ * })
23
+ **/
24
+
25
+ exports.func = (args) => {
26
+ const jar = args.jar
27
+ const newEvent = new events.EventEmitter()
28
+ const notifications = onNotification({ jar })
29
+
30
+ notifications.on('data', (name, message) => {
31
+ if (name === 'PartyNotifications' && message.Type === 'PartyUserJoined') {
32
+ newEvent.emit('data', {
33
+ PartyId: message.PartyId,
34
+ PartyType: message.PartyType
35
+ })
36
+ }
37
+ })
38
+
39
+ notifications.on('error', (err) => {
40
+ newEvent.emit('error', err)
41
+ })
42
+
43
+ notifications.on('connect', () => {
44
+ newEvent.emit('connect')
45
+ })
46
+
47
+ notifications.on('close', (internal) => {
48
+ if (internal) return
49
+ notifications.emit('close', true)
50
+ })
51
+
52
+ return newEvent
53
+ }
@@ -0,0 +1,53 @@
1
+ const events = require('events')
2
+
3
+ const onNotification = require('../client/onNotification.js').func
4
+
5
+ exports.optional = ['jar']
6
+
7
+ // Docs
8
+ /**
9
+ * 🔐 An event for when someone leaves a party.
10
+ * @category Party
11
+ * @alias onPartyUserLeft
12
+ * @returns An EventEmitter that emits when someone leaves a party.
13
+ * @example const noblox = require("noblox.js")
14
+ * // Login using your cookie
15
+ * const partyLeft = noblox.onPartyUserLeft()
16
+ * partyLeft.on("data", function(data) {
17
+ * console.log("Someone left party! ", data)
18
+ * })
19
+ * partyLeft.on("error", function(err) {
20
+ * console.error("Something went wrong: ", err)
21
+ * // Handle error as needed
22
+ * })
23
+ **/
24
+
25
+ exports.func = (args) => {
26
+ const jar = args.jar
27
+ const newEvent = new events.EventEmitter()
28
+ const notifications = onNotification({ jar })
29
+
30
+ notifications.on('data', (name, message) => {
31
+ if (name === 'PartyNotifications' && message.Type === 'PartyUserLeft') {
32
+ newEvent.emit('data', {
33
+ PartyId: message.PartyId,
34
+ PartyType: message.PartyType
35
+ })
36
+ }
37
+ })
38
+
39
+ notifications.on('error', (err) => {
40
+ newEvent.emit('error', err)
41
+ })
42
+
43
+ notifications.on('connect', () => {
44
+ newEvent.emit('connect')
45
+ })
46
+
47
+ notifications.on('close', (internal) => {
48
+ if (internal) return
49
+ notifications.emit('close', true)
50
+ })
51
+
52
+ return newEvent
53
+ }
@@ -0,0 +1,46 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const RobloxAPIError = require('../util/apiError.js')
4
+
5
+ // Args
6
+ exports.required = ['userId']
7
+ exports.optional = ['jar']
8
+
9
+ // Docs
10
+ /**
11
+ * 🔐 Gets whether or not a user has premium.
12
+ * @category User
13
+ * @alias getPremium
14
+ * @param {number} userId - The id of the user.
15
+ * @returns {Promise<boolean>}
16
+ * @example const noblox = require("noblox.js")
17
+ * // Login using your cookie
18
+ * const hasPremium = await noblox.getPremium(123456)
19
+ **/
20
+
21
+ // Define
22
+ function getPremium (jar, userId) {
23
+ return new Promise((resolve, reject) => {
24
+ const httpOpt = {
25
+ url: `https://premiumfeatures.roblox.com/v1/users/${userId}/validate-membership`,
26
+ options: {
27
+ method: 'GET',
28
+ jar,
29
+ resolveWithFullResponse: true
30
+ }
31
+ }
32
+ return http(httpOpt)
33
+ .then(function (res) {
34
+ if (res.statusCode === 200) {
35
+ resolve(res.body === 'true')
36
+ } else {
37
+ reject(new RobloxAPIError(res))
38
+ }
39
+ })
40
+ })
41
+ }
42
+
43
+ exports.func = function (args) {
44
+ const jar = args.jar
45
+ return getPremium(jar, args.userId)
46
+ }
@@ -0,0 +1,60 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const getGeneralToken = require('../util/getGeneralToken.js').func
4
+ const RobloxAPIError = require('../util/apiError.js')
5
+
6
+ // Args
7
+ exports.required = ['userIds']
8
+ exports.optional = []
9
+
10
+ // Docs
11
+ /**
12
+ * 🔐 Get the presence status of users.
13
+ * @category Presence
14
+ * @alias getPresences
15
+ * @param {Array<number>} userIds - An array of userIds.
16
+ * @returns {Promise<Presences>}
17
+ * @example const noblox = require("noblox.js")
18
+ * // Login using your cookie
19
+ * const presences = await noblox.getPresences([1, 2, 3])
20
+ **/
21
+
22
+ // Define
23
+ function getPresences (userIds, jar, xcsrf) {
24
+ return new Promise((resolve, reject) => {
25
+ const httpOpt = {
26
+ url: '//presence.roblox.com/v1/presence/users',
27
+ options: {
28
+ method: 'POST',
29
+ resolveWithFullResponse: true,
30
+ jar,
31
+ headers: {
32
+ 'X-CSRF-TOKEN': xcsrf,
33
+ 'Content-Type': 'application/json'
34
+ },
35
+ body: JSON.stringify({
36
+ userIds
37
+ })
38
+ }
39
+ }
40
+
41
+ return http(httpOpt)
42
+ .then(function (res) {
43
+ const responseData = JSON.parse(res.body)
44
+ if (res.statusCode !== 200) {
45
+ reject(new RobloxAPIError(res))
46
+ } else {
47
+ resolve(responseData)
48
+ }
49
+ })
50
+ .catch(error => reject(error))
51
+ })
52
+ }
53
+
54
+ exports.func = function (args) {
55
+ const jar = args.jar
56
+ return getGeneralToken({ jar })
57
+ .then(function (xcsrf) {
58
+ return getPresences(args.userIds, args.jar, xcsrf)
59
+ })
60
+ }
@@ -0,0 +1,55 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const RobloxAPIError = require('../util/apiError.js')
4
+ // Args
5
+ exports.required = []
6
+ exports.optional = ['pageNumber', 'pageSize', 'messageTab', 'jar']
7
+
8
+ // Docs
9
+ /**
10
+ * 🔐 Get the messages of the authenticated user.
11
+ * @category User
12
+ * @alias getMessages
13
+ * @param {number=} [pageNumber=0] - The number of the current page.
14
+ * @param {number=} [pageSize=25] - The size of the current page.
15
+ * @param {("Inbox" | "Sent" | "Archive")=} [messageTab=Inbox] - The tab of the messages being fetched (Inbox, Sent, Archive)
16
+ * @returns {Promise<PrivateMessagesPage>}
17
+ * @example const noblox = require("noblox.js")
18
+ * // Login using your cookie
19
+ * let messages = await noblox.getMessages(1, 10, "Inbox"))
20
+ **/
21
+
22
+ // Define
23
+ function getMessages (jar, pageNumber, pageSize, messageTab) {
24
+ return new Promise((resolve, reject) => {
25
+ const httpOpt = {
26
+ url: `//privatemessages.roblox.com/v1/messages?pageNumber=${pageNumber}&pageSize=${pageSize}&messageTab=${messageTab}`,
27
+ options: {
28
+ method: 'GET',
29
+ jar,
30
+ resolveWithFullResponse: true
31
+ }
32
+ }
33
+ return http(httpOpt)
34
+ .then(function (res) {
35
+ if (res.statusCode === 200) {
36
+ resolve(JSON.parse(res.body))
37
+ } else {
38
+ reject(new RobloxAPIError(res))
39
+ }
40
+ })
41
+ })
42
+ }
43
+
44
+ exports.func = function (args) {
45
+ const jar = args.jar
46
+ const pageNumber = (args.pageNumber && args.pageNumber.toString()) || '0'
47
+ const pageSize = (args.pageSize && args.pageSize.toString()) || '25'
48
+ const messageTab = args.messageTab || 'Inbox'
49
+ if (!['Inbox', 'Sent', 'Archive'].includes(messageTab)) {
50
+ return new Promise((resolve, reject) => {
51
+ reject(new Error('messageTab must be Inbox, Sent, or Archive'))
52
+ })
53
+ }
54
+ return getMessages(jar, pageNumber, pageSize, messageTab)
55
+ }
@@ -0,0 +1,75 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const queue = require('../internal/queue.js')
4
+ const getGeneralToken = require('../util/getGeneralToken.js').func
5
+ const getHash = require('../util/getHash.js').func
6
+ const getSenderId = require('../util/getSenderUserId.js').func
7
+ const RobloxAPIError = require('../util/apiError.js')
8
+
9
+ // Args
10
+ exports.required = ['recipient', 'subject', 'body']
11
+ exports.optional = ['replyMessageId', 'includePreviousMessage', 'jar']
12
+
13
+ // Docs
14
+ /**
15
+ * 🔐 Send a message. NOTE: Roblox blocks web servers and proxies from sending messages.
16
+ * @category User
17
+ * @alias message
18
+ * @param {number} recipient - The id of the user.
19
+ * @param {string} subject - The subject of the message.
20
+ * @param {string} body - The body of the message.
21
+ * @param {number=} replyMessageId - The messageId to reply to.
22
+ * @param {boolean=} [includePreviousMessage=false] - The previous or next page cursor.
23
+ * @returns {Promise<void>}
24
+ * @example const noblox = require("noblox.js")
25
+ * // Login using your cookie
26
+ * noblox.message(1, "A subject", "A body", 1234, true)
27
+ **/
28
+
29
+ // Define
30
+ function message (jar, token, senderId, recipient, subject, body, replyMessageId, includePreviousMessage) {
31
+ return new Promise((resolve, reject) => {
32
+ const httpOpt = {
33
+ url: '//privatemessages.roblox.com/v1/messages/send',
34
+ options: {
35
+ method: 'POST',
36
+ jar,
37
+ headers: {
38
+ 'X-CSRF-TOKEN': token,
39
+ 'Content-Type': 'application/json'
40
+ },
41
+ body: JSON.stringify({
42
+ userId: senderId,
43
+ recipientId: recipient,
44
+ subject,
45
+ body,
46
+ replyMessageId,
47
+ includePreviousMessage
48
+ }),
49
+ resolveWithFullResponse: true
50
+ }
51
+ }
52
+ return http(httpOpt)
53
+ .then(function (res) {
54
+ if (res.statusCode === 200) {
55
+ resolve(JSON.parse(res.body))
56
+ } else {
57
+ reject(new RobloxAPIError(res))
58
+ }
59
+ })
60
+ })
61
+ }
62
+
63
+ exports.func = function (args) {
64
+ const jar = args.jar
65
+ return queue('Message', getHash({ jar }), function () {
66
+ return getGeneralToken({ jar })
67
+ .then(function (xcsrf) {
68
+ return getSenderId({ jar }).then((senderId) => {
69
+ return message(jar, xcsrf, senderId, args.recipient, args.subject, args.body, args.replyMessageId, args.includePreviousMessage)
70
+ })
71
+ })
72
+ }, function () {
73
+ return true
74
+ })
75
+ }
@@ -0,0 +1,89 @@
1
+ // Dependencies
2
+ const events = require('events')
3
+
4
+ // Includes
5
+ const onNotification = require('../client/onNotification.js').func
6
+ const getMessages = require('./getMessages.js').func
7
+
8
+ // Args
9
+ exports.optional = ['jar']
10
+
11
+ // Docs
12
+ /**
13
+ * 🔐 An event for when a user sends you a message via. the older 'email-like' message system. To receive chat messages,
14
+ * see the `onNewMessage` method.
15
+ * @see [onNewMessage()](global.html#onNewMessage).
16
+ * @category User
17
+ * @alias onMessage
18
+ * @returns An EventEmitter that emits when a user sends you a message.
19
+ * @example const noblox = require("noblox.js")
20
+ * // Login using your cookie
21
+ * const messageEvent = noblox.onMessage()
22
+ * messageEvent.on("data", function(data) {
23
+ * console.log("New message! ", data)
24
+ * })
25
+ * messageEvent.on("error", function(err) {
26
+ * console.error("Something went wrong: ", err)
27
+ * // Handle error as needed
28
+ * })
29
+ **/
30
+
31
+ // Define
32
+ exports.func = function (args) {
33
+ const jar = args.jar
34
+ const onMessage = new events.EventEmitter()
35
+ let waitingForRequest = false
36
+ let latest
37
+ getMessages({ jar, messageTab: 'Inbox', pageNumber: 0, pageSize: 1 })
38
+ .then(function (initial) {
39
+ latest = initial.collection[0] ? initial.collection[0].id : 0
40
+ const notifications = onNotification({ jar })
41
+ notifications.on('data', function (name, message) {
42
+ if (name === 'MessageNotification' && message.Type === 'Created') {
43
+ if (waitingForRequest) {
44
+ waitingForRequest = false
45
+ } else {
46
+ getMessages({
47
+ jar,
48
+ messageTab: 'Inbox',
49
+ pageNumber: 0,
50
+ pageSize: 1
51
+ })
52
+ .then(function (inbox) {
53
+ const messages = inbox.collection
54
+ for (let i = messages.length - 1; i >= 0; i--) {
55
+ const message = messages[i]
56
+ const id = message.id
57
+ if (id > latest) {
58
+ latest = id
59
+ onMessage.emit('data', message)
60
+ }
61
+ }
62
+ })
63
+ }
64
+ } else if (name === 'FriendshipNotifications' && message.Type === 'FriendshipRequested') {
65
+ waitingForRequest = true
66
+ }
67
+ })
68
+ notifications.on('error', function (err) {
69
+ onMessage.emit('error', err)
70
+ })
71
+ notifications.on('connect', function () {
72
+ onMessage.emit('connect')
73
+ })
74
+ notifications.on('close', function (internal) {
75
+ if (internal) {
76
+ return
77
+ }
78
+ onMessage.emit('close', true)
79
+ })
80
+ onMessage.on('close', function (internal) {
81
+ if (internal) {
82
+ return
83
+ }
84
+ notifications.emit('close', true)
85
+ })
86
+ })
87
+
88
+ return onMessage
89
+ }
@@ -0,0 +1,56 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const RobloxAPIError = require('../util/apiError.js')
4
+
5
+ // Args
6
+ exports.required = ['group']
7
+ exports.optional = ['size', 'circular', 'format']
8
+
9
+ // Docs
10
+ /**
11
+ * ✅ Get the group's logo.
12
+ * @category Group
13
+ * @alias getLogo
14
+ * @param {number} group - The id of the group.
15
+ * @param {GroupIconSize=} [size=150x150] - The size of the logo.
16
+ * @param {boolean=} [circular=false] - Get the circular version of the logo.
17
+ * @param {GroupIconFormat=} [format=Png] - The file format of the logo.
18
+ * @returns {Promise<string>}
19
+ * @example const noblox = require("noblox.js")
20
+ * const logo = await noblox.getLogo(1)
21
+ **/
22
+
23
+ // Define
24
+ function getLogo (group, size, circular, format) {
25
+ const httpOpt = {
26
+ url: '//thumbnails.roblox.com/v1/groups/icons',
27
+ options: {
28
+ qs: {
29
+ groupIds: group,
30
+ size: size || '150x150',
31
+ format: format || 'Png',
32
+ isCircular: circular
33
+ },
34
+ json: true,
35
+ resolveWithFullResponse: true
36
+ }
37
+ }
38
+ return http(httpOpt)
39
+ .then(function (res) {
40
+ if (res.statusCode !== 200) {
41
+ throw new RobloxAPIError(res)
42
+ }
43
+
44
+ const thumbnailData = res.body.data[0]
45
+
46
+ if (thumbnailData.state !== 'Completed') {
47
+ throw new Error('The requested image has not been approved. Status: ' + thumbnailData.state)
48
+ }
49
+
50
+ return thumbnailData.imageUrl
51
+ })
52
+ }
53
+
54
+ exports.func = function (args) {
55
+ return getLogo(args.group)
56
+ }
@@ -0,0 +1,120 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const { thumbnail: settings } = require('../../settings.json')
4
+ const RobloxAPIError = require('../util/apiError.js')
5
+
6
+ // Args
7
+ exports.required = ['userIds']
8
+ exports.optional = ['size', 'format', 'isCircular', 'cropType', 'retryCount']
9
+
10
+ // Variables
11
+ const eligibleSizes = {
12
+ body: {
13
+ sizes: ['30x30', '48x48', '60x60', '75x75', '100x100', '110x110', '140x140', '150x150', '150x200', '180x180', '250x250', '352x352', '420x420', '720x720'],
14
+ endpoint: 'avatar'
15
+ },
16
+ bust: {
17
+ sizes: ['48x48', '50x50', '60x60', '75x75', '100x100', '150x150', '180x180', '352x352', '420x420'],
18
+ endpoint: 'avatar-bust'
19
+ },
20
+ headshot: {
21
+ sizes: ['48x48', '50x50', '60x60', '75x75', '100x100', '110x110', '150x150', '180x180', '352x352', '420x420', '720x720'],
22
+ endpoint: 'avatar-headshot'
23
+ }
24
+ }
25
+
26
+ // Docs
27
+ /**
28
+ * ✅ Get a user's thumbnail.
29
+ * @category User
30
+ * @alias getPlayerThumbnail
31
+ * @param {number | Array<number>} userIds - The id or an array ids of thumbnails to be retrieved; 100
32
+ * @param {number | string=} [size=720x720] - The [size of the image to be returned]{@link https://noblox.js.org/thumbnailSizes.png}; defaults highest resolution
33
+ * @param {'png' | 'jpeg'=} [format=png] - The file format of the returned thumbnails
34
+ * @param {boolean=} [isCircular=false] - Return the circular version of the thumbnails
35
+ * @param {'Body' | 'Bust' | 'Headshot'=} [cropType=Body] - The style of thumbnail that will be returned
36
+ * @returns {Promise<PlayerThumbnailData[]>}
37
+ * @example const noblox = require("noblox.js")
38
+ * let thumbnail_default = await noblox.getPlayerThumbnail(2416399685)
39
+ * let thumbnail_circHeadshot = await noblox.getPlayerThumbnail(2416399685, 420, "png", true, "Headshot")
40
+ * let thumbnails_body = await noblox.getPlayerThumbnail([2416399685, 234567, 345678], "150x200", "jpeg", false, "Body")
41
+ **/
42
+
43
+ // Define
44
+ function getPlayerThumbnail (userIds, size, format = 'png', isCircular = false, cropType = 'body', retryCount = settings.maxRetries) {
45
+ // Validate userIds
46
+ if (Array.isArray(userIds)) {
47
+ if (userIds.some(isNaN)) {
48
+ throw new Error('userIds must be a number or an array of numbers')
49
+ }
50
+ userIds = [...new Set(userIds)] // get rid of duplicates, endpoint response does this anyway
51
+ if (userIds.length > 100) {
52
+ throw new Error(`too many userIds provided (${userIds.length}); maximum 100`)
53
+ }
54
+ } else {
55
+ if (isNaN(userIds)) {
56
+ throw new Error('userId is not a number')
57
+ }
58
+ userIds = [userIds]
59
+ }
60
+
61
+ // Validate cropType
62
+ cropType = cropType.toLowerCase()
63
+ if (!Object.keys(eligibleSizes).includes(cropType)) {
64
+ throw new Error(`Invalid cropping type provided: ${cropType} | Use: ${Object.keys(eligibleSizes).join(', ')}`)
65
+ }
66
+ const { sizes, endpoint } = eligibleSizes[cropType]
67
+
68
+ // Validate size
69
+ size = size || sizes[sizes.length - 1]
70
+ if (typeof size === 'number') {
71
+ size = `${size}x${size}`
72
+ }
73
+ if (!sizes.includes(size)) {
74
+ throw new Error(`Invalid size parameter provided: ${size} | [${cropType.toUpperCase()}] Use: ${sizes.join(', ')}`)
75
+ }
76
+
77
+ // Validate format
78
+ if (format.toLowerCase() !== 'png' && format.toLowerCase() !== 'jpeg') {
79
+ throw new Error(`Invalid image type provided: ${format} | Use: png, jpeg`)
80
+ }
81
+
82
+ return http({
83
+ url: `https://thumbnails.roblox.com/v1/users/${endpoint}?userIds=${userIds.join(',')}&size=${size}&format=${format}&isCircular=${!!isCircular}`,
84
+ options: {
85
+ resolveWithFullResponse: true,
86
+ followRedirect: true
87
+ }
88
+ })
89
+ .then(async (res) => {
90
+ let { data } = JSON.parse(res.body)
91
+ if (res.statusCode === 200) {
92
+ if (retryCount > 0) {
93
+ const pendingThumbnails = data.filter(obj => { return obj.state === 'Pending' }).map(obj => obj.targetId) // Get 'Pending' thumbnails as array of userIds
94
+ if (pendingThumbnails.length > 0) {
95
+ await timeout(settings.retryDelay) // small delay helps cache populate on Roblox's end; default 500ms
96
+ const updatedPending = await getPlayerThumbnail(pendingThumbnails, size, format, isCircular, cropType, --retryCount) // Recursively retry for # of maxRetries attempts; default 2
97
+ data = data.map(obj => updatedPending.find(o => o.targetId === obj.targetId) || obj) // Update primary array's values
98
+ }
99
+ }
100
+ data = data.map(obj => {
101
+ if (obj.state !== 'Completed') {
102
+ const settingsUrl = settings.failedUrl[obj.state.toLowerCase()] // user defined settings.json default image URL for blocked or pending thumbnails; default ""
103
+ obj.imageUrl = settingsUrl || `https://noblox.js.org/moderatedThumbnails/moderatedThumbnail_${size}.png`
104
+ }
105
+ return obj
106
+ })
107
+ return data
108
+ } else {
109
+ throw new RobloxAPIError(res)
110
+ }
111
+ })
112
+ }
113
+
114
+ function timeout (ms) {
115
+ return new Promise(resolve => { setTimeout(resolve, ms) })
116
+ }
117
+
118
+ exports.func = function ({ userIds, size, format, isCircular, cropType, retryCount }) {
119
+ return getPlayerThumbnail(userIds, size, format, isCircular, cropType, retryCount)
120
+ }