roblox_api/api/notifications/
v2.rs1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{DateTime, Error, Paging, client::Client};
6
7pub const URL: &str = "https://notifications.roblox.com/v2";
8
9#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
10#[serde(rename_all = "camelCase")]
11pub struct NotificationUnreadCount {
12 #[serde(rename = "unreadNotifications")]
13 pub count: u64,
14 pub status_message: Option<String>,
15}
16
17#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
18#[serde(rename_all = "camelCase")]
19pub struct ClientEventsPayload {
20 #[serde(rename = "sender_userid")]
21 pub sender_user_id: Option<String>, pub place_id: Option<String>, pub root_place_id: Option<String>, pub universe_id: Option<String>, pub trigger: Option<String>,
26}
27
28#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
29pub enum VisualItemType {
30 Button,
31 TextBody,
32 Thumbnail,
33 MetaAction,
34}
35
36#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
37#[serde(rename_all = "camelCase")]
38pub struct VisualItemAction {
39 pub path: String,
40 pub next_state: String, pub action_type: String, pub fallback_state: String, }
44
45#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
46#[serde(rename_all = "camelCase")]
47pub struct StyledText {
48 pub text: String,
49 pub styled_elements: Vec<StyledElement>,
50}
51
52#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
53#[serde(rename_all = "camelCase")]
54pub struct StyledElement {
55 #[serde(rename = "styledElementType")]
56 pub kind: String, pub offset: i32,
58 pub length: u32,
59}
60
61#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
62#[serde(rename_all = "camelCase")]
63pub struct VisualItemTextBody {
64 #[serde(rename = "visualItemType")]
65 pub kind: VisualItemType,
66 pub label: StyledText,
67 pub title: Option<StyledText>,
68 pub actions: Vec<VisualItemAction>,
69
70 pub event_name: String,
71 pub client_events_payload: ClientEventsPayload,
72}
73
74#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
75#[serde(rename_all = "camelCase")]
76pub struct VisualItemButton {
77 #[serde(rename = "visualItemName")]
78 pub name: String,
79
80 #[serde(rename = "visualItemType")]
81 pub kind: VisualItemType,
82 pub label: StyledText,
83 pub actions: Vec<VisualItemAction>,
84
85 pub button_style: String, pub event_name: String,
87 pub client_events_payload: ClientEventsPayload,
88}
89
90#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
91#[serde(rename_all = "camelCase")]
92pub struct VisualItemThumbnail {
93 pub id: String,
94 pub id_type: String, #[serde(rename = "visualItemType")]
97 pub kind: VisualItemType,
98}
99
100#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
101#[serde(rename_all = "camelCase")]
102pub struct VisualItemMetaAction {
103 #[serde(rename = "visualItemName")]
104 pub name: String,
105
106 #[serde(rename = "visualItemType")]
107 pub kind: VisualItemType,
108 pub label: StyledText,
109 pub actions: Vec<VisualItemAction>,
110
111 pub action_icon: String, pub event_name: String,
113 pub client_events_payload: ClientEventsPayload,
114}
115
116#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
117#[serde(rename_all = "camelCase")]
118pub struct VisualItems {
119 pub button: Vec<VisualItemButton>,
120 pub text_body: Vec<VisualItemTextBody>,
121 pub thumbnail: Vec<VisualItemThumbnail>,
122 pub meta_action: Vec<VisualItemMetaAction>,
123}
124
125#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
126#[serde(rename_all = "camelCase")]
127pub struct NotificationContentStateDefault {
128 pub layout_key: String, pub visual_items: VisualItems,
130}
131
132#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
133#[serde(rename_all = "camelCase")]
134pub struct NotificationContent {
135 pub notification_type: String, pub min_version: String,
138 pub time_before_refresh: String, pub client_events_payload: ClientEventsPayload,
140 pub bundle_key: String,
141
142 pub current_state: String, pub states: HashMap<String, NotificationContentStateDefault>,
144}
145
146#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
147#[serde(rename_all = "camelCase")]
148pub struct Notification {
149 pub id: String,
150 pub notification_source_type: String, pub event_date: DateTime,
152 pub timestamp: String,
153 pub is_interacted: bool,
154
155 pub metadata_collection: Vec<u64>,
156 pub event_count: u64,
157
158 pub content: NotificationContent,
159}
160
161pub async fn unread_count(client: &mut Client) -> Result<NotificationUnreadCount, Error> {
162 let result = client
163 .requestor
164 .client
165 .get(format!("{URL}/stream-notifications/unread-count"))
166 .headers(client.requestor.default_headers.clone())
167 .send()
168 .await;
169
170 let response = client.validate_response(result).await?;
171 client
172 .requestor
173 .parse_json::<NotificationUnreadCount>(response)
174 .await
175}
176
177pub async fn recent(client: &mut Client, paging: Paging<'_>) -> Result<Vec<Notification>, Error> {
178 let limit = paging.limit.unwrap_or(20).to_string();
179 let cursor = match paging.cursor {
180 Some(cursor) => cursor.to_string(),
181 None => String::new(),
182 };
183
184 let result = client
185 .requestor
186 .client
187 .get(format!("{URL}/stream-notifications/get-recent"))
188 .query(&[("maxRows", limit), ("startIndex", cursor)])
189 .headers(client.requestor.default_headers.clone())
190 .send()
191 .await;
192
193 let response = client.validate_response(result).await?;
194 client
195 .requestor
196 .parse_json::<Vec<Notification>>(response)
197 .await
198}
199
200pub async fn clear_unread(client: &mut Client) -> Result<String, Error> {
201 let result = client
202 .requestor
203 .client
204 .post(format!("{URL}/stream-notifications/clear-unread"))
205 .headers(client.requestor.default_headers.clone())
206 .send()
207 .await;
208
209 #[derive(Debug, Deserialize)]
210 #[serde(rename_all = "camelCase")]
211 struct Response {
212 status_message: String,
213 }
214
215 let response = client.validate_response(result).await?;
216 Ok(client
217 .requestor
218 .parse_json::<Response>(response)
219 .await?
220 .status_message)
221}
222
223pub async fn dismiss(client: &mut Client, id: String) -> Result<String, Error> {
224 let result = client
225 .requestor
226 .client
227 .post(format!(
228 "{URL}/stream-notifications/clear-unread/action/{id}/SpecialItemIgnoreAction"
229 ))
230 .headers(client.requestor.default_headers.clone())
231 .send()
232 .await;
233
234 #[derive(Debug, Deserialize)]
235 #[serde(rename_all = "camelCase")]
236 struct Response {
237 status_message: String,
238 }
239
240 let response = client.validate_response(result).await?;
241 Ok(client
242 .requestor
243 .parse_json::<Response>(response)
244 .await?
245 .status_message)
246}