noblox.ts 4.10.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of noblox.ts might be problematic. Click here for more details.
- package/.eslintrc.js +21 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- package/.github/workflows/doc-publish.yml +33 -0
- package/.github/workflows/npmpublish.yml +70 -0
- package/.travis.yml +13 -0
- package/CODE_OF_CONDUCT.md +76 -0
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/examples/cleanPlayers.js +130 -0
- package/examples/cleanWall.js +110 -0
- package/examples/revertRanks.js +100 -0
- package/examples/savePlayers.js +119 -0
- package/examples/saveWall.js +96 -0
- package/img/moderatedThumbnails/moderatedThumbnail_100x100.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_110x110.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_140x140.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_150x150.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_150x200.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_180x180.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_250x250.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_30x30.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_352x352.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_420x420.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_48x48.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_50x50.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_60x60.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_720x720.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_75x75.png +0 -0
- package/img/noblox-js-small.png +0 -0
- package/img/noblox-js.png +0 -0
- package/img/thumbnailSizes.png +0 -0
- package/jsDocsConfig.json +55 -0
- package/lib/accountinformation/getUserSocialLinks.js +42 -0
- package/lib/accountsettings/block.js +58 -0
- package/lib/accountsettings/unblock.js +58 -0
- package/lib/asset/deleteFromInventory.js +69 -0
- package/lib/asset/getGamePassProductInfo.js +51 -0
- package/lib/asset/getProductInfo.js +56 -0
- package/lib/asset/uploadAnimation.js +103 -0
- package/lib/asset/uploadItem.js +83 -0
- package/lib/asset/uploadModel.js +90 -0
- package/lib/avatar/avatarRules.js +38 -0
- package/lib/avatar/currentlyWearing.js +32 -0
- package/lib/avatar/getAvatar.js +35 -0
- package/lib/avatar/getCurrentAvatar.js +37 -0
- package/lib/avatar/getRecentItems.js +37 -0
- package/lib/avatar/outfitDetails.js +32 -0
- package/lib/avatar/outfits.js +37 -0
- package/lib/avatar/redrawAvatar.js +48 -0
- package/lib/avatar/removeAssetId.js +55 -0
- package/lib/avatar/setAvatarBodyColors.js +60 -0
- package/lib/avatar/setAvatarScales.js +60 -0
- package/lib/avatar/setPlayerAvatarType.js +50 -0
- package/lib/avatar/setWearingAssets.js +50 -0
- package/lib/avatar/wearAssetId.js +55 -0
- package/lib/badges/getAwardedTimestamps.js +52 -0
- package/lib/badges/getBadgeInfo.js +43 -0
- package/lib/badges/getGameBadges.js +62 -0
- package/lib/badges/getPlayerBadges.js +28 -0
- package/lib/badges/updateBadgeInfo.js +80 -0
- package/lib/cache/add.js +14 -0
- package/lib/cache/addIf.js +26 -0
- package/lib/cache/clear.js +8 -0
- package/lib/cache/get.js +28 -0
- package/lib/cache/index.js +17 -0
- package/lib/cache/new.js +12 -0
- package/lib/cache/wrap.js +25 -0
- package/lib/chat/addUsersToConversation.js +61 -0
- package/lib/chat/chatSettings.js +33 -0
- package/lib/chat/getChatMessages.js +40 -0
- package/lib/chat/getConversations.js +43 -0
- package/lib/chat/getRolloutSettings.js +35 -0
- package/lib/chat/getUnreadConversationCount.js +33 -0
- package/lib/chat/getUnreadMessages.js +38 -0
- package/lib/chat/getUserConversations.js +37 -0
- package/lib/chat/markChatAsRead.js +52 -0
- package/lib/chat/markChatAsSeen.js +50 -0
- package/lib/chat/multiGetLatestMessages.js +37 -0
- package/lib/chat/onNewConversation.js +50 -0
- package/lib/chat/onNewMessage.js +53 -0
- package/lib/chat/onNewMessageBySelf.js +50 -0
- package/lib/chat/onUserOnline.js +50 -0
- package/lib/chat/onUserTyping.js +54 -0
- package/lib/chat/removeFromGroupConversation.js +62 -0
- package/lib/chat/renameGroupConversation.js +57 -0
- package/lib/chat/sendChatMessage.js +57 -0
- package/lib/chat/setChatUserTyping.js +61 -0
- package/lib/chat/start121Conversation.js +50 -0
- package/lib/chat/startCloudEditConversation.js +50 -0
- package/lib/chat/startGroupConversation.js +62 -0
- package/lib/client/onNotification.js +70 -0
- package/lib/client/setAPIKey.js +18 -0
- package/lib/client/setCookie.js +38 -0
- package/lib/datastores/deleteDatastoreEntry.js +66 -0
- package/lib/datastores/getDatastoreEntry.js +98 -0
- package/lib/datastores/getDatastoreEntryVersions.js +83 -0
- package/lib/datastores/getDatastoreKeys.js +73 -0
- package/lib/datastores/getDatastores.js +72 -0
- package/lib/datastores/incrementDatastoreEntry.js +93 -0
- package/lib/datastores/setDatastoreEntry.js +90 -0
- package/lib/develop/canManage.js +44 -0
- package/lib/develop/configureItem.js +142 -0
- package/lib/develop/updateUniverse.js +53 -0
- package/lib/develop/updateUniverseAccess.js +55 -0
- package/lib/economy/buy.js +99 -0
- package/lib/economy/getGroupFunds.js +43 -0
- package/lib/economy/getGroupRevenueSummary.js +48 -0
- package/lib/economy/getGroupTransactions.js +32 -0
- package/lib/economy/getResaleData.js +54 -0
- package/lib/economy/getResellers.js +35 -0
- package/lib/economy/getUserTransactions.js +34 -0
- package/lib/economy/onGroupTransaction.js +74 -0
- package/lib/friends/acceptFriendRequest.js +59 -0
- package/lib/friends/declineAllFriendRequests.js +57 -0
- package/lib/friends/declineFriendRequest.js +59 -0
- package/lib/friends/getFollowers.js +61 -0
- package/lib/friends/getFollowings.js +61 -0
- package/lib/friends/getFriendRequests.js +56 -0
- package/lib/friends/getFriends.js +53 -0
- package/lib/friends/onFriendRequest.js +58 -0
- package/lib/friends/removeFriend.js +58 -0
- package/lib/friends/sendFriendRequest.js +59 -0
- package/lib/friends/unfollow.js +58 -0
- package/lib/games/addDeveloperProduct.js +65 -0
- package/lib/games/checkDeveloperProductName.js +39 -0
- package/lib/games/configureGamePass.js +146 -0
- package/lib/games/getDeveloperProducts.js +51 -0
- package/lib/games/getGameInstances.js +31 -0
- package/lib/games/getGamePasses.js +39 -0
- package/lib/games/getGameRevenue.js +49 -0
- package/lib/games/getGameSocialLinks.js +45 -0
- package/lib/games/getGroupGames.js +30 -0
- package/lib/games/getPlaceInfo.js +48 -0
- package/lib/games/getUniverseInfo.js +51 -0
- package/lib/games/updateDeveloperProduct.js +69 -0
- package/lib/groups/changeRank.js +59 -0
- package/lib/groups/deleteWallPost.js +64 -0
- package/lib/groups/deleteWallPostsByUser.js +59 -0
- package/lib/groups/demote.js +25 -0
- package/lib/groups/exile.js +59 -0
- package/lib/groups/getAuditLog.js +67 -0
- package/lib/groups/getGroup.js +57 -0
- package/lib/groups/getGroupSocialLinks.js +44 -0
- package/lib/groups/getGroups.js +88 -0
- package/lib/groups/getJoinRequest.js +52 -0
- package/lib/groups/getJoinRequests.js +58 -0
- package/lib/groups/getPlayers.js +108 -0
- package/lib/groups/getRankInGroup.js +52 -0
- package/lib/groups/getRankNameInGroup.js +52 -0
- package/lib/groups/getRole.js +64 -0
- package/lib/groups/getRolePermissions.js +51 -0
- package/lib/groups/getRoles.js +56 -0
- package/lib/groups/getShout.js +49 -0
- package/lib/groups/getWall.js +59 -0
- package/lib/groups/groupPayout.js +103 -0
- package/lib/groups/handleJoinRequest.js +60 -0
- package/lib/groups/leaveGroup.js +60 -0
- package/lib/groups/onAuditLog.js +62 -0
- package/lib/groups/onJoinRequest.js +63 -0
- package/lib/groups/onJoinRequestHandle.js +105 -0
- package/lib/groups/onShout.js +57 -0
- package/lib/groups/onWallPost.js +58 -0
- package/lib/groups/promote.js +25 -0
- package/lib/groups/searchGroups.js +32 -0
- package/lib/groups/setGroupDescription.js +65 -0
- package/lib/groups/setGroupName.js +66 -0
- package/lib/groups/setRank.js +79 -0
- package/lib/groups/shout.js +65 -0
- package/lib/index.js +30 -0
- package/lib/internal/levelOneCopy.js +16 -0
- package/lib/internal/queue.js +61 -0
- package/lib/internal/timeout.js +30 -0
- package/lib/internal/wrap.js +78 -0
- package/lib/inventory/getCollectibles.js +31 -0
- package/lib/inventory/getInventory.js +32 -0
- package/lib/inventory/getInventoryById.js +31 -0
- package/lib/inventory/getOwnership.js +54 -0
- package/lib/inventory/getUAIDs.js +47 -0
- package/lib/itemconfiguration/getGroupAssets.js +32 -0
- package/lib/options.js +26 -0
- package/lib/party/onPartyDeleted.js +53 -0
- package/lib/party/onPartyInvite.js +53 -0
- package/lib/party/onPartyJoinedGame.js +53 -0
- package/lib/party/onPartyLeftGame.js +53 -0
- package/lib/party/onPartySelfJoined.js +53 -0
- package/lib/party/onPartySelfLeft.js +53 -0
- package/lib/party/onPartyUserJoined.js +53 -0
- package/lib/party/onPartyUserLeft.js +53 -0
- package/lib/premiumfeatures/getPremium.js +51 -0
- package/lib/presence/getPresences.js +63 -0
- package/lib/privatemessages/getMessages.js +60 -0
- package/lib/privatemessages/message.js +80 -0
- package/lib/privatemessages/onMessage.js +88 -0
- package/lib/thumbnails/getLogo.js +60 -0
- package/lib/thumbnails/getPlayerThumbnail.js +121 -0
- package/lib/thumbnails/getThumbnails.js +93 -0
- package/lib/trades/acceptTrade.js +58 -0
- package/lib/trades/canTradeWith.js +48 -0
- package/lib/trades/counterTrade.js +84 -0
- package/lib/trades/declineTrade.js +58 -0
- package/lib/trades/getTradeInfo.js +52 -0
- package/lib/trades/getTrades.js +37 -0
- package/lib/trades/sendTrade.js +82 -0
- package/lib/users/getBlurb.js +36 -0
- package/lib/users/getIdFromUsername.js +53 -0
- package/lib/users/getPlayerInfo.js +100 -0
- package/lib/users/getUsernameFromId.js +44 -0
- package/lib/users/onBlurbChange.js +46 -0
- package/lib/util/clearSession.js +32 -0
- package/lib/util/generalRequest.js +61 -0
- package/lib/util/getAction.js +45 -0
- package/lib/util/getCurrentUser.js +44 -0
- package/lib/util/getGeneralToken.js +52 -0
- package/lib/util/getHash.js +29 -0
- package/lib/util/getInputs.js +37 -0
- package/lib/util/getPageResults.js +89 -0
- package/lib/util/getSenderUserId.js +30 -0
- package/lib/util/getSession.js +38 -0
- package/lib/util/getVerification.js +60 -0
- package/lib/util/getVerificationInputs.js +31 -0
- package/lib/util/http.js +110 -0
- package/lib/util/jar.js +24 -0
- package/lib/util/refreshCookie.js +52 -0
- package/lib/util/relog.js +81 -0
- package/lib/util/setOptions.js +54 -0
- package/lib/util/shortPoll.js +102 -0
- package/lib/util/threaded.js +80 -0
- package/package.json +94 -0
- package/postinstall.js +1 -0
- package/settings.json +107 -0
- package/test/accountinformation.test.js +27 -0
- package/test/accountsettings.test.js +27 -0
- package/test/asset.test.js +81 -0
- package/test/assets/Great-White-Shark-Fin.rbxm +0 -0
- package/test/assets/KeyframeSequence.rbxm +0 -0
- package/test/avatar.test.js +164 -0
- package/test/badges.test.js +96 -0
- package/test/chat.test.js +104 -0
- package/test/datastore.test.js +105 -0
- package/test/develop.test.js +53 -0
- package/test/economy.test.js +137 -0
- package/test/friends.test.js +128 -0
- package/test/games.test.js +212 -0
- package/test/groups.test.js +311 -0
- package/test/inventory.test.js +98 -0
- package/test/itemconfiguration.test.js +24 -0
- package/test/premiumfeatures.test.js +17 -0
- package/test/presence.test.js +25 -0
- package/test/privatemessages.test.js +33 -0
- package/test/thumbnails.test.js +53 -0
- package/test/users.test.js +68 -0
- package/tutorials/Authentication.md +75 -0
- package/tutorials/Event Emitters.md +26 -0
- package/tutorials/Promises.md +86 -0
- package/tutorials/VPS Authentication.md +72 -0
- package/typings/index.d.ts +2525 -0
- package/typings/jsDocs.ts +1927 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const getGeneralToken = require('../util/getGeneralToken.js').func
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['assetId']
|
7
|
+
exports.optional = ['jar']
|
8
|
+
|
9
|
+
// Docs
|
10
|
+
/**
|
11
|
+
* 🔐 Removes an asset from the authenticated user's inventory; throws an error if the item is not owned.
|
12
|
+
* @category Asset
|
13
|
+
* @alias deleteFromInventory
|
14
|
+
* @param {number} assetId - The id of the asset.
|
15
|
+
* @returns {Promise<void>}
|
16
|
+
* @example const noblox = require("noblox.js")
|
17
|
+
* // Login using your cookie
|
18
|
+
* await noblox.deleteFromInventory(144075659)
|
19
|
+
**/
|
20
|
+
|
21
|
+
// Define
|
22
|
+
function deleteFromInventory (jar, assetId, xcsrf) {
|
23
|
+
return new Promise((resolve, reject) => {
|
24
|
+
const httpOpt = {
|
25
|
+
url: 'https://www.roblox.com/asset/delete-from-inventory',
|
26
|
+
options: {
|
27
|
+
method: 'POST',
|
28
|
+
resolveWithFullResponse: true,
|
29
|
+
body: `assetId=${assetId}`,
|
30
|
+
jar: jar,
|
31
|
+
headers: {
|
32
|
+
'X-CSRF-TOKEN': xcsrf,
|
33
|
+
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
return http(httpOpt)
|
39
|
+
.then(function (res) {
|
40
|
+
const responseData = typeof res.body === 'string' ? JSON.parse(res.body) : res.body
|
41
|
+
// Roblox likes to error here with 200 status codes too with inconsistency
|
42
|
+
if (res.statusCode === 200) {
|
43
|
+
let error = 'An unknown error has occurred.'
|
44
|
+
if (responseData && !responseData.isValid) {
|
45
|
+
error = responseData.error
|
46
|
+
reject(new Error(error))
|
47
|
+
} else if (responseData && responseData.isValid) {
|
48
|
+
resolve()
|
49
|
+
}
|
50
|
+
} else {
|
51
|
+
let error = 'An unknown error has occurred.'
|
52
|
+
if (responseData && responseData.errors) {
|
53
|
+
error = responseData.errors.map((e) => e.message).join('\n')
|
54
|
+
}
|
55
|
+
reject(new Error(error))
|
56
|
+
}
|
57
|
+
})
|
58
|
+
.catch(error => reject(error))
|
59
|
+
})
|
60
|
+
}
|
61
|
+
|
62
|
+
// Define
|
63
|
+
exports.func = function (args) {
|
64
|
+
const jar = args.jar
|
65
|
+
return getGeneralToken({ jar: jar })
|
66
|
+
.then(function (xcsrf) {
|
67
|
+
return deleteFromInventory(jar, args.assetId, xcsrf)
|
68
|
+
})
|
69
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const cache = require('../cache')
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['gamepass']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* ✅ Get the info of an gamepass.
|
11
|
+
* @category Asset
|
12
|
+
* @param {number} gamePassId - The id of the asset.
|
13
|
+
* @returns {Promise<GamePassProductInfo>}
|
14
|
+
* @example const noblox = require("noblox.js")
|
15
|
+
* const gamePassInfo = await noblox.getGamePassProductInfo(2919875)
|
16
|
+
**/
|
17
|
+
|
18
|
+
// Define
|
19
|
+
function getGamePassProductInfo (gamepass) {
|
20
|
+
return new Promise((resolve, reject) => {
|
21
|
+
const httpOpt = {
|
22
|
+
url: `//apis.roblox.com/game-passes/v1/game-passes/${gamepass}/product-info`,
|
23
|
+
options: {
|
24
|
+
resolveWithFullResponse: true,
|
25
|
+
method: 'GET'
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
return http(httpOpt)
|
30
|
+
.then(function (res) {
|
31
|
+
const data = JSON.parse(res.body)
|
32
|
+
|
33
|
+
if (res.statusCode === 200) {
|
34
|
+
resolve(data)
|
35
|
+
} else {
|
36
|
+
const errors = data.errors.map((e) => e.message)
|
37
|
+
|
38
|
+
reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
|
39
|
+
}
|
40
|
+
})
|
41
|
+
.catch(error => reject(error))
|
42
|
+
})
|
43
|
+
}
|
44
|
+
|
45
|
+
exports.func = function (args) {
|
46
|
+
const gamepass = args.gamepass
|
47
|
+
|
48
|
+
return cache.wrap('GamePassProduct', gamepass, function () {
|
49
|
+
return getGamePassProductInfo(gamepass)
|
50
|
+
})
|
51
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const cache = require('../cache')
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['asset']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* ✅ Get the info of an asset.
|
11
|
+
* @category Asset
|
12
|
+
* @param {number} assetId - The id of the asset.
|
13
|
+
* @returns {Promise<ProductInfo>}
|
14
|
+
* @example const noblox = require("noblox.js")
|
15
|
+
* const productInfo = await noblox.getProductInfo(1117747196)
|
16
|
+
**/
|
17
|
+
|
18
|
+
// Define
|
19
|
+
function getProductInfo (asset) {
|
20
|
+
return new Promise((resolve, reject) => {
|
21
|
+
const httpOpt = {
|
22
|
+
url: `//economy.roblox.com/v2/assets/${asset}/details`,
|
23
|
+
options: {
|
24
|
+
resolveWithFullResponse: true,
|
25
|
+
method: 'GET'
|
26
|
+
}
|
27
|
+
}
|
28
|
+
return http(httpOpt)
|
29
|
+
.then(function (res) {
|
30
|
+
if (res.statusCode === 200) {
|
31
|
+
resolve(JSON.parse(res.body))
|
32
|
+
} else {
|
33
|
+
// Sourced from: https://stackoverflow.com/a/32278428
|
34
|
+
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)
|
35
|
+
|
36
|
+
const body = isAnObject(res.body) ? JSON.parse(res.body) : {}
|
37
|
+
if (body.errors && body.errors.length > 0) {
|
38
|
+
const errors = body.errors.map((e) => {
|
39
|
+
return e.message
|
40
|
+
})
|
41
|
+
reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
|
42
|
+
} else {
|
43
|
+
reject(new Error(`${res.statusCode} ${res.body}`))
|
44
|
+
}
|
45
|
+
}
|
46
|
+
})
|
47
|
+
.catch(error => reject(error))
|
48
|
+
})
|
49
|
+
}
|
50
|
+
|
51
|
+
exports.func = function (args) {
|
52
|
+
const asset = args.asset
|
53
|
+
return cache.wrap('Product', asset, function () {
|
54
|
+
return getProductInfo(asset)
|
55
|
+
})
|
56
|
+
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const getGeneralToken = require('../util/getGeneralToken').func
|
4
|
+
const configureItem = require('../develop/configureItem.js').func
|
5
|
+
|
6
|
+
// Args
|
7
|
+
exports.required = ['data']
|
8
|
+
exports.optional = ['itemOptions', 'assetId', 'jar']
|
9
|
+
|
10
|
+
// Docs
|
11
|
+
/**
|
12
|
+
* 🔐 Upload an animation, either as a new asset or by overwriting an existing animation.
|
13
|
+
* @category Asset
|
14
|
+
* @alias uploadAnimation
|
15
|
+
* @param {string | Stream} data - The rbxm file containing the KeyframeSequence.
|
16
|
+
* @param {object=} itemOptions - The options for the upload. Only optional if assetId is not provided.
|
17
|
+
* @param {string=} itemOptions.name - The name of the animation.
|
18
|
+
* @param {string=} itemOptions.description - The description for the animation.
|
19
|
+
* @param {boolean=} itemOptions.copyLocked - If the animation is copy-locked.
|
20
|
+
* @param {boolean=} itemOptions.allowComments - If comments are allowed.
|
21
|
+
* @param {number=} itemOptions.groupId - The group to upload the animation to. This is ignored if the assetId is provided.
|
22
|
+
* @param {number=} assetId - An existing assetId to overwrite.
|
23
|
+
* @returns {Promise<number>}
|
24
|
+
* @example const noblox = require("noblox.js")
|
25
|
+
* const fs = require("fs")
|
26
|
+
* // Login using your cookie
|
27
|
+
* const assetId = await noblox.uploadAnimation(fs.readFileSync("./KeyframeSequence.rbxm"), {
|
28
|
+
* name: "A cool animation",
|
29
|
+
* description: "This is a very cool animation",
|
30
|
+
* copyLocked: false, //The asset is allowed to be copied.
|
31
|
+
* allowComments: false
|
32
|
+
* }, 7132858975)
|
33
|
+
**/
|
34
|
+
|
35
|
+
// Define
|
36
|
+
function upload (data, itemOptions, assetId, jar, token) {
|
37
|
+
const httpOpt = {
|
38
|
+
url: assetId ? `//www.roblox.com/ide/publish/uploadexistinganimation?assetID=${assetId}&isGamesAsset=False` : '//www.roblox.com/ide/publish/uploadnewanimation?AllID=1',
|
39
|
+
options: {
|
40
|
+
resolveWithFullResponse: true,
|
41
|
+
method: 'POST',
|
42
|
+
jar: jar,
|
43
|
+
body: data,
|
44
|
+
headers: {
|
45
|
+
'X-CSRF-TOKEN': token,
|
46
|
+
'Content-Type': 'application/xml',
|
47
|
+
'User-Agent': 'RobloxStudio/WinInet RobloxApp/0.483.1.425021 (GlobalDist; RobloxDirectDownload)'
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
if (!assetId && itemOptions) {
|
53
|
+
const copyLocked = itemOptions.copyLocked
|
54
|
+
const allowComments = itemOptions.allowComments
|
55
|
+
httpOpt.url += '&assetTypeName=Animation&genreTypeId=1&name=' +
|
56
|
+
itemOptions.name +
|
57
|
+
'&description=' +
|
58
|
+
(itemOptions.description || '') +
|
59
|
+
'&ispublic=' +
|
60
|
+
(copyLocked != null ? !copyLocked : false) +
|
61
|
+
'&allowComments=' +
|
62
|
+
(allowComments != null ? allowComments : true) +
|
63
|
+
'&groupId=' +
|
64
|
+
(itemOptions.groupId || '')
|
65
|
+
} else if (!assetId) {
|
66
|
+
throw new Error('ItemOptions is required for new assets.')
|
67
|
+
}
|
68
|
+
|
69
|
+
return http(httpOpt)
|
70
|
+
.then(function (res) {
|
71
|
+
if (res.statusCode === 200) {
|
72
|
+
const resultId = assetId || Number(res.body)
|
73
|
+
|
74
|
+
if (assetId && itemOptions) {
|
75
|
+
const copyLocked = itemOptions.copyLocked
|
76
|
+
const allowComments = itemOptions.allowComments
|
77
|
+
|
78
|
+
return configureItem({
|
79
|
+
id: resultId,
|
80
|
+
name: itemOptions.name,
|
81
|
+
description: itemOptions.description,
|
82
|
+
enableComments: (allowComments != null ? allowComments : true),
|
83
|
+
sellForRobux: (copyLocked != null ? !copyLocked : false)
|
84
|
+
}).then(function () {
|
85
|
+
return resultId
|
86
|
+
})
|
87
|
+
} else {
|
88
|
+
return resultId
|
89
|
+
}
|
90
|
+
} else {
|
91
|
+
throw new Error('Animation upload failed, confirm that all item options, asset options, and upload data are valid.')
|
92
|
+
}
|
93
|
+
})
|
94
|
+
}
|
95
|
+
|
96
|
+
exports.func = function (args) {
|
97
|
+
const jar = args.jar
|
98
|
+
return getGeneralToken({
|
99
|
+
jar
|
100
|
+
}).then(function (token) {
|
101
|
+
return upload(args.data, args.itemOptions, args.assetId, args.jar, token)
|
102
|
+
})
|
103
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const getVerification = require('../util/getVerification.js').func
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['name', 'assetType', 'file']
|
7
|
+
exports.optional = ['groupId', 'jar']
|
8
|
+
|
9
|
+
// Docs
|
10
|
+
/**
|
11
|
+
* 🔐 Upload an item.
|
12
|
+
* @category Asset
|
13
|
+
* @alias uploadItem
|
14
|
+
* @param {string} name - The name of the asset.
|
15
|
+
* @param {number} assetType - The [id for the asset type]{@link https://developer.roblox.com/en-us/api-reference/enum/AssetType}.
|
16
|
+
* @param {ReadStream} file - The read stream for the asset being uploaded.
|
17
|
+
* @param {number=} groupId - The group to upload the asset to.
|
18
|
+
* @returns {Promise<UploadItemResponse>}
|
19
|
+
* @example const noblox = require("noblox.js")
|
20
|
+
* const fs = require("fs")
|
21
|
+
* // Login using your cookie
|
22
|
+
* await noblox.uploadItem("A cool decal.", 13, fs.createReadStream("./Image.png"))
|
23
|
+
**/
|
24
|
+
|
25
|
+
// Define
|
26
|
+
function uploadItem (jar, file, name, assetType, groupId) {
|
27
|
+
return new Promise((resolve, reject) => {
|
28
|
+
return getVerification({
|
29
|
+
url: 'https://www.roblox.com/build/upload',
|
30
|
+
options: {
|
31
|
+
jar: jar
|
32
|
+
}
|
33
|
+
}).then(function (ver) {
|
34
|
+
const data = {
|
35
|
+
name: name,
|
36
|
+
assetTypeId: assetType,
|
37
|
+
groupId: groupId || '',
|
38
|
+
__RequestVerificationToken: ver.inputs.__RequestVerificationToken,
|
39
|
+
file: {
|
40
|
+
value: file,
|
41
|
+
options: {
|
42
|
+
filename: 'Image.png',
|
43
|
+
contentType: 'image/png'
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
return http({
|
48
|
+
url: '//www.roblox.com/build/upload',
|
49
|
+
options: {
|
50
|
+
method: 'POST',
|
51
|
+
verification: ver.header,
|
52
|
+
formData: data,
|
53
|
+
resolveWithFullResponse: true,
|
54
|
+
jar: jar
|
55
|
+
}
|
56
|
+
}).then(function (res) {
|
57
|
+
if (res.statusCode === 302) {
|
58
|
+
const location = res.headers.location
|
59
|
+
const errMsg = location.match('uploadedId=(.*)$')
|
60
|
+
const match = location.match(/\d+$/)
|
61
|
+
if (match) {
|
62
|
+
const id = parseInt(match[0], 10)
|
63
|
+
if (location.indexOf('/build/upload') === -1) {
|
64
|
+
reject(new Error('Unknown redirect: ' + location))
|
65
|
+
}
|
66
|
+
resolve(id)
|
67
|
+
} else if (errMsg) {
|
68
|
+
reject(new Error('Upload error: ' + decodeURI(errMsg[1])))
|
69
|
+
} else {
|
70
|
+
reject(new Error('Match error. Original: ' + location))
|
71
|
+
}
|
72
|
+
} else {
|
73
|
+
reject(new Error('Unknown upload error'))
|
74
|
+
}
|
75
|
+
})
|
76
|
+
})
|
77
|
+
.catch(error => reject(error))
|
78
|
+
})
|
79
|
+
}
|
80
|
+
|
81
|
+
exports.func = function (args) {
|
82
|
+
return uploadItem(args.jar, args.file, args.name, args.assetType, args.groupId)
|
83
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const getGeneralToken = require('../util/getGeneralToken').func
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['data']
|
7
|
+
exports.optional = ['itemOptions', 'assetId', 'jar']
|
8
|
+
|
9
|
+
// Docs
|
10
|
+
/**
|
11
|
+
* 🔐 Upload a model.
|
12
|
+
* @category Asset
|
13
|
+
* @alias uploadModel
|
14
|
+
* @param {string | Stream} data - The model data.
|
15
|
+
* @param {object=} itemOptions - The options for the upload.
|
16
|
+
* @param {string=} itemOptions.name - The name of the model.
|
17
|
+
* @param {string=} itemOptions.description - The description for the model.
|
18
|
+
* @param {boolean=} itemOptions.copyLocked - If the model is copy-locked.
|
19
|
+
* @param {boolean=} itemOptions.allowComments - If comments are allowed.
|
20
|
+
* @param {number=} itemOptions.groupId - The group to upload the model to.
|
21
|
+
* @param {number=} assetId - An existing assetId to overwrite.
|
22
|
+
* @returns {Promise<UploadModelResponse>}
|
23
|
+
* @example const noblox = require("noblox.js")
|
24
|
+
* const fs = require("fs")
|
25
|
+
* // Login using your cookie
|
26
|
+
* noblox.uploadModel(fs.readFileSync("./model.rbxm"), {
|
27
|
+
* name: "A cool model",
|
28
|
+
* description: "This is a very cool model",
|
29
|
+
* copyLocked: false, //The asset is allowed to be copied.
|
30
|
+
* allowComments: false,
|
31
|
+
* groupId: 1
|
32
|
+
* }, 1117747196)
|
33
|
+
**/
|
34
|
+
|
35
|
+
// Define
|
36
|
+
function upload (data, itemOptions, assetId, jar, token) {
|
37
|
+
const httpOpt = {
|
38
|
+
url: '//data.roblox.com/Data/Upload.ashx?json=1&assetid=' + (assetId || 0),
|
39
|
+
options: {
|
40
|
+
resolveWithFullResponse: true,
|
41
|
+
method: 'POST',
|
42
|
+
jar: jar,
|
43
|
+
body: data,
|
44
|
+
headers: {
|
45
|
+
'X-CSRF-TOKEN': token,
|
46
|
+
'Content-Type': 'application/xml'
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
if (itemOptions) {
|
51
|
+
const copyLocked = itemOptions.copyLocked
|
52
|
+
const allowComments = itemOptions.allowComments
|
53
|
+
httpOpt.url += '&type=Model&genreTypeId=1&name=' +
|
54
|
+
itemOptions.name +
|
55
|
+
'&description=' +
|
56
|
+
(itemOptions.description || '') +
|
57
|
+
'&ispublic=' +
|
58
|
+
(copyLocked != null ? !copyLocked : false) +
|
59
|
+
'&allowComments=' +
|
60
|
+
(allowComments != null ? allowComments : true) +
|
61
|
+
'&groupId=' +
|
62
|
+
(itemOptions.groupId || '')
|
63
|
+
} else if (!assetId) {
|
64
|
+
throw new Error('ItemOptions is required for new assets.')
|
65
|
+
}
|
66
|
+
return http(httpOpt)
|
67
|
+
.then(function (res) {
|
68
|
+
if (res.statusCode === 200) {
|
69
|
+
const body = res.body
|
70
|
+
let parsed
|
71
|
+
try {
|
72
|
+
parsed = JSON.parse(body)
|
73
|
+
} catch (e) {
|
74
|
+
throw new Error('Could not parse JSON, returned body:' + body)
|
75
|
+
}
|
76
|
+
return parsed
|
77
|
+
} else {
|
78
|
+
throw new Error('Upload failed, confirm that all item options, asset options, and upload data are valid.')
|
79
|
+
}
|
80
|
+
})
|
81
|
+
}
|
82
|
+
|
83
|
+
exports.func = function (args) {
|
84
|
+
const jar = args.jar
|
85
|
+
return getGeneralToken({
|
86
|
+
jar
|
87
|
+
}).then(function (token) {
|
88
|
+
return upload(args.data, args.itemOptions, args.assetId, args.jar, token)
|
89
|
+
})
|
90
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
const http = require('../util/http.js').func
|
2
|
+
|
3
|
+
exports.optional = ['option', 'jar']
|
4
|
+
|
5
|
+
// Docs
|
6
|
+
/**
|
7
|
+
* ✅ Get the avatar rules.
|
8
|
+
* @category Avatar
|
9
|
+
* @alias avatarRules
|
10
|
+
* @param {string=} option - A specific rule to filter for.
|
11
|
+
* @returns {Promise<AvatarRules>}
|
12
|
+
* @example const noblox = require("noblox.js")
|
13
|
+
* const avatarRules = await noblox.avatarRules()
|
14
|
+
**/
|
15
|
+
|
16
|
+
exports.func = (args) => {
|
17
|
+
const jar = args.jar
|
18
|
+
const option = args.option
|
19
|
+
|
20
|
+
return http({
|
21
|
+
url: '//avatar.roblox.com/v1/avatar-rules',
|
22
|
+
options: {
|
23
|
+
method: 'GET',
|
24
|
+
jar: jar,
|
25
|
+
followRedirect: false,
|
26
|
+
resolveWithFullResponse: true
|
27
|
+
}
|
28
|
+
}).then((res) => {
|
29
|
+
if (res.statusCode === 200) {
|
30
|
+
const json = JSON.parse(res.body)
|
31
|
+
const result = (option ? json[option] : json)
|
32
|
+
|
33
|
+
return result
|
34
|
+
} else {
|
35
|
+
throw new Error('Error fetching avatar rules')
|
36
|
+
}
|
37
|
+
})
|
38
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
const http = require('../util/http.js').func
|
2
|
+
|
3
|
+
exports.required = ['userId']
|
4
|
+
|
5
|
+
// Docs
|
6
|
+
/**
|
7
|
+
* ✅ Get the assets a given user is wearing.
|
8
|
+
* @category Avatar
|
9
|
+
* @alias currentlyWearing
|
10
|
+
* @param {number} userId - The user's userId.
|
11
|
+
* @returns {Promise<AssetIdList>}
|
12
|
+
* @example const noblox = require("noblox.js")
|
13
|
+
* const wearingAssets = await noblox.currentlyWearing(1)
|
14
|
+
**/
|
15
|
+
|
16
|
+
exports.func = (args) => {
|
17
|
+
const userId = args.userId
|
18
|
+
|
19
|
+
return http({
|
20
|
+
url: '//avatar.roblox.com/v1/users/' + userId + '/currently-wearing',
|
21
|
+
options: {
|
22
|
+
method: 'GET',
|
23
|
+
resolveWithFullResponse: true
|
24
|
+
}
|
25
|
+
}).then((res) => {
|
26
|
+
if (res.statusCode === 200) {
|
27
|
+
return JSON.parse(res.body)
|
28
|
+
} else {
|
29
|
+
throw new Error('User does not exist')
|
30
|
+
}
|
31
|
+
})
|
32
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
const http = require('../util/http.js').func
|
2
|
+
|
3
|
+
exports.required = ['userId']
|
4
|
+
|
5
|
+
// Docs
|
6
|
+
/**
|
7
|
+
* ✅ Get a user's avatar.
|
8
|
+
* @category Avatar
|
9
|
+
* @alias getAvatar
|
10
|
+
* @param {number} userId - The user's userId.
|
11
|
+
* @returns {Promise<AvatarInfo>}
|
12
|
+
* @example const noblox = require("noblox.js")
|
13
|
+
* const avatar = await noblox.getAvatar(1)
|
14
|
+
**/
|
15
|
+
|
16
|
+
const getAvatar = (userId) => {
|
17
|
+
return http({
|
18
|
+
url: '//avatar.roblox.com/v1/users/' + userId + '/avatar',
|
19
|
+
options: {
|
20
|
+
method: 'GET',
|
21
|
+
resolveWithFullResponse: true
|
22
|
+
}
|
23
|
+
}).then((res) => {
|
24
|
+
if (res.statusCode === 200) {
|
25
|
+
return JSON.parse(res.body)
|
26
|
+
} else {
|
27
|
+
throw new Error('User does not exist')
|
28
|
+
}
|
29
|
+
})
|
30
|
+
}
|
31
|
+
|
32
|
+
exports.func = (args) => {
|
33
|
+
const userId = args.userId
|
34
|
+
return getAvatar(userId)
|
35
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
const http = require('../util/http.js').func
|
2
|
+
|
3
|
+
exports.optional = ['option', 'jar']
|
4
|
+
|
5
|
+
// Docs
|
6
|
+
/**
|
7
|
+
* 🔐 Gets your current avatar.
|
8
|
+
* @category Avatar
|
9
|
+
* @alias getCurrentAvatar
|
10
|
+
* @param {number=} option - The name of a parameter on the avatar.
|
11
|
+
* @returns {Promise<AvatarInfo>}
|
12
|
+
* @example const noblox = require("noblox.js")
|
13
|
+
* // Login using your cookie
|
14
|
+
* const avatar = await noblox.getCurrentAvatar()
|
15
|
+
*/
|
16
|
+
|
17
|
+
exports.func = (args) => {
|
18
|
+
const jar = args.jar
|
19
|
+
const option = args.option
|
20
|
+
|
21
|
+
return http({
|
22
|
+
url: '//avatar.roblox.com/v1/avatar',
|
23
|
+
options: {
|
24
|
+
method: 'GET',
|
25
|
+
jar: jar,
|
26
|
+
followRedirect: false,
|
27
|
+
resolveWithFullResponse: true
|
28
|
+
}
|
29
|
+
}).then((res) => {
|
30
|
+
if (res.statusCode !== 200) {
|
31
|
+
throw new Error('You are not logged in')
|
32
|
+
} else {
|
33
|
+
const json = JSON.parse(res.body)
|
34
|
+
return (option ? json[option] : json)
|
35
|
+
}
|
36
|
+
})
|
37
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
const http = require('../util/http.js').func
|
2
|
+
|
3
|
+
exports.optional = ['listType', 'jar']
|
4
|
+
|
5
|
+
// Docs
|
6
|
+
/**
|
7
|
+
* 🔐 Get assets you've recently worn.
|
8
|
+
* @category Avatar
|
9
|
+
* @alias getRecentItems
|
10
|
+
* @param {number=} listType - A type of item. Ex: Shirt, All
|
11
|
+
* @returns {Promise<AssetRecentItemsResult>}
|
12
|
+
* @example const noblox = require("noblox.js")
|
13
|
+
* // Login using your cookie
|
14
|
+
* const recentlyWorn = await noblox.getRecentItems("All")
|
15
|
+
**/
|
16
|
+
|
17
|
+
exports.func = (args) => {
|
18
|
+
const jar = args.jar
|
19
|
+
const listType = typeof (args.listType) === 'string' ? args.listType : 'All'
|
20
|
+
|
21
|
+
return http({
|
22
|
+
url: '//avatar.roblox.com/v1/recent-items/' + listType + '/list',
|
23
|
+
options: {
|
24
|
+
method: 'GET',
|
25
|
+
jar: jar,
|
26
|
+
resolveWithFullResponse: true
|
27
|
+
}
|
28
|
+
}).then((res) => {
|
29
|
+
if (res.statusCode === 401) {
|
30
|
+
throw new Error('You are not logged in')
|
31
|
+
} else if (res.statusCode === 400) {
|
32
|
+
throw new Error('Invalid list type')
|
33
|
+
} else {
|
34
|
+
return JSON.parse(res.body)
|
35
|
+
}
|
36
|
+
})
|
37
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
const http = require('../util/http.js').func
|
2
|
+
|
3
|
+
exports.required = ['outfitId']
|
4
|
+
|
5
|
+
// Docs
|
6
|
+
/**
|
7
|
+
* ✅ Get the details of an outfit.
|
8
|
+
* @category Avatar
|
9
|
+
* @alias outfitDetails
|
10
|
+
* @param {number} outfitId - The id of the outfit.
|
11
|
+
* @returns {Promise<AvatarOutfitDetails>}
|
12
|
+
* @example const noblox = require("noblox.js")
|
13
|
+
* const outfit = await noblox.outfitDetails(111)
|
14
|
+
**/
|
15
|
+
|
16
|
+
exports.func = (args) => {
|
17
|
+
const outfitId = args.outfitId
|
18
|
+
|
19
|
+
return http({
|
20
|
+
url: '//avatar.roblox.com/v1/outfits/' + outfitId + '/details',
|
21
|
+
options: {
|
22
|
+
method: 'GET',
|
23
|
+
resolveWithFullResponse: true
|
24
|
+
}
|
25
|
+
}).then((res) => {
|
26
|
+
if (res.statusCode === 200) {
|
27
|
+
return JSON.parse(res.body)
|
28
|
+
} else {
|
29
|
+
throw new Error('Outfit does not exist')
|
30
|
+
}
|
31
|
+
})
|
32
|
+
}
|