OpenBlox - OpenCloud & Classic API Wrapper (NodeJs & Bun)

logo

repo dot package dot docs


OpenBlox is a strictly typed API wrapper for both Classic and OpenCloud Roblox endpoints. It is written in TypeScript and can run natively on both NodeJs and Bun.

  • Currently wraps over 200 Roblox API endpoints. :tada:
  • Automatically handles CSRF tokens.
  • Automatically polls long running operations.
  • Easily iterate over paginated endpoints via async iterators (see Pagination).
  • Use any http library via HTTP adapters (fetch is used by default).
  • Easily rebind any Openblox API wrapper method to use different credentials (cookie, opencloud key, oauth access token) (see Rebinding).
  • Prettifies response data
    • ensures camel case (Example).
    • turns Date strings into Date’s (Example).
    • removes outer data wrappers (Example).
    • if an endpoint asks for an array of IDs and it returns its response data as an array, where each item in the response array corresponds to an item in the IDs array, then it will turn the response data into a dictionary so the data can be accessed more easily (Example).
    • Abstracts pagination data away into its own cursors object (see Pagination) (Example).

OpenCloud APIs Support

CloudCompat
Last updated 18th July 2024 - Openblox v.1.0.18

Classic APIs Support

Last updated 18th August 2024 - Openblox v.1.0.41


Getting Started!

  1. Install Openblox:
npm install openblox
  1. Setup Openblox in your project:
import "dotenv/config";
import { setConfig } from "openblox/config";

/*
Naming your Roblox Cookie environment variable `ROBLOX_COOKIE` will automatically
import it into your Openblox config, therefore voiding the need to set it in the config
manually. Similarly, naming your OpenCloud API Key environment variable `ROBLOX_CLOUD_KEY`
will also automatically import it into your Openblox config.
*/
setConfig({
  cookie: process.env.MY_ROBLOX_COOKIE,
  cloudKey: process.env.MY_ROBLOX_CLOUD_KEY
});
  1. Run Openblox API wrapper methods:
import "dotenv/config";
import { setConfig } from "openblox/config";
import { UsersApi } from "openblox/cloud";
import { ClassicUsersApi } from "openblox/classic"; // Classic APIs will always be prefixed with `Classic`.

/*
Naming your Roblox Cookie environment variable `ROBLOX_COOKIE` will automatically
import it into your Openblox config, therefore voiding the need to set it in the config
manually. Similarly, naming your OpenCloud API Key environment variable `ROBLOX_CLOUD_KEY`
will also automatically import it into your Openblox config.
*/
setConfig({
  cookie: process.env.MY_ROBLOX_COOKIE,
  cloudKey: process.env.MY_ROBLOX_CLOUD_KEY
})

(async () => {

  const { data:userInfo_classic } = await ClassicUsersApi.userInfo({ userId: 45348281 })

  const { data:userInfo_cloud } = await UsersApi.userInfo({ userId: 45348281 })

})

Support

You can get support for Openblox in the following servers:
RobloxAPI
RoAPI

24 Likes

I’m a fairly new user for this fairly new project, and so far it has been amazing. I made the switch from noblox.js due to issues with their http client and other internal aspects that make requests randomly drop (my main concern was group ranking not going through.

After the switch, I haven’t experienced any issues with requests and openblox even supports custom http adapters if node-fetch is not for you.

This wrapper is also finer than noblox.js, and I believe it only makes one request per function. This can make it less basic to achieve the same functions, but you have A LOT more control over your project–this has come in very handy and I appreciate it a lot, I save myself from making unneeded requests to the ROBLOX api.

The last thing I’d like to mention is that the maintainer is extremely helpful and has helped me extensively every time I’ve had an issue or concern!

3 Likes

OpenBlox v1.0.19

Introducing Queries

The most ergonomic way to interact with the Roblox API.

As you probably know Openblox is a quite low-level API wrapper, each function makes a call to only 1 Roblox API endpoint. This allows the library to be versatile and to easily allow higher level abstractions to be built on top of it.

My end goal with Openblox is for it to be versatile and cater to a wide audience. And to achieve this the library needs to be as unopinionated as possible, hence the low-level design. However, some Roblox Developers who would prefer something higher-level may feel alienated by this design choice - so thats where queries come in.

Queries are extremely readable and are constructed via a builder pattern. Much like their lower-level counterpart they are incredibly typesafe. With queries complex and tedious concepts such as parallel fetching and data aggregation are abstracted away, making it a perfect solution for someone who may be new to Javascript, Typescript, programming, or someone who wants an ergonomic hassle-free experience.

Heres an example of queries in action:

const { data } = await Users.get([ "name", "displayName", "thumbnail" ]).forIds([ 45348281, 50 ])

The only data that is returned is the data that is requested, this is of course reflected in the return type of the query’s data:

const data: {
    45348281: {
        name?: string | undefined;
        displayName?: string | undefined;
        thumbnail?: `https://${string}` | undefined;
    };
    50: {
        name?: string | undefined;
        displayName?: string | undefined;
        thumbnail?: `https://${string}` | undefined;
    };
}

Of course performance is incredibly important, especially considering that queries are expected to be executed many times throughout the lifetime of your js/ts programs. The bulk of the computation is done in the first step:

Users.get([ "name", "displayName", "thumbnail" ])

You can consider the get function as the pre-calculation / preparation step. due to this it is wise to assign the result of this pre-calculation step to a variable in an outer scope of your program and reference/use it in inner scopes, for example:

const getName = Users.get([ "name" ])

const functionThatRunsManyTimes = async () => {
  const { data:names } = await getName.forIds([ 45348281, 50 ])
  console.log(names)
}

for (let count = 0; count <= 10; count++) {
  await functionThatRunsManyTimes()
}

Getting Started

  1. Make sure you have the latest version of openblox installed via npm install openblox@latest --force or bun install openblox@latest --force.

  2. Import a query builder into your project (currently only an open cloud user query builder exists):

import { Users } from "openblox/queries/cloud"
  1. happy querying :tada:
Users.get([ "about", "locale", "socialNetworkProfiles" ]).forIds([ 45348281 ])

Does this support economy.roblox.com, or https://catalog.roblox.com?

Did you just forget to read or are you just blind?

1 Like

It doesn’t currently support economy or catalog but they are on the roadmap though.

Amazing resource! When will Datastore V2 support come?

1 Like

Probably within the next few days.

2 Likes

Openblox v1.0.21

Added StandardDatastoresApi_V2 → docs: listStandardDataStores – Nextra

Added ClassicGroupsApi.featuredEvent → docs: featuredEvent – Nextra

1 Like

Openblox v1.0.22

  • non literal array types are now allowed where previously they would throw an error.

  • renamed userIdsToUsersInfo to usersInfoFromIds

  • renamed usernamesToUsersInfo to usersInfoFromNames

  • data is only calculated when it is accessed.


Openblox 1.0.23


Openblox 1.0.24

  • Fixed regression with 1.0.23

Openblox 1.0.25

1 Like

Openblox 1.0.26


Openblox 1.0.27

  • fixed bug with setting cookie manually in the config not working

Openblox v1.0.28

New Methods

Internal changes

  • Rewrote apiGroup to be more optimised and clean (this includes pagination).
  • renamed prettifyFn to formatRawDataFn for addApiMethod.
  • formData now uses a builder pattern for addApiMethod.

Hey, the library now supports the economy and catalog apis.

economy api docs: https://open.blox.wiki/classic/economy/assetResaleData
catalog api docs: https://open.blox.wiki/classic/catalog/assetIdsToCatalogCategoryIds

1 Like

Woah, that was unexpected but thanks!

1 Like

Openblox 1.0.29

Openblox 1.0.37 (major bump due to issues with the updated library uploading properly).

Added cloud LegacyBadgesApi. docs → https://open.blox.wiki/cloud/legacyBadges/updateBadge
Added cloud LegacyFollowingsApi. docs → https://open.blox.wiki/cloud/legacyFollowings/universeFollowingsForUser


Openblox v1.0.40 (versions 1.0.38 and 1.0.39 were minor JSDoc tweaks).

  • Some cloud apis were not exported properly, this has now been fixed.
  • The assets api was getting npm ignored so that has been fixed as well.


Openblox v1.0.42

I am considering using this package to handle datastores, because the package I am currently using seems no longer maintained and doesn’t support the new V2 endpoints of Datastores.

One thing I see in the V2 endpoints is that in the Update Data Store Entry endpoint, it is possible to specify the allowMissing query parameter to create the entry if it does not exist, but specifying this parameter does not seem possible with OpenBlox. Any chance this can be added ?

The omission of the allowMissing query parameter was an accidental oversight on my part, my apologies. This has now been fixed.

1 Like

Hey @MightyPart i am using cloud part of your package but I actually having some issue adding filter in Openblox.UserApi.userinfo

I want to add a filter but I can’t figure out how do that are you able to give me a quick example code?

It looks that filter: {userid: 10} does not work

Edit I found an example but it’s not working it looks that the url formatting is wrong , as it’s like adding some sort of “+”

UsersApi.userInfo only takes a userId argument:

My bad sorry I was meaning Openblox.GroupsApi.GroupMembers looks like when adding a filter as I written above the url formatting is wrong

My code:
OB.GroupsApi.groupMembers({groupid: 1, filter: {userid: 1}})

Actually this return an errors and url is malformed

URL encoded by library: https://apis.roblox.com/cloud/v2/groups/4219097/memberships?filter=user+%3D%3D+'users%2F45348281'

Decoded:
https://apis.roblox.com/cloud/v2/groups/4219097/memberships?filter=user+==+'users/45348281

As you can see it’s putting the “+” wich are wrong

Target function: groupMembers – Nextra