Client

Struct Client 

Source
pub struct Client { /* private fields */ }
Expand description

A client used for making requests to the Roblox API.

The client stores the roblosecurity cookie, X-CSRF-TOKEN header, and an HTTPS client to send web requests. The client also caches the user id, username, and display name of the user.

Constructed using a ClientBuilder.

§Construction Examples

§Without Roblosecurity or a Custom Reqwest Client

use roboat::ClientBuilder;

let client = ClientBuilder::new().build();

§With a Roblosecurity

use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

§With a Custom Reqwest Client

use roboat::ClientBuilder;

let reqwest_client = reqwest::Client::new();
let client = ClientBuilder::new().reqwest_client(reqwest_client).build();

§With a Roblosecurity and a Custom Reqwest Client

use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let reqwest_client = reqwest::Client::new();
let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).reqwest_client(reqwest_client).build();

§Standard Errors

The errors that can be returned by any of Client’s methods are:

§Auth Required Errors

The errors that can be returned by any of Client’s methods that require authentication are:

§X-CSRF-TOKEN Required Errors

The errors that can be returned by any of Client’s methods that require the X-CSRF-TOKEN header are:

§2-Factor Authentication / Captcha Required Errors

The errors that can be returned by any of Client’s methods that require 2-factor authentication or a captcha are:

Implementations§

Source§

impl Client

WARNING: Some AssetDelivery V2 API returns Errors even when its status code 200

Source

pub async fn fetch_asset_metadata( &self, asset_id: u64, ) -> Result<AssetIdResponse, RoboatError>

Gets Meta data from item, this works on Animations, outfits, places and other assets. This will return which has asset_type_id and the download for the file. Also more information like if the item is deleted.

§Notes

Requires valid roblosecurity *Can return a sucess but still have error codes in the response Doesn’t need xcrf, but will add one if it gets 401

Source

pub async fn post_asset_metadata_batch( &self, asset_batch: Vec<AssetBatchPayload>, ) -> Result<Vec<AssetBatchResponse>, RoboatError>

Sends a batch request to fetch metadata for multiple assets.

This method accepts a vector of AssetBatchPayload items, sends them to the Roblox AssetDelivery v2 batch API endpoint, and returns a vector of AssetBatchResponse objects corresponding to each requested asset.

§Parameters
  • asset_batch: A vector of AssetBatchPayload structs representing the assets for which metadata is requested.
§Notes

Needs Roblox Cookie but not CSRF Can return a sucess but still have error codes in the response

§Returns

Returns a Result containing a vector of AssetBatchResponse on success, or a RoboatError if the request fails or the response is malformed.

§Behavior
  • Automatically handles InvalidXcsrf errors by refreshing the X-CSRF token and retrying the request once.
  • Requires a valid .ROBLOSECURITY cookie set in the Client.
§Example
use clap::Parser;
use roboat::assetdelivery::request_types::AssetBatchPayload;

#[derive(Parser, Debug)]
struct Args {
    #[arg(long, short)]
    roblosecurity: String,
}

use roboat::ClientBuilder;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args = Args::parse();
    let client = ClientBuilder::new()
        .roblosecurity(args.roblosecurity)
        .build();
    let payloads = vec![AssetBatchPayload {
        asset_id: Some("105277031944789".to_string()),
        request_id: Some("0".to_string()),
        ..Default::default()
    }];
    let responses = client.post_asset_metadata_batch(payloads).await?;
    for response in responses {
        println!("Response for request {:?}", response);
    }
    Ok(())
}
§Errors

This function will return errors including but not limited to:

  • Network or HTTP errors from the reqwest client
  • Invalid or expired X-CSRF tokens (which it will attempt to refresh automatically)
  • Malformed responses from the API
Source

pub async fn fetch_asset_data( &self, asset_id: u64, ) -> Result<Bytes, RoboatError>

Downloads a raw asset bytes using the endpoint https://assetdelivery.roblox.com/v1/asset/?id={id}.

§Notes
  • Requires Gzip feature on reqwest for automatic decompression of the data.
  • Requires a valid .ROBLOSECURITY cookie for private or restricted assets.
  • Returns the raw binary content of the asset (e.g., .rbxm, .rbxmx, etc.).
  • The use case for this API, would be download Animation, Models and outfits.
  • very usefully for studio projects
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "your_cookie";
const ASSET_ID: u64 = 12345678;

let client = ClientBuilder::new()
    .roblosecurity(ROBLOSECURITY.to_string())
    .build();

let data = client.fetch_asset_data(ASSET_ID).await?;
println!("Downloaded {} bytes", data.len());

If this API hangs, use a timeout and retry.

Source§

impl Client

Source

pub async fn force_refresh_xcsrf(&self) -> Result<(), RoboatError>

Used to force refresh the xcsrf. This does not invalidate the current xcsrf, it just makes sure that the current xcsrf is valid and adds a new one if it is not.

Uses the endpoint https://auth.roblox.com/

§Notes
  • Works with or without a Roblosecurity. If a Roblosecurity is added, it will be used.
§Return Value Notes
  • Will return Ok(()) if everything was successful.
§Errors
§Examples
use roboat::ClientBuilder;

let client = ClientBuilder::new().build();

let _ = client.force_refresh_xcsrf().await?;
println!("Successfully Refreshed Xcsrf!");
Source§

impl Client

Source

pub async fn non_tradable_limited_details( &self, collectible_item_ids: Vec<String>, ) -> Result<Vec<NonTradableLimitedDetails>, RoboatError>

Grabs details of one or more non-tradable limiteds from https://apis.roblox.com/marketplace-items/v1/items/details. Does not work on normal items. Note that this is a messy, all-encompassing endpoint that should only be used directly when necessary.

Specialized endpoints that use this internally include: Client::collectible_product_id and Client::collectible_product_id_bulk.

§Notes
  • Requires a valid roblosecurity.
  • The amount of items that can be requested at once is unknown as not enough non-tradable limiteds exist, and the endpoint doesn’t accept duplicates.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Examples
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new()
    .roblosecurity(ROBLOSECURITY.to_string())
    .build();

let collectible_item_id_1 = "a4b5cb79-5218-4ca1-93fa-1e3436f595ef".to_owned();
let collectible_item_id_2 = "61f2e366-9fe6-4562-8ce3-47334083372a".to_owned();
let items = vec![collectible_item_id_1, collectible_item_id_2];

let details = client.non_tradable_limited_details(items).await?;

println!("Item Name: {}", details[0].name);
println!("Item Description: {}", details[0].description);
println!("Item Price: {}", details[0].price);

println!("Item Name: {}", details[1].name);
println!("Item Description: {}", details[1].description);
println!("Item Price: {}", details[1].price);
Source

pub async fn collectible_product_id( &self, collectible_item_id: String, ) -> Result<String, RoboatError>

Fetches the collectible product id of a non-tradeable limited. Uses Client::non_tradable_limited_details internally (which fetches from https://apis.roblox.com/marketplace-items/v1/items/details)

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Examples
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new()
    .roblosecurity(ROBLOSECURITY.to_string())
    .build();

let collectible_item_id = "a4b5cb79-5218-4ca1-93fa-1e3436f595ef".to_owned();
let collectible_product_id = client.collectible_product_id(collectible_item_id).await?;

println!("Collectible Product ID: {}", collectible_product_id);
Source

pub async fn collectible_product_id_bulk( &self, collectible_item_ids: Vec<String>, ) -> Result<Vec<String>, RoboatError>

Fetches collectible product ids of multiple non-tradeable limiteds. Uses Client::non_tradable_limited_details internally (which fetches from https://apis.roblox.com/marketplace-items/v1/items/details)

§Notes
  • Requires a valid roblosecurity.
  • The amount of items that can be requested at once is unknown as not enough non-tradable limiteds exist, and the endpoint doesn’t accept duplicates.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Examples
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new()
    .roblosecurity(ROBLOSECURITY.to_string())
    .build();

let collectible_item_id_1 = "a4b5cb79-5218-4ca1-93fa-1e3436f595ef".to_owned();
let collectible_item_id_2 = "61f2e366-9fe6-4562-8ce3-47334083372a".to_owned();
let items = vec![collectible_item_id_1, collectible_item_id_2];

let collectible_product_ids = client.collectible_product_id_bulk(items).await?;

println!("Collectible Product ID 1: {}", collectible_product_ids[0]);
println!("Collectible Product ID 2: {}", collectible_product_ids[1]);
Source

pub async fn collectible_creator_id( &self, collectible_item_id: String, ) -> Result<u64, RoboatError>

Fetches the id of the original creator of a non-tradable limited. This is used when buying stock of an item (and not resellers).

Uses Client::non_tradable_limited_details internally (which fetches from https://apis.roblox.com/marketplace-items/v1/items/details)

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Examples
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new()
    .roblosecurity(ROBLOSECURITY.to_string())
    .build();

let collectible_item_id = "a4b5cb79-5218-4ca1-93fa-1e3436f595ef".to_owned();
let collectible_creator_id = client.collectible_creator_id(collectible_item_id).await?;

println!("Collectible Creator ID: {}", collectible_creator_id);
Source

pub async fn purchase_non_tradable_limited( &self, collectible_item_id: String, collectible_product_id: String, collectible_seller_id: u64, price: u64, ) -> Result<(), RoboatError>

Purchases a non-tradable limited (includes ugc limiteds) using endpoint https://apis.roblox.com/marketplace-sales/v1/item/{collectible_item_id}/purchase-item.

§Warning

This endpoint and related endpoints may change as new things are discovered about this endpoint. This is because no resellers can sell items yet.

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
  • Currently only tested to work when buying from users (as opposed to groups), and only tested when buying the items from the original seller (with original stock). This is because these are the only conditions that currently exist as of 4/14/2023.
§Return Value Notes
  • Will return Ok(()) if the limited was successfully purchased.
§Argument Notes
  • collectible_item_id is the string id of a non-tradable limited. It can be fetched using Client::collectible_item_id.
  • collectible_product_id is the string product id of a non-tradable limited. It can be fetched using Client::collectible_product_id.
  • collectible_seller_id is the user id of the seller of a non-tradable limited. It can be fetched using Client::collectible_creator_id (currently it is unknown how to buy from a reseller instead of the original creator as they do not exist yet).
§Errors
§Examples
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let collectible_item_id = "abc".to_string();;
let collectible_product_id = "xyz".to_string();
let collectible_seller_id = 123456789;
let price = 0;

let _ = client.purchase_non_tradable_limited(collectible_item_id, collectible_product_id, collectible_seller_id, price).await?;
println!("Successfully Purchased!");
Source

pub async fn get_asset_info( &self, asset_id: u64, ) -> Result<AssetInfo, RoboatError>

Fetches detailed information about a specific asset using its asset ID.

This function retrieves asset information such as the asset’s name, description, and other related details from the Roblox API. It uses the internal get_asset_info_internal function to send a request to the server and parse the response.

§Argument Notes
  • asset_id: The unique ID of the asset whose information is being fetched. This ID can be obtained through various means, such as browsing the asset page on Roblox or using other API endpoints.
§Notes
  • requires .ROBLOSECURITY cookie
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let asset_id = 123456789;

let asset_info = client.get_asset_info(asset_id).await?;
println!("Asset Info: {:?}", asset_info);
Source

pub async fn upload_classic_clothing_to_group( &self, group_id: u64, name: String, description: String, image_path: String, classic_clothing_type: ClassicClothingType, ) -> Result<(), RoboatError>

Uploads classic clothing to a group. This currently only works for classic clothing and for people uploading from groups. This is because the endpoint is not fully understood yet and reverse engineering it is expensive.

Uses endpoint https://apis.roblox.com/assets/user-auth/v1/assets.

§WARNING: UNDER CONSTRUCTION
§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
  • The image_path must be a valid path to an image file.
Source§

impl Client

Source

pub async fn item_details( &self, items: Vec<Item>, ) -> Result<Vec<ItemDetails>, RoboatError>

Grabs details of one or more items from https://catalog.roblox.com/v1/catalog/items/details. This now supports “new” limiteds (which include ugc limiteds). Note that this is a messy, all-encompassing endpoint that should only be used directly when necessary.

Specialized endpoints that use this internally include: Client::product_id, Client::product_id_bulk, Client::collectible_item_id, and Client::collectible_item_id_bulk.

§Notes
  • Does not require a valid roblosecurity.
  • This endpoint will accept up to 120 items at a time.
  • Will repeat once if the x-csrf-token is invalid.
§Argument Notes
  • The id parameter is that acts differently for this endpoint than others. If the item_type is ItemType::Asset, then id is the item ID. Otherwise, if the item_type is ItemType::Bundle, then id is the bundle ID.
§Errors
§Examples
use roboat::catalog::{ItemType, Item};
use roboat::ClientBuilder;

let client = ClientBuilder::new().build();

let asset = Item {
    item_type: ItemType::Asset,
    id: 1365767,
};

let bundle = Item {
   item_type: ItemType::Bundle,
   id: 39,
};

let ugc_limited = Item {
   item_type: ItemType::Asset,
   id: 13032232281,
};

let items = vec![asset, bundle];
let details = client.item_details(items).await?;

println!("Item Name: {}", details[0].name);
println!("Bundle Name: {}", details[1].name);
println!("UGC Limited Name: {} / UGC Limited Collectible ID: {}", details[2].name,
    details[2].collectible_item_id.as_ref().ok_or("No collectible ID")?);
Source

pub async fn product_id(&self, item_id: u64) -> Result<u64, RoboatError>

Fetches the product ID of an item (must be an asset). Uses Client::item_details internally (which fetches from https://catalog.roblox.com/v1/catalog/items/details)

§Notes
  • Does not require a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().build();

let item_id = 12345679;

let product_id = client.product_id(item_id).await?;
Source

pub async fn product_id_bulk( &self, item_ids: Vec<u64>, ) -> Result<Vec<u64>, RoboatError>

Fetches the product ID of multiple items (must be an asset). More efficient than calling Client::product_id repeatedly. Uses Client::item_details internally (which fetches from https://catalog.roblox.com/v1/catalog/items/details).

§Notes
  • Does not require a valid roblosecurity.
  • This endpoint will accept up to 120 items at a time.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().build();

let item_id_1 = 12345679;
let item_id_2 = 987654321;

let product_ids = client.product_id_bulk(vec![item_id_1, item_id_2]).await?;

let product_id_1 = product_ids.get(0).ok_or("No product ID 1")?;
let product_id_2 = product_ids.get(1).ok_or("No product ID 2")?;
Source

pub async fn collectible_item_id( &self, item_id: u64, ) -> Result<String, RoboatError>

Fetches the collectible item id of a multiple non-tradeable limited (including ugc limiteds). More efficient than calling Client::product_id repeatedly. Uses Client::item_details internally (which fetches from https://catalog.roblox.com/v1/catalog/items/details).

§Notes
  • Does not require a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().build();

let item_id = 12345679;

let collectible_item_id = client.collectible_item_id(item_id).await?;
Source

pub async fn collectible_item_id_bulk( &self, item_ids: Vec<u64>, ) -> Result<Vec<String>, RoboatError>

Fetches the collectible item ids of multiple non-tradeable limiteds (including ugc limiteds). More efficient than calling Client::collectible_item_id repeatedly. Uses Client::item_details internally (which fetches from https://catalog.roblox.com/v1/catalog/items/details).

§Notes
  • Does not require a valid roblosecurity.
  • This endpoint will accept up to 120 items at a time.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().build();

let item_id_1 = 12345679;
let item_id_2 = 987654321;

let collectible_item_ids = client.collectible_item_id_bulk(vec![item_id_1, item_id_2]).await?;

let collectible_item_id_1 = collectible_item_ids.get(0).ok_or("No collectible item ID 1")?;
let collectible_item_id_2 = collectible_item_ids.get(1).ok_or("No collectible item ID 2")?;

Performs a search query using https://catalog.roblox.com/v1/search/items. Query parameters are specified using the AvatarSearchQuery struct, which can be built using the AvatarSearchQueryBuilder.

§Notes
  • Does not require a valid roblosecurity.
§Argument Notes
§Errors
§Examples
use roboat::catalog::{Item, Category, AvatarSearchQueryBuilder};
use roboat::ClientBuilder;

let client = ClientBuilder::new().build();

let query = AvatarSearchQueryBuilder::new()
    .keyword("cute".to_owned())
    .category(Category::Accessories)
    .build();

let next_cursor = None;

// Fetch the first page of results.
let (items, next_cursor) = client.avatar_catalog_search(&query, next_cursor).await?;
println!("Found {} items.", items.len());
println!("Next cursor: {}", next_cursor.clone().unwrap_or_default());

// Fetch the next page of results.
let (items, next_cursor) = client.avatar_catalog_search(&query, next_cursor).await?;
println!("Found {} items.", items.len());
println!("Next cursor: {}", &next_cursor.clone().unwrap_or_default());
Source§

impl Client

Source

pub async fn unread_conversation_count(&self) -> Result<u64, RoboatError>

Fetches the number of unread chats/conversations using https://chat.roblox.com/v2/get-unread-conversation-count. Keep in mind that these are not the same as “messages”.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let count = client.unread_conversation_count().await?;

println!("Unread message count: {}", count);
Source§

impl Client

Source

pub async fn user_id(&self) -> Result<u64, RoboatError>

Returns the user id of the user. If the user id is not cached, it will be fetched from Roblox first.

The user id should be the only thing used to differentiate between accounts as username and display name can change.

Source

pub async fn username(&self) -> Result<String, RoboatError>

Returns the username of the user. If the username is not cached, it will be fetched from Roblox first.

Username can change (although rarely). For this reason only user id should be used for differentiating accounts.

Source

pub async fn display_name(&self) -> Result<String, RoboatError>

Returns the display name of the user. If the display name is not cached, it will be fetched from Roblox first.

Display name can change. For this reason only user id should be used for differentiating accounts.

Source§

impl Client

Source

pub async fn robux(&self) -> Result<u64, RoboatError>

Grabs robux count of the current account from https://economy.roblox.com/v1/users/{user_id}/currency.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let robux = client.robux().await?;
println!("Robux: {}", robux);
Source

pub async fn resellers( &self, item_id: u64, limit: Limit, cursor: Option<String>, ) -> Result<(Vec<Listing>, Option<String>), RoboatError>

Grabs resellers of an item from https://economy.roblox.com/v1/assets/{item_id}/resellers?cursor={cursor}&limit={limit}.

§Notes
  • Requires a valid roblosecurity.
§Argument Notes
  • The cursor is used to get the a certain page of results. If you want the starting page, use None.
§Return Value Notes
  • The first value is a vector of reseller listings.
  • The second value is the cursor for the next page of results. If there are no more pages, this will be None.
§Errors
§Example
use roboat::Limit;
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let item_id = 1365767;
let limit = Limit::Ten;
let cursor = None;

let (resellers, next_page_cursor) = client.resellers(item_id, limit, cursor).await?;
println!("Lowest Price for Item {}: {}", item_id, resellers[0].price);
Source

pub async fn user_sales( &self, limit: Limit, cursor: Option<String>, ) -> Result<(Vec<UserSale>, Option<String>), RoboatError>

Grabs user sales from https://economy.roblox.com/v2/users/{user_id}/transactions?transactionType=Sale&cursor={cursor}&limit={limit}.

§Notes
  • Requires a valid roblosecurity.
§Argument Notes
  • The cursor is used to get the a certain page of results. If you want the starting page, use None.
§Return Value Notes
  • The first value is a vector of user sales.
  • The second value is the cursor for the next page of results. If there are no more pages, this will be None.
§Errors
§Example
use roboat::Limit;
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let limit = Limit::Ten;
let cursor = None;

let (user_sales, next_page_cursor) = client.user_sales(limit, cursor).await?;

let sale_amount = user_sales.len();
let total_robux_earned = user_sales
    .iter()
    .map(|sale| sale.robux_received)
    .sum::<u64>();

println!("Robux gained from last {} sales: {}", sale_amount, total_robux_earned);
Source

pub async fn put_limited_on_sale( &self, item_id: u64, uaid: u64, price: u64, ) -> Result<(), RoboatError>

Puts a limited item on sale using the endpoint https://economy.roblox.com/v1/assets/{item_id}/resellable-copies/{uaid}.

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Return Value Notes
  • Will return Ok(()) if the item was successfully put on sale.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let item_id = 123456789;
let uaid = 987654321;
let price = 5000;

match client.put_limited_on_sale(item_id, uaid, price).await {
   Ok(_) => println!("Successfully put item on sale!"),
   Err(e) => println!("Error: {}", e),
}
Source

pub async fn take_limited_off_sale( &self, item_id: u64, uaid: u64, ) -> Result<(), RoboatError>

Takes a limited item off sale using the endpoint https://economy.roblox.com/v1/assets/{item_id}/resellable-copies/{uaid}.

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Return Value Notes
  • Will return Ok(()) if the item was successfully taken off sale.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let item_id = 123456789;
let uaid = 987654321;

match client.take_limited_off_sale(item_id, uaid).await {
   Ok(_) => println!("Successfully took item off sale!"),
   Err(e) => println!("Error: {}", e),
}
Source

pub async fn purchase_tradable_limited( &self, product_id: u64, seller_id: u64, uaid: u64, price: u64, ) -> Result<(), RoboatError>

Purchases a limited using https://economy.roblox.com/v1/purchases/products/{product_id}. Only works on tradeable (legacy) limiteds.

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Return Value Notes
  • Will return Ok(()) if the limited was successfully purchased.
  • As it will repeat once if the x-csrf-token is invalid, you may want to manually refresh the x-csrf-token on another thread by using Client::force_refresh_xcsrf.
§Argument Notes
  • product_id is the product id of the limited, NOT the item id.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let product_id = 12345679;
let seller_id = 5656565656;
let uaid = 987654321;
let price = 5000;

let _ = client.purchase_tradable_limited(product_id, seller_id, uaid, price).await?;
println!("Successfully Purchased!");
Source§

impl Client

Source

pub async fn friends_list( &self, user_id: u64, ) -> Result<Vec<FriendUserInformation>, RoboatError>

Get list of all friends for the specified user using https://friends.roblox.com/v1/users/{userId}/friends.

§Notes
  • Does not require a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const USER_ID: u64 = 1692828498;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let friends = client.friends_list(USER_ID).await?;

println!("Found {} friends.", friends.len());

for friend in friends {
    println!("{}: {}", friend.username, friend.user_id);
}
Source

pub async fn friend_requests( &self, cursor: Option<String>, ) -> Result<(FriendRequestsResponse, Option<String>), RoboatError>

Get list of friend requests with cursor using https://friends.roblox.com/v1/my/friends/requests.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let (friend_requests, next_cursor) = client.friend_requests(None).await?;

for user in friend_requests {
    println!("{} from {}: {}", user.username, user.user_id);
}
Source

pub async fn pending_friend_requests(&self) -> Result<u64, RoboatError>

Get count of pending friend requests using https://friends.roblox.com/v1/user/friend-requests/count.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let count_of_friend_requests = client.pending_friend_requests().await?;

println!("There's a {} pending friend requests!", count_of_friend_requests);
Source

pub async fn accept_friend_request( &self, requester_id: u64, ) -> Result<(), RoboatError>

Accepts friend request using https://friends.roblox.com/v1/users/{requester_id}/accept-friend-request.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const REQUESTER_ID: u64 = 1;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

client.accept_friend_request(REQUESTER_ID).await?;

println!("Accepted friend request from {}!", REQUESTER_ID);
Source

pub async fn decline_friend_request( &self, requester_id: u64, ) -> Result<(), RoboatError>

Declines friend request using https://friends.roblox.com/v1/users/{requester_id}/decline-friend-request.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const REQUESTER_ID: u64 = 1;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

client.decline_friend_request(REQUESTER_ID).await?;

println!("Declined friend request from {}!", REQUESTER_ID);
Source

pub async fn send_friend_request( &self, target_id: u64, ) -> Result<(), RoboatError>

Sends friend request using https://friends.roblox.com/v1/users/{target_id}/request-friendship.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const TARGET_ID: u64 = 1;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

client.send_friend_request(TARGET_ID).await?;

println!("Sent friend request to {}!", TARGET_ID);
Source

pub async fn unfriend(&self, target_id: u64) -> Result<(), RoboatError>

Unfriends using https://friends.roblox.com/v1/users/{target_id}/unfriend.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const TARGET_ID: u64 = 1;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

client.unfriend(TARGET_ID).await?;

println!("Unfriended {}", TARGET_ID);
Source§

impl Client

Source

pub async fn group_roles(&self, group_id: u64) -> Result<Vec<Role>, RoboatError>

Returns the roles of a group using https://groups.roblox.com/v1/groups/{group_id}/roles.

§Notes
  • Does not require a valid roblosecurity.
  • Returns roles in ascending order by rank.
  • Does not appear to have a rate limit.
§Errors
§Example
use roboat::ClientBuilder;

const GROUP_ID: u64 = 1127093;

let client = ClientBuilder::new().build();

let roles = client.group_roles(GROUP_ID).await?;

// Print all roles in order by rank
for role in roles {
    println!(
       "Role: {} / ID: {} / Rank: {}",
       role.name, role.id, role.rank
   );
 }
Source

pub async fn group_role_members( &self, group_id: u64, role_id: u64, limit: Limit, cursor: Option<String>, ) -> Result<(Vec<User>, Option<String>), RoboatError>

Returns a page of members of a group role using https://groups.roblox.com/v1/groups/{group_id}/roles/{role_id}/users?cursor={cursor}&limit={limit}&sortOrder=Desc.

§Notes
  • Does not require a valid roblosecurity.
  • Does not appear to have a rate limit.
§Errors
§Example
use roboat::{ClientBuilder, Limit};

const GROUP_ID: u64 = 1127093;
const ROLE_ID: u64 = 18792070;

let client = ClientBuilder::new().build();

let (members, cursor) = client
    .group_role_members(GROUP_ID, ROLE_ID, Limit::Hundred, None)
    .await?;

for member in members {
    println!(
    "User ID: {} / Username: {} / Display Name: {}",
    member.user_id, member.username, member.display_name
    );
}
Source

pub async fn set_group_member_role( &self, user_id: u64, group_id: u64, role_id: u64, ) -> Result<(), RoboatError>

Sets a group member’s role by role id using https://groups.roblox.com/v1/groups/{group_id}/users/{user_id}.

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Return Value Notes
  • Will return Ok(()) if the role was successfully set.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const user_id: u64 = 123456789;
const group_id: u64 = 1127093;
const role_id: u64 = 78505465;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let _ = client.set_group_member_role(user_id, group_id, role_id).await?;

println!(
    "Set user {}'s role to role id {} in group {}.",
    user_id, role_id, group_id
);
Source§

impl Client

Source

pub async fn user_games( &self, user_id: u64, ) -> Result<GamesResponseV2, RoboatError>

Retrieves the first 50 games for a specified user_id.

§Endpoint

Sends a GET request to https://games.roblox.com/v2/users/{user_id}/games?limit=50

§Notes
  • This is a public endpoint that does not require authentication.
  • The limit is automatically set to 50, which is the maximum allowed by this endpoint.
  • Returns games in descending order by default (most recent first).
  • Use pagination cursors in the response to fetch additional pages of results.
§Parameters
  • user_id – The numeric user ID to retrieve games for
§Return Value Notes
  • Returns GamesResponseV2 containing the paginated list of games if successful.
  • The response includes pagination cursors for fetching additional results.
  • Each game contains detailed information including creator, root place, visit counts, and timestamps.
§Errors
§Example
use roboat::ClientBuilder;

let client = ClientBuilder::new().build();

let user_id = 3054007;
let games_response = client.user_games(user_id).await?;

println!("Found {} games", games_response.data.len());

for game in games_response.data {
    println!("Game: {} (ID: {})", game.name, game.id);
    println!("  Visits: {}", game.place_visits);
    println!("  Created: {}", game.created);
}

// Check for more pages
if let Some(next_cursor) = games_response.next_page_cursor {
    println!("More results available with cursor: {}", next_cursor);
}
Source

pub async fn group_games( &self, group_id: u64, ) -> Result<GamesResponseV2, RoboatError>

Retrieves the first 100 games for a specified group id..

§Endpoint

Sends a GET request to https://games.roblox.com/v2/groups/{group_id}/gamesv2?limit=100

§Notes
  • This is a public endpoint that does not require authentication.
  • The limit is automatically set to 100, which is the maximum allowed by this endpoint.
  • Returns games in descending order by default (most recent first).
  • Use pagination cursors in the response to fetch additional pages of results.
§Parameters
  • group_id – The numeric group ID to retrieve games for
§Return Value Notes
  • Returns GamesResponseV2 containing the paginated list of games if successful.
  • The response includes pagination cursors for fetching additional results.
  • Each game contains detailed information including creator, root place, visit counts, and timestamps.
§Errors
§Example
use roboat::ClientBuilder;

let client = ClientBuilder::new().build();

let group_id = 3190902;
let games_response = client.group_games(group_id).await?;

println!("Found {} games for group", games_response.data.len());

for game in games_response.data {
    println!("Game: {} (ID: {})", game.name, game.id);
    println!("  Root Place ID: {}", game.root_place.id);
    println!("  Visits: {}", game.place_visits);
    println!("  Last Updated: {}", game.updated);
}

// Check for more pages
if let Some(next_cursor) = games_response.next_page_cursor {
    println!("More results available with cursor: {}", next_cursor);
}
``
Source§

impl Client

Source

pub async fn upload_new_animation( &self, animation_info: NewAnimation, ) -> Result<String, RoboatError>

Uploads a new animation asset to Roblox using the internal ide/publish/uploadnewanimation endpoint.

§Endpoint

Sends a POST request to https://www.roblox.com/ide/publish/uploadnewanimation with animation metadata as query parameters and animation binary data in the body.

§Notes
  • Requires a valid .ROBLOSECURITY cookie for authentication.
  • The animation data (animation_data) must be provided as binary (e.g., R15 animation XML).
  • If the X-CSRF token is expired or invalid, it will retry the request once with a refreshed token.
§Upload Animation Query Parameters

Automatically included in the request URL:

  • AllID, ispublic, allowComments, isGamesAsset
  • assetTypeName – Always set to "Animation"
  • name – The title of the animation
  • description – The description of the animation
§Optional Animation Params
  • groupId – Optional group ID (if uploading to a group)
§Return Value Notes
  • Returns String of the new animation ID if the animation was uploaded successfully.
  • Or Returns an error.
§Errors
  • [RoboatError::MissingAuth] – If the .ROBLOSECURITY cookie is missing.
  • RoboatError::InvalidXcsrf – If the CSRF token needs refreshing (retry will be attempted).
  • RoboatError::ReqwestError – For any network issues.
  • [RoboatError::ResponseError] – If Roblox returns a failure response.
§Example
use bytes::Bytes;
use roboat::{ClientBuilder, ide::request_types::Animation};

const ROBLOSECURITY: &str = "your_.ROBLOSECURITY_cookie";

let client = ClientBuilder::new()
    .roblosecurity(ROBLOSECURITY.to_string())
    .build();

let animation = Animation {
    id: None,
    title: "MyCoolAnimation".to_string(),
    description: "A test animation created by Roboat.".to_string(),
    group_id: Some(123456),
    animation_data: Some(Bytes::from_static(b"<KeyframeSequence>...</KeyframeSequence>")),
};

client.upload_new_animation(animation).await?;

println!("Successfully uploaded animation.");
Source§

impl Client

Source

pub async fn register_presence(&self) -> Result<(), RoboatError>

Registers presence on the website (makes you appear to be online). Endpoint called is https://presence.roblox.com/v1/presence/register-app-presence

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
  • Normally repeats every 15 seconds when viewing the Roblox homepage.
§Return Value Notes
  • Will return Ok(()) if presence was successfully registered.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

match client.register_presence().await {
   Ok(_) => println!("Successfully registered presence!"),
   Err(e) => println!("Error: {}", e),
}
Source

pub async fn fetch_users_presence( &self, users: Vec<u64>, ) -> Result<UserPresenceResponse, RoboatError>

Fetch presences of users on roblox like (Offline, Online, In Game, Last Location). Endpoint called is https://presence.roblox.com/v1/presence/users

§Notes
  • valid roblosecurity is optional for more info about the game the user is in
  • If user is in game and either their joins are turned off or you don’t have a valid cookie information like place_id will always be None
  • Can handle up to 50 users at once
  • Doesnt need xcsrf token.
  • This API is ratelimited
§Return Value Notes
  • Will return Ok(UserPresenceResponse) if presence was successfully fetched.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();
let users = vec![1, 35958674918];
match client.fetch_user_presence(users).await {
   Ok(user_statuses) => println!("Successfully registered presence: {:?}", user_statuses),
   Err(e) => println!("Error: {}", e),
}
Source§

impl Client

Source

pub async fn messages( &self, page: u64, message_tab_type: MessageTabType, ) -> Result<(Vec<Message>, MessagesMetadata), RoboatError>

Page starts at 0

Fetches private messages from the specified message tab using https://privatemessages.roblox.com/v1/messages.

§Notes
  • Requires a valid roblosecurity.
  • Returns 20 messages at a time.
§Argument Notes
  • The page starts at 0.
§Return Value Notes
  • The first value in the tuple is a vector of messages.
  • The second value in the tuple is the metadata of the messages (total count and page amount).
§Errors
§Example
use roboat::ClientBuilder;
use roboat::private_messages::MessageTabType::Inbox;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let inbox_type = Inbox;

let (messages, messages_metadata) = client.messages(0, inbox_type).await?;

println!("First Message Subject: {}", messages[0].subject);
println!("Total Messages: {}", messages_metadata.total_message_count);
println!("Total Pages: {}", messages_metadata.total_pages);
Source§

impl Client

Source

pub async fn thumbnail_url_bulk( &self, ids: Vec<u64>, size: ThumbnailSize, thumbnail_type: ThumbnailType, ) -> Result<Vec<String>, RoboatError>

Fetches multiple thumbnails of a specified size and type using https://thumbnails.roblox.com/v1/batch.

§Notes
  • Does not require a valid roblosecurity.
  • Can handle up to 100 asset ids at once.
  • Does not appear to have a rate limit.
  • Note all types are implemented, the full list can be found here and the implemented ones can be found in ThumbnailType.
§Errors
§Example
use roboat::ClientBuilder;
use roboat::thumbnails::{ThumbnailSize, ThumbnailType};

let client = ClientBuilder::new().build();

let size = ThumbnailSize::S420x420;
let thumbnail_type = ThumbnailType::Avatar;

let avatar_id_1 = 20418400;
let avatar_id_2 = 12660007639;

let urls = client
    .thumbnail_url_bulk(vec![avatar_id_1, avatar_id_2], size, thumbnail_type)
    .await?;

println!("Avatar {} thumbnail url: {}", avatar_id_1, urls[0]);
println!("Avatar {} thumbnail url: {}", avatar_id_2, urls[1]);

let size = ThumbnailSize::S420x420;
let thumbnail_type = ThumbnailType::AvatarHeadshot;

let avatar_id_1 = 20418400;
let avatar_id_2 = 12660007639;

let urls = client
    .thumbnail_url_bulk(vec![avatar_id_1, avatar_id_2], size, thumbnail_type)
    .await?;

println!("Avatar headshot {} thumbnail url: {}", avatar_id_1, urls[0]);
println!("Avatar headshot {} thumbnail url: {}", avatar_id_2, urls[1]);

let size = ThumbnailSize::S420x420;
let thumbnail_type = ThumbnailType::Asset;

let asset_id_1 = 20418400;
let asset_id_2 = 12660007639;

let urls = client
    .thumbnail_url_bulk(vec![asset_id_1, asset_id_2], size, thumbnail_type)
    .await?;

println!("Asset {} thumbnail url: {}", asset_id_1, urls[0]);
println!("Asset {} thumbnail url: {}", asset_id_2, urls[1]);
Source

pub async fn thumbnail_url( &self, id: u64, size: ThumbnailSize, thumbnail_type: ThumbnailType, ) -> Result<String, RoboatError>

Fetches a thumbnail of a specified size and type using https://thumbnails.roblox.com/v1/batch.

§Notes
  • Does not require a valid roblosecurity.
  • Can handle up to 100 asset ids at once.
  • Does not appear to have a rate limit.
  • Note all types are implemented, the full list can be found here and the implemented ones can be found in ThumbnailType.
§Errors
§Example
use roboat::ClientBuilder;
use roboat::thumbnails::{ThumbnailSize, ThumbnailType};

let client = ClientBuilder::new().build();

let size = ThumbnailSize::S420x420;
let thumbnail_type = ThumbnailType::Avatar;

let avatar_id = 20418400;

let url = client
    .thumbnail_url(avatar_id, size, thumbnail_type)
    .await?;

println!("Avatar {} thumbnail url: {}", avatar_id, url);

let size = ThumbnailSize::S420x420;
let thumbnail_type = ThumbnailType::AvatarHeadshot;

let avatar_id = 20418400;

let url = client
    .thumbnail_url(avatar_id, size, thumbnail_type)
    .await?;

println!("Avatar headshot {} thumbnail url: {}", avatar_id, url);

let size = ThumbnailSize::S420x420;
let thumbnail_type = ThumbnailType::Asset;

let asset_id = 20418400;

let url = client
    .thumbnail_url(asset_id, size, thumbnail_type)
    .await?;

println!("Asset {} thumbnail url: {}", asset_id, url);
Source§

impl Client

Source

pub async fn trades( &self, trade_type: TradeType, limit: Limit, cursor: Option<String>, ) -> Result<(Vec<Trade>, Option<String>), RoboatError>

Returns a list of trades using the endpoint https://trades.roblox.com/v1/{trade_type}.

§Notes
  • Requires a valid roblosecurity.
  • Trades are ordered newest to oldest.
§Errors
§Example
use roboat::ClientBuilder;
use roboat::trades::TradeType;
use roboat::Limit;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let trade_type = TradeType::Inbound;
let limit = Limit::Ten;
let cursor = None;

let (trades, next_cursor) = client.trades(trade_type, limit, cursor).await?;

println!("Inbound Trade #1 Partner: {}", trades[0].partner.username);
Source

pub async fn trade_details( &self, trade_id: u64, ) -> Result<TradeDetails, RoboatError>

Returns the details of a trade using https://trades.roblox.com/v1/trades/{trade_id}.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const TRADE_ID: u64 = 123456789;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let trade_details = client.trade_details(TRADE_ID).await?;

println!("Trade Details: {:#?}", trade_details);
Source

pub async fn decline_trade(&self, trade_id: u64) -> Result<(), RoboatError>

Declines a trade using https://trades.roblox.com/v1/trades/{trade_id}/decline.

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const TRADE_ID: u64 = 123456789;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

client.decline_trade(TRADE_ID).await?;

println!("Declined trade {}", TRADE_ID);
Source

pub async fn send_trade( &self, partner_id: u64, your_item_uaids: Vec<u64>, your_robux: u64, partner_item_uaids: Vec<u64>, partner_robux: u64, ) -> Result<u64, RoboatError>

your_robux and partner robux is before tax

/// Declines a trade using https://trades.roblox.com/v1/trades/{trade_id}/decline.

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Argument Notes
  • your_robux and partner is before 30% tax.
  • Uaids are NOT item/asset ids. They are unique ids for each item.
§Return Notes
  • The value returned on success is the trade id.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let partner_id = 12345;
let your_uaids = vec![123, 456];
let your_robux = 100;
let partner_uaids = vec![321, 654];
let partner_robux = 0;

let trade_id = client
    .send_trade(
        partner_id,
        your_uaids,
        your_robux,
        partner_uaids,
        partner_robux,
    )
    .await?;

println!("Sent Trade! Trade ID: {}", trade_id);
Source

pub async fn accept_trade(&self, trade_id: u64) -> Result<(), RoboatError>

Accepts a trade using https://trades.roblox.com/v1/trades/{trade_id}/accept.

§Notes
  • Requires a valid roblosecurity.
  • Will repeat once if the x-csrf-token is invalid.
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const TRADE_ID: u64 = 123456789;

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

client.accept_trade(TRADE_ID).await?;

println!("Accepted trade {}", TRADE_ID);
Source

pub async fn trade_count(&self) -> Result<u64, RoboatError>

Retrieves the count of trades the user using https://trades.roblox.com/v1/trades/inbound/count.

§Notes
  • Requires a valid roblosecurity.
§Errors
§Examples
use roboat::ClientBuilder;
use roboat::RoboatError;

const ROBLOSECURITY: &str = "roblosecurity";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let trade_count = client.trade_count().await?;

println!("Total trades: {}", trade_count);
Source§

impl Client

Searches for a user using https://users.roblox.com/v1/users/search.

§Notes
  • Does not require a valid roblosecurity.
  • HOWEVER, if a valid roblosecurity is not provided then there will be a very low rate limit.
  • The cursors in this response are not used as using them is currently broken.
  • Limits are not used for the same reason (the endpoint does not respect them).
§Errors
§Example
use roboat::ClientBuilder;

const ROBLOSECURITY: &str = "roblosecurity";
const KEYWORD: &str = "linkmon";

let client = ClientBuilder::new().roblosecurity(ROBLOSECURITY.to_string()).build();

let keyword = KEYWORD.to_string();
let users = client.user_search(keyword).await?;

println!("Found {} users.", users.len());

for user in users {
    println!("{}: {}", user.username, user.user_id);
}
Source

pub async fn user_details( &self, user_id: u64, ) -> Result<UserDetails, RoboatError>

Fetches user details using https://users.roblox.com/v1/users/{user_id}.

For bulk fetching, it is recommended to use Client::username_user_details instead. This is because more users can be fetched at once using that endpoint. The only downside of this is that you can only search using usernames instead of user IDs.

§Notes
  • Does not require a valid roblosecurity.
§Errors
§Example
use roboat::ClientBuilder;

const USER_ID: u64 = 2207291;

let client = ClientBuilder::new().build();

let user_details = client.user_details(USER_ID).await?;

println!("Username: {}", user_details.username);
println!("Display Name: {}", user_details.display_name);
println!("Year Created: {}", user_details.created_at.chars().take(4).collect::<String>());
Source

pub async fn username_user_details( &self, usernames: Vec<String>, exclude_banned_users: bool, ) -> Result<Vec<UsernameUserDetails>, RoboatError>

Fetches user details using https://users.roblox.com/v1/usernames/users.

This endpoint uses a post request instead of a get request so it can be used to retrieve information about multiple users at once.

To fetch a single user, or to fetch a user using a user ID instead of a username, use Client::user_details instead.

§Notes
  • Does not require a valid roblosecurity.
  • This is virtually the same as Client::user_details except that it can fetch multiple users at once, and it searches using usernames instead of user IDs.
  • The usernames are not case sensitive.
§Errors
§Example
use roboat::ClientBuilder;

const USERNAME: &str = "Builderman";

let client = ClientBuilder::new().build();

let users = vec![USERNAME.to_owned()];
let all_username_user_details = client.username_user_details(users, true).await?;
let username_user_details = all_username_user_details.first().ok_or("User not found")?;

println!("Username: {}", username_user_details.username);
println!("Display Name: {}", username_user_details.display_name);
println!("ID: {}", username_user_details.id);

Trait Implementations§

Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Client

Source§

fn default() -> Client

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl !UnwindSafe for Client

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,