roblox_api/api/inventory/
v1.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{AssetTypeId, Error, Paging, client::Client};
4
5pub const URL: &str = "https://inventory.roblox.com/v1";
6
7#[repr(u8)]
8#[derive(Clone, Debug, Deserialize, Serialize)]
9pub enum ItemType {
10    Asset = 0,
11    Gamepass,
12    Badge,
13    Bundle,
14}
15
16#[derive(Clone, Debug, Deserialize)]
17pub struct AssetInfo {
18    pub id: u64,
19    #[serde(rename = "type")]
20    pub kind: String,
21    pub name: String,
22    #[serde(rename = "instanceId")]
23    pub instance_id: u64,
24}
25
26#[derive(Clone, Debug, Deserialize)]
27pub struct UserOwnsAssets {
28    #[serde(rename = "nextPageCursor")]
29    pub next_cursor: Option<String>,
30    #[serde(rename = "previousPageCursor")]
31    pub previous_cursor: Option<String>,
32    #[serde(rename = "data")]
33    pub assets: Vec<AssetInfo>,
34}
35
36#[derive(Clone, Debug, Deserialize)]
37pub struct CollectibleInfo {
38    #[serde(rename = "assetId")]
39    pub id: u64,
40    #[serde(rename = "originalPrice")]
41    pub original_price: u64,
42    #[serde(rename = "recentAveragePrice")]
43    pub recent_average_price: u64,
44    #[serde(rename = "assetStock")]
45    pub stock: u64,
46    #[serde(rename = "userAssetId")]
47    pub instance_id: u64,
48    pub name: String,
49    #[serde(rename = "buildersClubMembershipType")]
50    pub premium_membership_type: String,
51    #[serde(rename = "isOnHold")]
52    pub on_hold: bool,
53    #[serde(rename = "serialNumber")]
54    pub serial: Option<u64>,
55}
56
57#[derive(Clone, Debug, Deserialize)]
58pub struct UserOwnedCollectibles {
59    #[serde(rename = "nextPageCursor")]
60    pub next_cursor: Option<String>,
61    #[serde(rename = "previousPageCursor")]
62    pub previous_cursor: Option<String>,
63    #[serde(rename = "data")]
64    pub assets: Vec<CollectibleInfo>,
65}
66
67pub async fn can_view_inventory(client: &mut Client, user_id: u64) -> Result<bool, Error> {
68    let result = client
69        .requestor
70        .client
71        .get(format!("{URL}/users/{user_id}/can-view-inventory"))
72        .headers(client.requestor.default_headers.clone())
73        .send()
74        .await;
75
76    #[derive(Clone, Debug, Deserialize)]
77    struct Response {
78        #[serde(rename = "canView")]
79        can_view: bool,
80    }
81
82    let response = client.validate_response(result).await?;
83    Ok(client
84        .requestor
85        .parse_json::<Response>(response)
86        .await?
87        .can_view)
88}
89
90pub async fn user_owns_assets(
91    client: &mut Client,
92    user_id: u64,
93    id: u64,
94    item_type: ItemType,
95    paging: Paging<'_>,
96) -> Result<UserOwnsAssets, Error> {
97    let item_type = item_type as u8;
98
99    let cursor = match paging.cursor {
100        Some(cursor) => cursor.to_string(),
101        None => String::new(),
102    };
103
104    let result = client
105        .requestor
106        .client
107        .get(format!("{URL}/users/{user_id}/items/{item_type}/{id}"))
108        .query(&[("cursor", cursor)])
109        .headers(client.requestor.default_headers.clone())
110        .send()
111        .await;
112
113    let response = client.validate_response(result).await?;
114    client
115        .requestor
116        .parse_json::<UserOwnsAssets>(response)
117        .await
118}
119
120pub async fn user_owned_collectibles(
121    client: &mut Client,
122    user_id: u64,
123    asset_type_id: Option<AssetTypeId>,
124    paging: Paging<'_>,
125) -> Result<UserOwnedCollectibles, Error> {
126    let limit = paging.limit.unwrap_or(10).to_string();
127    let sort_order = paging.order.unwrap_or_default().to_string();
128    let cursor = match paging.cursor {
129        Some(cursor) => cursor.to_string(),
130        None => String::new(),
131    };
132
133    let asset_type = match asset_type_id {
134        Some(id) => {
135            let id = id as u8;
136            id.to_string()
137        }
138        None => String::new(),
139    };
140
141    let result = client
142        .requestor
143        .client
144        .get(format!("{URL}/users/{user_id}/assets/collectibles"))
145        .query(&[
146            ("assetType", asset_type),
147            ("limit", limit),
148            ("sortOrder", sort_order),
149            ("cursor", cursor),
150        ])
151        .headers(client.requestor.default_headers.clone())
152        .send()
153        .await;
154
155    let response = client.validate_response(result).await?;
156    client
157        .requestor
158        .parse_json::<UserOwnedCollectibles>(response)
159        .await
160}