1use crate::util::QueryBuilder;
2use serde::{Deserialize, Serialize};
3
4use super::{Attachment, SendAttachment};
5
6#[derive(Clone, Debug, Default, Serialize)]
9pub struct SendMessage {
10 #[serde(skip_serializing_if = "Vec::is_empty")]
12 pub to: Vec<String>,
13 #[serde(skip_serializing_if = "Vec::is_empty")]
15 pub cc: Vec<String>,
16 #[serde(skip_serializing_if = "Vec::is_empty")]
18 pub bcc: Vec<String>,
19 #[serde(skip_serializing_if = "Option::is_none")]
21 pub subject: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub text: Option<String>,
25 #[serde(skip_serializing_if = "Option::is_none")]
27 pub html: Option<String>,
28 #[serde(skip_serializing_if = "Vec::is_empty")]
30 pub labels: Vec<String>,
31 #[serde(skip_serializing_if = "Vec::is_empty")]
33 pub reply_to: Vec<String>,
34 #[serde(skip_serializing_if = "Vec::is_empty")]
36 pub attachments: Vec<SendAttachment>,
37 #[serde(skip_serializing_if = "Option::is_none")]
39 pub headers: Option<serde_json::Value>,
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub track_opens: Option<bool>,
43}
44#[derive(Clone, Debug, Deserialize)]
46pub struct SentMessage {
47 pub message_id: String,
49 pub thread_id: String,
51}
52#[derive(Clone, Debug, Default, Serialize)]
56pub struct ReplyToMessage {
57 #[serde(skip_serializing_if = "Vec::is_empty")]
59 pub to: Vec<String>,
60 #[serde(skip_serializing_if = "Option::is_none")]
63 pub reply_all: Option<bool>,
64 #[serde(skip_serializing_if = "Vec::is_empty")]
66 pub cc: Vec<String>,
67 #[serde(skip_serializing_if = "Vec::is_empty")]
69 pub bcc: Vec<String>,
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub text: Option<String>,
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub html: Option<String>,
76 #[serde(skip_serializing_if = "Vec::is_empty")]
78 pub labels: Vec<String>,
79 #[serde(skip_serializing_if = "Vec::is_empty")]
81 pub attachments: Vec<SendAttachment>,
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub headers: Option<serde_json::Value>,
85 #[serde(skip_serializing_if = "Option::is_none")]
87 pub track_opens: Option<bool>,
88}
89
90#[derive(Clone, Debug, Deserialize)]
93pub struct RawMessage {
94 pub message_id: String,
96 #[serde(default)]
98 pub size: Option<u64>,
99 pub download_url: String,
101 #[serde(default)]
103 pub expires_at: Option<String>,
104}
105
106#[derive(Clone, Debug, Default, Serialize)]
108pub struct BatchGetMessages {
109 pub message_ids: Vec<String>,
111}
112
113#[derive(Clone, Debug, Deserialize)]
115pub struct BatchGetMessagesResponse {
116 pub count: u64,
118 #[serde(default)]
120 pub messages: Vec<Message>,
121}
122
123#[derive(Clone, Debug, Default, Serialize)]
126pub struct BatchUpdateMessages {
127 pub message_ids: Vec<String>,
129 #[serde(skip_serializing_if = "Vec::is_empty")]
131 pub add_labels: Vec<String>,
132 #[serde(skip_serializing_if = "Vec::is_empty")]
134 pub remove_labels: Vec<String>,
135}
136
137#[derive(Clone, Debug, Deserialize)]
139pub struct BatchUpdateMessagesResponse {
140 pub count: u64,
142 #[serde(default)]
144 pub updates: Vec<UpdatedMessage>,
145}
146#[derive(Clone, Debug, Default, Serialize)]
148pub struct UpdateMessage {
149 #[serde(skip_serializing_if = "Vec::is_empty")]
151 pub add_labels: Vec<String>,
152 #[serde(skip_serializing_if = "Vec::is_empty")]
154 pub remove_labels: Vec<String>,
155}
156#[derive(Clone, Debug, Deserialize)]
159pub struct UpdatedMessage {
160 pub message_id: String,
162 #[serde(default)]
164 pub labels: Vec<String>,
165}
166#[derive(Clone, Debug, Deserialize)]
169pub struct Message {
170 pub message_id: String,
172 #[serde(default)]
174 pub inbox_id: Option<String>,
175 #[serde(default)]
177 pub thread_id: Option<String>,
178 #[serde(default)]
180 pub from: Option<String>,
181 #[serde(default)]
183 pub to: Vec<String>,
184 #[serde(default)]
186 pub reply_to: Vec<String>,
187 #[serde(default)]
189 pub cc: Vec<String>,
190 #[serde(default)]
192 pub bcc: Vec<String>,
193 #[serde(default)]
195 pub subject: Option<String>,
196 #[serde(default)]
198 pub preview: Option<String>,
199 #[serde(default)]
201 pub text: Option<String>,
202 #[serde(default)]
204 pub html: Option<String>,
205 #[serde(default)]
207 pub extracted_text: Option<String>,
208 #[serde(default)]
210 pub extracted_html: Option<String>,
211 #[serde(default)]
213 pub labels: Vec<String>,
214 #[serde(default)]
216 pub timestamp: Option<String>,
217 #[serde(default)]
219 pub attachments: Vec<Attachment>,
220 #[serde(default)]
222 pub in_reply_to: Option<String>,
223 #[serde(default)]
225 pub references: Vec<String>,
226 #[serde(default)]
228 pub headers: Option<serde_json::Value>,
229 #[serde(default)]
231 pub calendar_event_id: Option<String>,
232 #[serde(default)]
234 pub size: Option<u64>,
235 #[serde(default)]
237 pub updated_at: Option<String>,
238 #[serde(default)]
240 pub created_at: Option<String>,
241 #[serde(default)]
243 pub highlights: Option<serde_json::Value>,
244}
245#[derive(Clone, Debug, Deserialize)]
247pub struct MessageList {
248 pub count: u64,
250 #[serde(default)]
252 pub messages: Vec<Message>,
253 #[serde(default)]
255 pub next_page_token: Option<String>,
256}
257#[derive(Clone, Debug, Default)]
262pub struct MessageListFilters {
263 pub limit: Option<u32>,
265 pub page_token: Option<String>,
267 pub labels: Vec<String>,
269 pub before: Option<String>,
271 pub after: Option<String>,
273 pub ascending: Option<bool>,
275 pub include_spam: Option<bool>,
277 pub include_blocked: Option<bool>,
279 pub include_unauthenticated: Option<bool>,
281 pub include_trash: Option<bool>,
283 pub from: Vec<String>,
285 pub to: Vec<String>,
287 pub subject: Vec<String>,
289}
290impl MessageListFilters {
291 pub(crate) fn query(&self) -> Vec<(&'static str, String)> {
292 QueryBuilder::new()
293 .opt("limit", self.limit.as_ref())
294 .opt("page_token", self.page_token.as_ref())
295 .many("labels", &self.labels)
296 .opt("before", self.before.as_ref())
297 .opt("after", self.after.as_ref())
298 .opt("ascending", self.ascending.as_ref())
299 .opt("include_spam", self.include_spam.as_ref())
300 .opt("include_blocked", self.include_blocked.as_ref())
301 .opt(
302 "include_unauthenticated",
303 self.include_unauthenticated.as_ref(),
304 )
305 .opt("include_trash", self.include_trash.as_ref())
306 .many("from", &self.from)
307 .many("to", &self.to)
308 .many("subject", &self.subject)
309 .build()
310 }
311}