1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
//! # About
//! A high performance interface for the Roblox API.
//!
//! This library is designed to be high-performance capable, meaning
//! that a [`Client`] is designed to work with proxies, as well as make
//! multiple requests in parallel. All API calls are made through a [`Client`].
//!
//! Extensive documentation is used throughout this crate.
//! All public methods in this crate are documented and have at least one corresponding example.
//!
//! # Coverage
//! * Auth API
//! - Force Refresh Xcsrf - [`Client::force_refresh_xcsrf`]
//! * BEDEV2 API
//! - Fetch Non-Tradable Limited Details - [`Client::non_tradable_limited_details`]
//! - Fetch Collectible Product ID - [`Client::collectible_product_id`]
//! - Fetch Collectible Product ID Bulk - [`Client::collectible_product_id_bulk`]
//! - Fetch Collectible Creator ID - [`Client::collectible_creator_id`]
//! - Purchase Non-Tradable Limited - [`Client::purchase_non_tradable_limited`]
//! * Catalog API
//! - Fetch Item Details - [`Client::item_details`]
//! - Fetch Product ID - [`Client::product_id`]
//! - Fetch Product ID Bulk - [`Client::product_id_bulk`]
//! - Fetch Collectible Item ID - [`Client::collectible_item_id`]
//! - Fetch Collectible Item ID Bulk - [`Client::collectible_item_id_bulk`]
//! - Avatar Catalog Search - [`Client::avatar_catalog_search`]
//! * Chat API
//! - Fetch Unread Conversation Count - [`Client::unread_conversation_count`]
//! * Economy API
//! - Fetch Robux Balance - [`Client::robux`]
//! - Fetch Resellers - [`Client::resellers`]
//! - Fetch User Sales - [`Client::user_sales`]
//! - Put Limited On Sale - [`Client::put_limited_on_sale`]
//! - Take Limited Off Sale - [`Client::take_limited_off_sale`]
//! - Purchase Tradable Limited - [`Client::purchase_tradable_limited`]
//! * Group API
//! - Fetch Group Roles - [`Client::group_roles`]
//! - Fetch Group Role Members - [`Client::group_role_members`]
//! - Set Group Member Role - [`Client::set_group_member_role`]
//! * Presence API
//! - Register Presence - [`Client::register_presence`]
//! - Fetch Users Presence - [`Client::fetch_users_presence`]
//! * Private Messages API
//! - Fetch Messages - [`Client::messages`]
//! * Thumbnails API
//! - Fetch Thumbnail Url Bulk - [`Client::thumbnail_url_bulk`]
//! - Fetch Thumbnail Url - [`Client::thumbnail_url`]
//! * Trades API
//! - Accept Trade - [`Client::accept_trade`]
//! - Decline Trade - [`Client::decline_trade`]
//! - Send Trade - [`Client::send_trade`]
//! - Fetch Trade Details - [`Client::trade_details`]
//! - Fetch Trades List - [`Client::trades`]
//! - Fetch Trade Count - [`Client::trade_count`]
//! * Users API
//! - Fetch User ID - [`Client::user_id`]
//! - Fetch Username - [`Client::username`]
//! - Fetch Display Name - [`Client::display_name`]
//! - User Search - [`Client::user_search`]
//! - Username User Details - [`Client::username_user_details`]
//! - Fetch User Details - [`Client::user_details`]
//! * Friends API
//! - Fetch Count of Pending Friend Requests - [`Client::pending_friend_requests`]
//! - Fetch Friend Requests - [`Client::friend_requests`]
//! - Fetch Friends List - [`Client::friends_list`]
//! - Accept Friend Request - [`Client::accept_friend_request`]
//! - Decline Friend Request - [`Client::decline_friend_request`]
//! - Send Friend Request - [`Client::send_friend_request`]
//! - Unfriend - [`Client::unfriend`]
//! * Assetdelivery API
//! - Fetch Asset Data - [`Client::fetch_asset_data`]
//! * IDE API (Animations)
//! - Upload New Animation - [`Client::upload_new_animation`]
//! - Get User Games - [`Client::user_games`]
//! - Get Group Games - [`Client::group_games`]
//! * Client Settings
//! - Get Client Version - [`Client::client_version`]
//! - Get Client Version for Channel - [`Client::client_version_for_channel`]
//! - Get User Channel - [`Client::user_channel`]
//! * UNDER CONSTRUCTION
//! - Upload Classic Clothing To Group - [`Client::upload_classic_clothing_to_group`]
//!
//! # Quick Start Examples
//!
//! ## Example 1 - Purchase Free UGC Limited
//! This code snippet allows you to purchase a free ugc limited.
//!
//! It can be modified to purchase a non-free ugc limited by changing the price.
//!
//! ```no_run
//! // Replace this value with your own roblosecurity token.
//! const ROBLOSECURITY: &str = "your-roblosecurity-token";
//! // Replace this value with the item id of the item you want to purchase.
//! const ITEM_ID: u64 = 13119979433;
//! // Replace this value if you want to purchase a non-free item.
//! const PRICE: u64 = 0;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let client = roboat::ClientBuilder::new()
//! .roblosecurity(ROBLOSECURITY.to_string())
//! .build();
//!
//! let collectible_item_id = client.collectible_item_id(ITEM_ID).await?;
//!
//! let collectible_product_id = client
//! .collectible_product_id(collectible_item_id.clone())
//! .await?;
//!
//! let collectible_creator_id = client
//! .collectible_creator_id(collectible_item_id.clone())
//! .await?;
//!
//! client
//! .purchase_non_tradable_limited(
//! collectible_item_id,
//! collectible_product_id,
//! collectible_creator_id,
//! PRICE,
//! )
//! .await?;
//!
//! println!("Purchased item {} for {} robux!", ITEM_ID, PRICE);
//!
//! Ok(())
//! }
//! ```
//!
//! ## Example 2 - Fetch User Info
//!
//! This code snippet allows you to get your current robux, id, username, and display name.
//!
//! ```no_run
//! // Replace this value with your own roblosecurity token.
//! const ROBLOSECURITY: &str = "your-roblosecurity-token";
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let client = roboat::ClientBuilder::new()
//! .roblosecurity(ROBLOSECURITY.to_string())
//! .build();
//!
//! let robux = client.robux().await?;
//! let user_id = client.user_id().await?;
//! let username = client.username().await?;
//! let display_name = client.display_name().await?;
//!
//! println!("Robux: {}", robux);
//! println!("User ID: {}", user_id);
//! println!("Username: {}", username);
//! println!("Display Name: {}", display_name);
//!
//! Ok(())
//! }
//! ```
//!
//! ## Example 3 - Fetch Price of Tradable Limited
//!
//! This code snippet allows you to view the lowest price of a tradable limited item by
//! fetching a list of reseller listings.
//!
//! ```no_run
//! // Replace this value with your own roblosecurity token.
//! const ROBLOSECURITY: &str = "your-roblosecurity-token";
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let client = roboat::ClientBuilder::new()
//! .roblosecurity(ROBLOSECURITY.to_string())
//! .build();
//!
//! let item_id = 1365767;
//! let limit = roboat::Limit::Ten;
//! let cursor = None;
//!
//! let (resellers, _) = client.resellers(item_id, limit, cursor).await?;
//!
//! println!("Lowest Price for Valkyrie Helm: {}", resellers[0].price);
//!
//! Ok(())
//! }
//! ```
//!
//! ## Example 4 - Fetch Item Details
//!
//! This code snippet allows you to get the details of an item.
//!
//! ```no_run
//! use roboat::catalog::{Item, ItemType};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let client = roboat::ClientBuilder::new().build();
//!
//! let item = Item {
//! item_type: ItemType::Asset,
//! id: 1365767,
//! };
//!
//! let details = &client.item_details(vec![item]).await?[0];
//!
//! let name = &details.name;
//! let description = &details.description;
//! let creator_name = &details.creator_name;
//! let price = details.price.unwrap_or(0);
//!
//! println!("Name: {}", name);
//! println!("Description: {}", description);
//! println!("Creator Name: {}", creator_name);
//! println!("Price: {}", price);
//!
//! Ok(())
//! }
//! ```
// Re-export reqwest so people can use the correct version.
pub use reqwest;
use ;
pub use PurchaseNonTradableLimitedError;
pub use ;
pub use PurchaseTradableLimitedError;
///
/// A module for endpoints prefixed with <https://assetdelivery.roblox.com/*>
/// A module for endpoints prefixed with <https://auth.roblox.com/*>.
/// A module for endpoints prefixed with <https://apis.roblox.com/*>.
/// A module for endpoints prefixed with <https://catalog.roblox.com/*>.
/// A module for endpoints prefixed with <https://chat.roblox.com/*>.
/// A module related to the [`Client`] struct.
/// A module for endpoints prefixed with <https://clientsettings.roblox.com/*>.
/// A module for endpoints prefixed with <https://economy.roblox.com/*>.
/// A module for endpoints prefixed with <https://friends.roblox.com/*>.
/// A module for endpoints prefixed with <https://groups.roblox.com/*>.
/// A module for endpoints prefixed with <https://games.roblox.com/*>
/// A module for endpoints prefixed with <https://www.roblox.com/ide/*>
// This is used for private APIs like ide/uploadnewanimation and ide/places/createV2
/// A module for endpoints prefixed with <https://presence.roblox.com/*>.
/// A module for endpoints prefixed with <https://privatemessages.roblox.com/*>.
/// A module for endpoints prefixed with <https://thumbnails.roblox.com/*>.
/// A module for endpoints prefixed with <https://trades.roblox.com/*>.
/// A module for endpoints prefixed with <https://users.roblox.com/*>.
/// A module related to validating requests.
// todo: figure out authtickets
// todo: maybe respect cookies returned
// todo: maybe add stronger types for stuff like cursors? stuff that can be returned basically and is unlikely to cbe created by the user.
// todo: add doc example and example count somewhere
// todo: the roblox api docs show the roblox error codes, maybe a custom sub error can be made
// todo: add a "2 step not implemented for this endpoint" error
// Used in request header keys.
const XCSRF_HEADER: &str = "x-csrf-token";
// The user agent used for fussy endpoints.
const USER_AGENT: &str =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0";
// The content type used for fussy endpoints.
const CONTENT_TYPE: &str = "application/json;charset=utf-8";
/// The maximum amount of instances to return from an endpoint. Used as a parameter in various methods that call
/// endpoints.
///
/// This is an enum instead of an integer as these are usually the only values that are accepted by Roblox
/// for the limit parameter.
///
/// This is the most common limit used on Roblox endpoints. However, not all endpoints use this limit.
/// Some alternative limits are as follows:
/// * [`catalog::CatalogQueryLimit`]
/// The universal error used in this crate. Encapsulates any sub-errors used in this crate.
/// The type of the challenge required to complete a request.
/// This can be either a captcha or a two step verification code (can be an authenticator or an email).
/// The challenge info returned by Roblox when a challenge is required to complete a request.
/// This challenge can be either a two step verification code or a captcha. This is specified by the `challenge_type` field.
/// The universal struct for a Roblox user in this crate.