Skip to main content

roblox_api/api/private_messages/
v1.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{DateTime, Paging, endpoint};
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
87endpoint! {
88    unread_count() -> u64 {
89        GET "{URL}/messages/unread/count";
90        types { CountResponse { count: u64 } }
91        map |r: CountResponse| r.count
92    }
93
94    /// The paging cursor is a page number
95    messages(tab: MessageTab, paging: Paging<'_>) -> Messages {
96        GET "{URL}/messages";
97        prelude {
98            let tab = tab.to_string();
99            let limit = paging.limit.unwrap_or(100).to_string();
100            let cursor = paging.cursor.map_or(String::new(), |c| c.to_string());
101        }
102        query {
103            "messageTab" => &tab,
104            "pageNumber" => &cursor,
105            "pageSize" => &limit
106        }
107    }
108
109    announcements() -> Announcements {
110        GET "{URL}/announcements";
111    }
112
113    archive(ids: &[u64]) -> Vec<u64> {
114        POST "{URL}/messages/archive";
115        types {
116            Request<'a> { message_ids("messageIds"): &'a [u64] }
117            ActionResponse { failed("failedMessages"): Vec<u64> }
118        }
119        body_serialize { Request { message_ids: ids } }
120        map |r: ActionResponse| r.failed
121    }
122
123    unarchive(ids: &[u64]) -> Vec<u64> {
124        POST "{URL}/messages/unarchive";
125        types {
126            Request<'a> { message_ids("messageIds"): &'a [u64] }
127            ActionResponse { failed("failedMessages"): Vec<u64> }
128        }
129        body_serialize { Request { message_ids: ids } }
130        map |r: ActionResponse| r.failed
131    }
132
133    mark_as_read(ids: &[u64]) -> Vec<u64> {
134        POST "{URL}/messages/mark-read";
135        types {
136            Request<'a> { message_ids("messageIds"): &'a [u64] }
137            ActionResponse { failed("failedMessages"): Vec<u64> }
138        }
139        body_serialize { Request { message_ids: ids } }
140        map |r: ActionResponse| r.failed
141    }
142
143    mark_as_unread(ids: &[u64]) -> Vec<u64> {
144        POST "{URL}/messages/mark-unread";
145        types {
146            Request<'a> { message_ids("messageIds"): &'a [u64] }
147            ActionResponse { failed("failedMessages"): Vec<u64> }
148        }
149        body_serialize { Request { message_ids: ids } }
150        map |r: ActionResponse| r.failed
151    }
152}