roblox_api/api/private_messages/
v1.rs1use serde::{Deserialize, Serialize};
2
3use crate::{DateTime, Error, Paging, client::Client};
4
5pub const URL: &str = "https://privatemessages.roblox.com/v1";
6
7#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
8#[serde(rename_all = "lowercase")]
9pub enum MessageTab {
10 #[default]
11 Inbox,
12 Sent,
13 Archive,
14}
15
16#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
17#[serde(rename_all = "camelCase")]
18pub struct User {
19 pub id: u64,
20 pub name: String,
21 pub display_name: String,
22 #[serde(rename = "hasVerifiedBadge")]
23 pub is_verified: bool,
24}
25
26#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
27#[serde(rename_all = "camelCase")]
28pub struct Message {
29 pub id: u64,
30 pub subject: String,
31 pub body: String,
32
33 pub sender: User,
34 pub recipient: User,
35
36 pub created: DateTime,
37 pub updated: DateTime,
38
39 pub is_read: bool,
40 pub is_system_message: bool,
41 pub is_report_abuse_displayed: bool,
42}
43
44#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
45pub struct Announcement {
46 pub id: u64,
47 pub subject: String,
48 pub body: String,
49
50 pub sender: User,
51
52 pub created: DateTime,
53 pub updated: DateTime,
54}
55
56#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
57#[serde(rename_all = "camelCase")]
58pub struct Announcements {
59 pub collection: Vec<Announcement>,
60 pub total_collection_size: u64,
61}
62
63#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
64#[serde(rename_all = "camelCase")]
65pub struct Messages {
66 pub collection: Vec<Message>,
67 pub total_collection_size: u64,
68 pub total_pages: u64,
69 #[serde(rename = "pageNumber")]
70 pub current_page: u64,
71}
72
73impl std::fmt::Display for MessageTab {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 write!(
76 f,
77 "{}",
78 match self {
79 MessageTab::Inbox => "inbox",
80 MessageTab::Sent => "sent",
81 MessageTab::Archive => "archive",
82 }
83 )
84 }
85}
86
87async fn generic_message_action(
88 client: &mut Client,
89 path: &str,
90 ids: &[u64],
91) -> Result<Vec<u64>, Error> {
92 #[derive(Debug, Serialize)]
93 struct Request<'a> {
94 #[serde(rename = "messageIds")]
95 ids: &'a [u64],
96 }
97
98 let result = client
99 .requestor
100 .client
101 .post(format!("{URL}/messages/{path}"))
102 .json(&Request { ids })
103 .headers(client.requestor.default_headers.clone())
104 .send()
105 .await;
106
107 #[derive(Debug, Deserialize)]
108 struct Response {
109 #[serde(rename = "failedMessages")]
110 failed: Vec<u64>,
111 }
112
113 let response = client.validate_response(result).await?;
114 Ok(client
115 .requestor
116 .parse_json::<Response>(response)
117 .await?
118 .failed)
119}
120
121pub async fn unread_count(client: &mut Client) -> Result<u64, Error> {
122 let result = client
123 .requestor
124 .client
125 .get(format!("{URL}/messages/unread/count"))
126 .headers(client.requestor.default_headers.clone())
127 .send()
128 .await;
129
130 #[derive(Debug, Deserialize)]
131 struct Response {
132 count: u64,
133 }
134
135 let response = client.validate_response(result).await?;
136 Ok(client
137 .requestor
138 .parse_json::<Response>(response)
139 .await?
140 .count)
141}
142
143pub async fn messages(
145 client: &mut Client,
146 tab: MessageTab,
147 paging: Paging<'_>,
148) -> Result<Messages, Error> {
149 let limit = paging.limit.unwrap_or(100).to_string();
150 let cursor = match paging.cursor {
151 Some(cursor) => cursor.to_string(),
152 None => String::new(),
153 };
154
155 let result = client
156 .requestor
157 .client
158 .get(format!("{URL}/messages"))
159 .query(&[
160 ("messageTab", tab.to_string()),
161 ("pageNumber", cursor),
162 ("pageSize", limit),
163 ])
164 .headers(client.requestor.default_headers.clone())
165 .send()
166 .await;
167
168 let response = client.validate_response(result).await?;
169 client.requestor.parse_json::<Messages>(response).await
170}
171
172pub async fn announcements(client: &mut Client) -> Result<Announcements, Error> {
173 let result = client
174 .requestor
175 .client
176 .get(format!("{URL}/announcements"))
177 .headers(client.requestor.default_headers.clone())
178 .send()
179 .await;
180
181 let response = client.validate_response(result).await?;
182 client.requestor.parse_json::<Announcements>(response).await
183}
184
185pub async fn archive(client: &mut Client, ids: &[u64]) -> Result<Vec<u64>, Error> {
186 generic_message_action(client, "archive", ids).await
187}
188
189pub async fn unarchive(client: &mut Client, ids: &[u64]) -> Result<Vec<u64>, Error> {
190 generic_message_action(client, "unarchive", ids).await
191}
192
193pub async fn mark_as_read(client: &mut Client, ids: &[u64]) -> Result<Vec<u64>, Error> {
194 generic_message_action(client, "mark-read", ids).await
195}
196
197pub async fn mark_as_unread(client: &mut Client, ids: &[u64]) -> Result<Vec<u64>, Error> {
198 generic_message_action(client, "mark-unread", ids).await
199}