Skip to content
This repository was archived by the owner on Mar 29, 2026. It is now read-only.
Closed

Next #899

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c0a9b7a
Request forwarding for CI (#863)
Regalijan May 6, 2025
5840266
Fixes #864 (#865)
mutex-lock Jun 10, 2025
bf07f5f
Remove buy() (#867)
Regalijan Jul 29, 2025
f8f4cab
Migrate methods to RobloxAPIError class (#855)
Regalijan Jul 30, 2025
11f45ec
First attempt at new release system
Neztore Aug 1, 2025
3f36ca6
BREAKING CHANGE: Document new versioning
Neztore Aug 1, 2025
138cf4f
fix: add release branches
Neztore Aug 1, 2025
78ee589
ci: Add new release workflow
Neztore Aug 1, 2025
fbe035a
fix: Update user block/unblock endpoints (#869)
Regalijan Aug 8, 2025
6860256
feat: UserNotification Cloud API (#851)
commonly-ts Aug 8, 2025
5bb6344
feat: Add group ban methods (#872)
Regalijan Aug 8, 2025
29b53c4
fix: Update user agent per Roblox's request (#870)
Regalijan Aug 11, 2025
d026597
feat: Add getGroupPayoutEligibility (#834)
supercoolspy Aug 11, 2025
89cb726
fix: Final touches of error migration (#873)
Regalijan Aug 11, 2025
e7e83dc
Bump handlebars from 4.7.8 to 4.7.9 (#886)
dependabot[bot] Mar 27, 2026
81d3e84
Bump undici from 6.21.2 to 6.24.1 (#883)
dependabot[bot] Mar 27, 2026
e0c53f4
Bump minimatch from 3.1.2 to 3.1.5 (#881)
dependabot[bot] Mar 27, 2026
42965bb
Bump lodash from 4.17.21 to 4.17.23 (#879)
dependabot[bot] Mar 27, 2026
9821790
Bump picomatch from 2.3.1 to 2.3.2 (#885)
dependabot[bot] Mar 27, 2026
3d8bd78
Bump flatted from 3.3.3 to 3.4.2 (#884)
dependabot[bot] Mar 27, 2026
c3e9c90
feat: Implement handleJoinRequests function for batch user join reque…
realCartar Mar 27, 2026
9350d0c
Update deprecated GitHub Actions to latest versions (#889)
Neztore Mar 27, 2026
46dbb51
Switch npm publish to on dispatch only (#890)
Neztore Mar 27, 2026
81fc85a
v7.4.0 (#891)
Neztore Mar 27, 2026
d4fc3c3
Merge branch 'master' into next
Neztore Mar 27, 2026
be759c8
Update action
Neztore Mar 27, 2026
457ec39
Copy master over next (#895)
Neztore Mar 27, 2026
b9a75e8
fix: Update endpoint for getGamePasses (#875)
Regalijan Mar 29, 2026
b8c6f30
BREAKING CHANGE: Groups methods overhaul (#876)
Regalijan Mar 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ Steps to reproduce the behavior:
**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.
**Error messages**
If applicable, add error messages to help explain your problem.

**Additional context**
Add any other context about the problem here.
6 changes: 3 additions & 3 deletions .github/workflows/doc-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up node
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24

- name: Install yarn
run: npm install -g yarn
Expand Down
39 changes: 18 additions & 21 deletions .github/workflows/npmpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,30 @@ on:
pull_request:
branches:
- master
- next

push:
branches:
- master
- next

permissions:
contents: write
packages: write
id-token: write
issues: write

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up node
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24

- name: Install yarn
run: npm install -g yarn
Expand All @@ -35,23 +43,13 @@ jobs:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- name: Checkout code with ADMIN_TOKEN
if: github.event.pull_request.head.repo.full_name == github.repository
uses: actions/checkout@v2
with:
token: ${{ secrets.ADMIN_TOKEN }}

- name: Checkout code
if: github.event.pull_request.head.repo.full_name != github.repository
uses: actions/checkout@v2

- name: Prepare repository
run: git fetch --unshallow --tags
uses: actions/checkout@v4

- name: Set up node
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24

- name: Install yarn
run: npm install -g yarn
Expand All @@ -60,16 +58,15 @@ jobs:
run: yarn install --frozen-lockfile

- name: Cache node modules
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: node_modules
key: yarn-deps-${{ hashFiles('yarn.lock') }}
restore-keys: |
yarn-deps-${{ hashFiles('yarn.lock') }}

- name: Create Release
run: npx semantic-release@25.0.3
env:
token: ${{ secrets.ADMIN_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
run: |
npx auto shipit
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

29 changes: 23 additions & 6 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,44 @@ on:

jobs:
test:
permissions:
id-token: write

runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up node
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 24

- name: Install yarn
run: npm install -g yarn
- name: Enable Corepack
run: corepack enable

- name: Install dependencies
run: yarn install
run: yarn install --frozen-lockfile

- name: Lint lib/
run: yarn lint

- id: auth
name: Generate ID Token
uses: google-github-actions/auth@v2
with:
token_format: id_token
workload_identity_provider: ${{ vars.workload_identity_provider }}
service_account: ${{ vars.service_account }}
id_token_audience: "https://${{ vars.forwarder_hostname }}"
id_token_include_email: true

- name: Run tests
env:
API_KEY: ${{ secrets.API_KEY }}
COOKIE: ${{ secrets.COOKIE }}
COOKIE_2: ${{ secrets.COOKIE_2 }}
FORWARDER_HOSTNAME: ${{ vars.forwarder_hostname }}
ID_TOKEN: ${{ steps.auth.outputs.id_token }}
run: yarn test

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ This NPM package enables operations froms the [Roblox website](https://www.roblo

If you are looking for more information on how to create something like this, check out [our sister library, `noblox.js-server`](https://github.com/noblox/noblox.js-server) or [our YouTube series](https://www.youtube.com/playlist?list=PLEW4K4VqMUb_VMA3Yp9LI4gReRyVWGTnU). Keep in mind that these resources may not always be up to date, so it is **highly** encouraged that you learn to use the `noblox.js` library directly.


Note: We use the semantic release plugin. You should treat npm as the source of truth regarding package versions - the package.json version in this repository will not be up to date.
---

## Prerequisites
Expand Down
12 changes: 5 additions & 7 deletions lib/accountinformation/getUserSocialLinks.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Includes
const http = require('../util/http.js').func
const RobloxAPIError = require('../util/apiError.js')

// Args
exports.required = ['userId']
Expand All @@ -25,14 +26,11 @@ function getUserSocialLinks (userId, jar) {
resolveWithFullResponse: true
}
})
.then(({ statusCode, body }) => {
const { errors } = JSON.parse(body)
if (statusCode === 200) {
return JSON.parse(body)
} else if (statusCode === 400) {
throw new Error(`${errors[0].message} | userId: ${userId}`)
.then((res) => {
if (res.statusCode === 200) {
return JSON.parse(res.body)
} else {
throw new Error(`An unknown error occurred with getUserSocialLinks() | [${statusCode}] userId: ${userId}`)
throw new RobloxAPIError(res)
}
})
}
Expand Down
11 changes: 3 additions & 8 deletions lib/accountsettings/block.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Includes
const http = require('../util/http.js').func
const getGeneralToken = require('../util/getGeneralToken.js').func
const RobloxAPIError = require('../util/apiError.js')

// Args
exports.required = ['userId']
Expand All @@ -22,7 +23,7 @@ exports.optional = ['jar']
function block (jar, token, userId) {
return new Promise((resolve, reject) => {
const httpOpt = {
url: `//accountsettings.roblox.com/v1/users/${userId}/block`,
url: `https://apis.roblox.com/user-blocking-api/v1/users/${userId}/block-user`,
options: {
method: 'POST',
jar,
Expand All @@ -37,13 +38,7 @@ function block (jar, token, userId) {
if (res.statusCode === 200) {
resolve()
} else {
const body = JSON.parse(res.body) || {}
if (body.errors && body.errors.length > 0) {
const errors = body.errors.map((e) => {
return e.message
})
reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
}
reject(new RobloxAPIError(res))
}
})
})
Expand Down
11 changes: 3 additions & 8 deletions lib/accountsettings/unblock.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Includes
const http = require('../util/http.js').func
const getGeneralToken = require('../util/getGeneralToken.js').func
const RobloxAPIError = require('../util/apiError.js')

// Args
exports.required = ['userId']
Expand All @@ -22,7 +23,7 @@ exports.optional = ['jar']
function unblock (jar, token, userId) {
return new Promise((resolve, reject) => {
const httpOpt = {
url: `//accountsettings.roblox.com/v1/users/${userId}/unblock`,
url: `https://apis.roblox.com/user-blocking-api/v1/users/${userId}/unblock-user`,
options: {
method: 'POST',
jar,
Expand All @@ -37,13 +38,7 @@ function unblock (jar, token, userId) {
if (res.statusCode === 200) {
resolve()
} else {
const body = JSON.parse(res.body) || {}
if (body.errors && body.errors.length > 0) {
const errors = body.errors.map((e) => {
return e.message
})
reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
}
reject(new RobloxAPIError(res))
}
})
})
Expand Down
20 changes: 4 additions & 16 deletions lib/asset/deleteFromInventory.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Includes
const http = require('../util/http.js').func
const getGeneralToken = require('../util/getGeneralToken.js').func
const RobloxAPIError = require('../util/apiError.js')

// Args
exports.required = ['assetId']
Expand Down Expand Up @@ -28,30 +29,17 @@ function deleteFromInventory (jar, assetId, xcsrf) {
resolveWithFullResponse: true,
jar,
headers: {
'X-CSRF-TOKEN': xcsrf,
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
'X-CSRF-TOKEN': xcsrf
}
}
}

return http(httpOpt)
.then(function (res) {
const responseData = typeof res.body === 'string' ? JSON.parse(res.body) : res.body
// Roblox likes to error here with 200 status codes too with inconsistency
if (res.statusCode === 200) {
let error = 'An unknown error has occurred.'
if (responseData && !responseData.isValid) {
error = responseData.error
reject(new Error(error))
} else if (responseData && responseData.isValid) {
resolve()
}
resolve()
} else {
let error = 'An unknown error has occurred.'
if (responseData && responseData.errors) {
error = responseData.errors.map((e) => e.message).join('\n')
}
reject(new Error(error))
reject(new RobloxAPIError(res))
}
})
.catch(error => reject(error))
Expand Down
5 changes: 2 additions & 3 deletions lib/asset/getGamePassProductInfo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Includes
const http = require('../util/http.js').func
const cache = require('../cache')
const RobloxAPIError = require('../util/apiError.js')

// Args
exports.required = ['gamepass']
Expand Down Expand Up @@ -33,9 +34,7 @@ function getGamePassProductInfo (gamepass) {
if (res.statusCode === 200) {
resolve(data)
} else {
const errors = data.errors.map((e) => e.message)

reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
reject(new RobloxAPIError(res))
}
})
.catch(error => reject(error))
Expand Down
14 changes: 2 additions & 12 deletions lib/asset/getProductInfo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Includes
const http = require('../util/http.js').func
const cache = require('../cache')
const RobloxAPIError = require('../util/apiError.js')

// Args
exports.required = ['asset']
Expand Down Expand Up @@ -30,18 +31,7 @@ function getProductInfo (asset) {
if (res.statusCode === 200) {
resolve(JSON.parse(res.body))
} else {
// Sourced from: https://stackoverflow.com/a/32278428
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)

const body = isAnObject(res.body) ? JSON.parse(res.body) : {}
if (body.errors && body.errors.length > 0) {
const errors = body.errors.map((e) => {
return e.message
})
reject(new Error(`${res.statusCode} ${errors.join(', ')}`))
} else {
reject(new Error(`${res.statusCode} ${res.body}`))
}
reject(new RobloxAPIError(res))
}
})
.catch(error => reject(error))
Expand Down
3 changes: 2 additions & 1 deletion lib/avatar/avatarRules.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const http = require('../util/http.js').func
const RobloxAPIError = require('../util/apiError.js')

exports.optional = ['option', 'jar']

Expand Down Expand Up @@ -32,7 +33,7 @@ exports.func = (args) => {

return result
} else {
throw new Error('Error fetching avatar rules')
throw new RobloxAPIError(res)
}
})
}
3 changes: 2 additions & 1 deletion lib/avatar/currentlyWearing.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const http = require('../util/http.js').func
const RobloxAPIError = require('../util/apiError.js')

exports.required = ['userId']

Expand Down Expand Up @@ -26,7 +27,7 @@ exports.func = (args) => {
if (res.statusCode === 200) {
return JSON.parse(res.body)
} else {
throw new Error('User does not exist')
throw new RobloxAPIError(res)
}
})
}
3 changes: 2 additions & 1 deletion lib/avatar/getAvatar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const http = require('../util/http.js').func
const RobloxAPIError = require('../util/apiError.js')

exports.required = ['userId']

Expand All @@ -24,7 +25,7 @@ const getAvatar = (userId) => {
if (res.statusCode === 200) {
return JSON.parse(res.body)
} else {
throw new Error('User does not exist')
throw new RobloxAPIError(res)
}
})
}
Expand Down
Loading
Loading