1mod calendars;
4pub mod events;
5mod mail;
6mod me;
7
8pub use calendars::list_calendars;
9pub use events::{
10 EventsPage, NewEvent, RsvpKind, cancel_event, create_event, delete_event, get_event,
11 list_calendar_view, move_event_to_calendar, move_time, rsvp_event, update_event,
12};
13pub use mail::{
14 InboxPage, MailFolder, Outgoing, add_attachment, create_child_folder, create_draft,
15 create_forward_draft, create_mail_folder, create_reply_all_draft, create_reply_draft,
16 delete_attachment, delete_mail_folder, delete_message, fetch_message_headers, forward_message,
17 get_attachment_bytes, get_message, list_attachments, list_child_folders, list_drafts,
18 list_folder_messages, list_inbox, list_mail_folders, mark_read, mark_unread, move_message,
19 reply_all_message, reply_message, search_messages, send_draft, send_mail, set_flag,
20 update_draft,
21};
22pub use me::{Me, get_me};
23
24use crate::auth::AuthClient;
25use crate::auth::config;
26use crate::error::ClientError;
27use pidge_core::Message;
28
29pub struct GraphClient {
31 auth: AuthClient,
32 http: reqwest::Client,
33 base_url: String,
34}
35
36impl GraphClient {
37 pub fn new(auth: AuthClient) -> Result<Self, ClientError> {
38 Ok(Self {
39 auth,
40 http: reqwest::Client::builder()
41 .user_agent(format!("pidge/{}", env!("CARGO_PKG_VERSION")))
42 .build()?,
43 base_url: config::GRAPH_BASE.to_string(),
44 })
45 }
46
47 pub fn for_test(auth: AuthClient, base_url: impl Into<String>) -> Self {
48 Self {
49 auth,
50 http: reqwest::Client::new(),
51 base_url: base_url.into(),
52 }
53 }
54
55 pub fn auth(&self) -> &AuthClient {
56 &self.auth
57 }
58
59 pub async fn me(&self, access_token: &str) -> Result<Me, ClientError> {
61 get_me(&self.http, &self.base_url, access_token).await
62 }
63
64 pub async fn list_inbox(
67 &self,
68 account: &str,
69 limit: usize,
70 skip: usize,
71 unread_only: bool,
72 ) -> Result<InboxPage, ClientError> {
73 let token = self.auth.get_valid_token(account).await?;
74 list_inbox(
75 &self.http,
76 &self.base_url,
77 &token,
78 account,
79 limit,
80 skip,
81 unread_only,
82 )
83 .await
84 }
85
86 pub async fn list_folder(
88 &self,
89 account: &str,
90 folder_id: &str,
91 limit: usize,
92 skip: usize,
93 unread_only: bool,
94 ) -> Result<InboxPage, ClientError> {
95 let token = self.auth.get_valid_token(account).await?;
96 list_folder_messages(
97 &self.http,
98 &self.base_url,
99 &token,
100 account,
101 folder_id,
102 limit,
103 skip,
104 unread_only,
105 )
106 .await
107 }
108
109 pub async fn search_messages(
111 &self,
112 account: &str,
113 query: &str,
114 limit: usize,
115 ) -> Result<Vec<Message>, ClientError> {
116 let token = self.auth.get_valid_token(account).await?;
117 search_messages(&self.http, &self.base_url, &token, account, query, limit).await
118 }
119
120 pub async fn mark_unread(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
122 let token = self.auth.get_valid_token(account).await?;
123 mail::mark_unread(&self.http, &self.base_url, &token, message_id).await
124 }
125
126 pub async fn set_flag(
128 &self,
129 account: &str,
130 message_id: &str,
131 flagged: bool,
132 ) -> Result<(), ClientError> {
133 let token = self.auth.get_valid_token(account).await?;
134 mail::set_flag(&self.http, &self.base_url, &token, message_id, flagged).await
135 }
136
137 pub async fn move_message(
139 &self,
140 account: &str,
141 message_id: &str,
142 destination: &str,
143 ) -> Result<(), ClientError> {
144 let token = self.auth.get_valid_token(account).await?;
145 mail::move_message(&self.http, &self.base_url, &token, message_id, destination).await
146 }
147
148 pub async fn list_mail_folders(&self, account: &str) -> Result<Vec<MailFolder>, ClientError> {
150 let token = self.auth.get_valid_token(account).await?;
151 mail::list_mail_folders(&self.http, &self.base_url, &token).await
152 }
153
154 pub async fn create_mail_folder(
156 &self,
157 account: &str,
158 display_name: &str,
159 ) -> Result<MailFolder, ClientError> {
160 let token = self.auth.get_valid_token(account).await?;
161 mail::create_mail_folder(&self.http, &self.base_url, &token, display_name).await
162 }
163
164 pub async fn list_child_folders(
166 &self,
167 account: &str,
168 parent_id: &str,
169 ) -> Result<Vec<MailFolder>, ClientError> {
170 let token = self.auth.get_valid_token(account).await?;
171 mail::list_child_folders(&self.http, &self.base_url, &token, parent_id).await
172 }
173
174 pub async fn create_child_folder(
176 &self,
177 account: &str,
178 parent_id: &str,
179 display_name: &str,
180 ) -> Result<MailFolder, ClientError> {
181 let token = self.auth.get_valid_token(account).await?;
182 mail::create_child_folder(&self.http, &self.base_url, &token, parent_id, display_name).await
183 }
184
185 pub async fn delete_mail_folder(
188 &self,
189 account: &str,
190 folder_id: &str,
191 ) -> Result<(), ClientError> {
192 let token = self.auth.get_valid_token(account).await?;
193 mail::delete_mail_folder(&self.http, &self.base_url, &token, folder_id).await
194 }
195
196 pub async fn send_mail(&self, account: &str, message: &Outgoing) -> Result<(), ClientError> {
198 let token = self.auth.get_valid_token(account).await?;
199 mail::send_mail(&self.http, &self.base_url, &token, message).await
200 }
201
202 pub async fn reply_message(
204 &self,
205 account: &str,
206 message_id: &str,
207 comment: &str,
208 ) -> Result<(), ClientError> {
209 let token = self.auth.get_valid_token(account).await?;
210 mail::reply_message(&self.http, &self.base_url, &token, message_id, comment).await
211 }
212
213 pub async fn reply_all_message(
215 &self,
216 account: &str,
217 message_id: &str,
218 comment: &str,
219 ) -> Result<(), ClientError> {
220 let token = self.auth.get_valid_token(account).await?;
221 mail::reply_all_message(&self.http, &self.base_url, &token, message_id, comment).await
222 }
223
224 pub async fn forward_message(
226 &self,
227 account: &str,
228 message_id: &str,
229 to: &[String],
230 comment: &str,
231 ) -> Result<(), ClientError> {
232 let token = self.auth.get_valid_token(account).await?;
233 mail::forward_message(&self.http, &self.base_url, &token, message_id, to, comment).await
234 }
235
236 pub async fn list_drafts(
238 &self,
239 account: &str,
240 limit: usize,
241 skip: usize,
242 ) -> Result<InboxPage, ClientError> {
243 let token = self.auth.get_valid_token(account).await?;
244 mail::list_drafts(&self.http, &self.base_url, &token, account, limit, skip).await
245 }
246
247 pub async fn create_draft(
249 &self,
250 account: &str,
251 message: &Outgoing,
252 ) -> Result<String, ClientError> {
253 let token = self.auth.get_valid_token(account).await?;
254 mail::create_draft(&self.http, &self.base_url, &token, message).await
255 }
256
257 pub async fn create_reply_draft(
259 &self,
260 account: &str,
261 message_id: &str,
262 comment: &str,
263 ) -> Result<String, ClientError> {
264 let token = self.auth.get_valid_token(account).await?;
265 mail::create_reply_draft(&self.http, &self.base_url, &token, message_id, comment).await
266 }
267
268 pub async fn create_reply_all_draft(
270 &self,
271 account: &str,
272 message_id: &str,
273 comment: &str,
274 ) -> Result<String, ClientError> {
275 let token = self.auth.get_valid_token(account).await?;
276 mail::create_reply_all_draft(&self.http, &self.base_url, &token, message_id, comment).await
277 }
278
279 pub async fn create_forward_draft(
281 &self,
282 account: &str,
283 message_id: &str,
284 to: &[String],
285 comment: &str,
286 ) -> Result<String, ClientError> {
287 let token = self.auth.get_valid_token(account).await?;
288 mail::create_forward_draft(&self.http, &self.base_url, &token, message_id, to, comment)
289 .await
290 }
291
292 pub async fn send_draft(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
294 let token = self.auth.get_valid_token(account).await?;
295 mail::send_draft(&self.http, &self.base_url, &token, message_id).await
296 }
297
298 pub async fn update_draft(
300 &self,
301 account: &str,
302 message_id: &str,
303 message: &Outgoing,
304 ) -> Result<(), ClientError> {
305 let token = self.auth.get_valid_token(account).await?;
306 mail::update_draft(&self.http, &self.base_url, &token, message_id, message).await
307 }
308
309 pub async fn delete_message(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
312 let token = self.auth.get_valid_token(account).await?;
313 mail::delete_message(&self.http, &self.base_url, &token, message_id).await
314 }
315
316 pub async fn add_attachment(
318 &self,
319 account: &str,
320 message_id: &str,
321 name: &str,
322 content_type: &str,
323 bytes: &[u8],
324 ) -> Result<String, ClientError> {
325 let token = self.auth.get_valid_token(account).await?;
326 mail::add_attachment(
327 &self.http,
328 &self.base_url,
329 &token,
330 message_id,
331 name,
332 content_type,
333 bytes,
334 )
335 .await
336 }
337
338 pub async fn delete_attachment(
340 &self,
341 account: &str,
342 message_id: &str,
343 attachment_id: &str,
344 ) -> Result<(), ClientError> {
345 let token = self.auth.get_valid_token(account).await?;
346 mail::delete_attachment(
347 &self.http,
348 &self.base_url,
349 &token,
350 message_id,
351 attachment_id,
352 )
353 .await
354 }
355
356 pub async fn get_message(
358 &self,
359 account: &str,
360 message_id: &str,
361 ) -> Result<pidge_core::FullMessage, ClientError> {
362 let token = self.auth.get_valid_token(account).await?;
363 mail::get_message(&self.http, &self.base_url, &token, account, message_id).await
364 }
365
366 pub async fn fetch_message_headers(
368 &self,
369 account: &str,
370 message_id: &str,
371 ) -> Result<Vec<(String, String)>, ClientError> {
372 let token = self.auth.get_valid_token(account).await?;
373 mail::fetch_message_headers(&self.http, &self.base_url, &token, message_id).await
374 }
375
376 pub async fn list_attachments(
378 &self,
379 account: &str,
380 message_id: &str,
381 ) -> Result<Vec<pidge_core::Attachment>, ClientError> {
382 let token = self.auth.get_valid_token(account).await?;
383 mail::list_attachments(&self.http, &self.base_url, &token, message_id).await
384 }
385
386 pub async fn get_attachment_bytes(
388 &self,
389 account: &str,
390 message_id: &str,
391 attachment_id: &str,
392 ) -> Result<Vec<u8>, ClientError> {
393 let token = self.auth.get_valid_token(account).await?;
394 mail::get_attachment_bytes(
395 &self.http,
396 &self.base_url,
397 &token,
398 message_id,
399 attachment_id,
400 )
401 .await
402 }
403
404 pub async fn mark_read(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
406 let token = self.auth.get_valid_token(account).await?;
407 mail::mark_read(&self.http, &self.base_url, &token, message_id).await
408 }
409
410 pub async fn list_calendars(
414 &self,
415 account: &str,
416 ) -> Result<Vec<pidge_core::Calendar>, ClientError> {
417 let token = self.auth.get_valid_token(account).await?;
418 calendars::list_calendars(&self.http, &self.base_url, &token, account).await
419 }
420
421 pub async fn list_calendar_view(
423 &self,
424 account: &str,
425 calendar_id: Option<&str>,
426 start: chrono::DateTime<chrono::Utc>,
427 end: chrono::DateTime<chrono::Utc>,
428 limit: usize,
429 ) -> Result<events::EventsPage, ClientError> {
430 let token = self.auth.get_valid_token(account).await?;
431 events::list_calendar_view(
432 &self.http,
433 &self.base_url,
434 &token,
435 account,
436 calendar_id,
437 start,
438 end,
439 limit,
440 )
441 .await
442 }
443
444 pub async fn get_event(
446 &self,
447 account: &str,
448 event_id: &str,
449 ) -> Result<pidge_core::Event, ClientError> {
450 let token = self.auth.get_valid_token(account).await?;
451 events::get_event(&self.http, &self.base_url, &token, account, event_id).await
452 }
453
454 pub async fn create_event(
456 &self,
457 account: &str,
458 calendar_id: Option<&str>,
459 new_event: &events::NewEvent,
460 ) -> Result<String, ClientError> {
461 let token = self.auth.get_valid_token(account).await?;
462 events::create_event(&self.http, &self.base_url, &token, calendar_id, new_event).await
463 }
464
465 pub async fn update_event(
467 &self,
468 account: &str,
469 event_id: &str,
470 new_event: &events::NewEvent,
471 ) -> Result<(), ClientError> {
472 let token = self.auth.get_valid_token(account).await?;
473 events::update_event(&self.http, &self.base_url, &token, event_id, new_event).await
474 }
475
476 pub async fn move_time(
478 &self,
479 account: &str,
480 event_id: &str,
481 start: chrono::DateTime<chrono::Utc>,
482 end: chrono::DateTime<chrono::Utc>,
483 tz: &str,
484 ) -> Result<(), ClientError> {
485 let token = self.auth.get_valid_token(account).await?;
486 events::move_time(&self.http, &self.base_url, &token, event_id, start, end, tz).await
487 }
488
489 pub async fn delete_event(&self, account: &str, event_id: &str) -> Result<(), ClientError> {
491 let token = self.auth.get_valid_token(account).await?;
492 events::delete_event(&self.http, &self.base_url, &token, event_id).await
493 }
494
495 pub async fn cancel_event(
497 &self,
498 account: &str,
499 event_id: &str,
500 comment: &str,
501 ) -> Result<(), ClientError> {
502 let token = self.auth.get_valid_token(account).await?;
503 events::cancel_event(&self.http, &self.base_url, &token, event_id, comment).await
504 }
505
506 pub async fn rsvp_event(
508 &self,
509 account: &str,
510 event_id: &str,
511 kind: events::RsvpKind,
512 comment: &str,
513 send_response: bool,
514 ) -> Result<(), ClientError> {
515 let token = self.auth.get_valid_token(account).await?;
516 events::rsvp_event(
517 &self.http,
518 &self.base_url,
519 &token,
520 event_id,
521 kind,
522 comment,
523 send_response,
524 )
525 .await
526 }
527
528 pub async fn move_event_to_calendar(
530 &self,
531 account: &str,
532 event_id: &str,
533 destination_calendar_id: &str,
534 ) -> Result<(), ClientError> {
535 let token = self.auth.get_valid_token(account).await?;
536 events::move_event_to_calendar(
537 &self.http,
538 &self.base_url,
539 &token,
540 event_id,
541 destination_calendar_id,
542 )
543 .await
544 }
545}