roblox_api/api/gamepasses/
v1.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{DateTime, Error, Paging, client::Client};
4
5pub const URL: &str = "https://apis.roblox.com/game-passes/v1";
6
7#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
8pub enum CreatorType {
9    User,
10    Group,
11}
12
13#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
14#[serde(rename_all = "PascalCase")]
15pub struct Creator {
16    pub id: u64,
17    pub name: String,
18    #[serde(rename = "CreatorType")]
19    pub kind: CreatorType,
20    #[serde(rename = "CreatorTargetId")]
21    pub target_id: u64,
22}
23
24#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
25#[serde(rename_all = "camelCase")]
26pub struct GamepassCreator {
27    #[serde(rename = "creatorId")]
28    pub id: u64,
29    pub name: String,
30    #[serde(rename = "creatorType")]
31    pub kind: CreatorType,
32}
33
34#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
35#[serde(rename_all = "camelCase")]
36pub struct Gamepass {
37    #[serde(rename = "gamePassId")]
38    pub id: u64,
39    pub name: String,
40    pub description: String,
41
42    #[serde(rename = "iconAssetId")]
43    pub icon_image_id: Option<u64>,
44
45    pub price: Option<u64>,
46    #[serde(rename = "isForSale")]
47    pub on_sale: bool,
48    pub creator: GamepassCreator,
49}
50
51#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
52#[serde(rename_all = "camelCase")]
53pub struct PriceInformation {
54    #[serde(rename = "defaultPriceInRobux")]
55    pub price_in_robux: u64,
56    pub enabled_features: Vec<String>, // Such as RegionalPricing
57}
58
59#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
60#[serde(rename_all = "camelCase")]
61pub struct GamepassDetails {
62    #[serde(rename = "gamePassId")]
63    pub id: u64,
64    pub name: String,
65    pub description: String,
66
67    pub place_id: u64,
68    #[serde(rename = "iconAssetId")]
69    pub icon_image_id: u64,
70
71    #[serde(rename = "createdTimestamp")]
72    pub created: DateTime,
73    #[serde(rename = "updatedTimestamp")]
74    pub updated: DateTime,
75
76    #[serde(rename = "isForSale")]
77    pub on_sale: bool,
78    pub price_information: PriceInformation,
79}
80
81#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
82#[serde(rename_all = "PascalCase")]
83pub struct GamepassProductInformation {
84    #[serde(rename = "TargetId")]
85    pub id: u64,
86    pub asset_id: u64,
87    pub product_id: u64,
88
89    pub name: String,
90    pub description: String,
91
92    pub product_type: String,
93    pub asset_type_id: u8, // seems to be 0?
94
95    pub creator: Creator,
96
97    #[serde(rename = "IconImageAssetId")]
98    pub icon_image_id: u64,
99
100    pub created: DateTime,
101    pub updated: DateTime,
102
103    #[serde(rename = "PriceInRobux")]
104    pub robux_price: Option<u64>,
105    #[serde(rename = "PriceInTickets")]
106    pub tickets_price: Option<u64>,
107
108    pub sales: u64,
109    pub remaining: Option<u64>,
110
111    #[serde(rename = "IsForSale")]
112    pub on_sale: bool,
113
114    pub is_new: bool,
115    pub is_public_domain: bool,
116    pub is_limited: bool,
117    pub is_limited_unique: bool,
118
119    pub minimum_membership_level: u8,
120}
121
122pub async fn details(client: &mut Client, id: u64) -> Result<GamepassDetails, Error> {
123    let result = client
124        .requestor
125        .client
126        .get(format!("{URL}/game-passes/{id}/details"))
127        .headers(client.requestor.default_headers.clone())
128        .send()
129        .await;
130
131    let response = client.validate_response(result).await?;
132    client
133        .requestor
134        .parse_json::<GamepassDetails>(response)
135        .await
136}
137
138pub async fn product_information(
139    client: &mut Client,
140    id: u64,
141) -> Result<GamepassProductInformation, Error> {
142    let result = client
143        .requestor
144        .client
145        .get(format!("{URL}/game-passes/{id}/product-info"))
146        .headers(client.requestor.default_headers.clone())
147        .send()
148        .await;
149
150    let response = client.validate_response(result).await?;
151    client
152        .requestor
153        .parse_json::<GamepassProductInformation>(response)
154        .await
155}
156
157/// The cursor is the gamepass_id you want to start from
158pub async fn user_gamepasses(
159    client: &mut Client,
160    id: u64,
161    paging: Paging<'_>,
162) -> Result<Vec<Gamepass>, Error> {
163    let limit = paging.limit.unwrap_or(100).to_string();
164    let cursor = match paging.cursor {
165        Some(cursor) => cursor.to_string(),
166        None => String::new(),
167    };
168
169    let result = client
170        .requestor
171        .client
172        .get(format!("{URL}/users/{id}/game-passes"))
173        .query(&[("count", limit), ("exclusiveStartId", cursor)])
174        .headers(client.requestor.default_headers.clone())
175        .send()
176        .await;
177
178    #[derive(Debug, Deserialize)]
179    struct Response {
180        #[serde(rename = "gamePasses")]
181        gamepasses: Vec<Gamepass>,
182    }
183
184    let response = client.validate_response(result).await?;
185    Ok(client
186        .requestor
187        .parse_json::<Response>(response)
188        .await?
189        .gamepasses)
190}