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_categories, get_message, list_attachments, list_child_folders,
18 list_drafts, list_folder_messages, list_inbox, list_mail_folders, mark_read, mark_unread,
19 move_message, reply_all_message, reply_message, search_messages, send_draft, send_mail,
20 set_categories, set_flag, 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 get_categories(
139 &self,
140 account: &str,
141 message_id: &str,
142 ) -> Result<Vec<String>, ClientError> {
143 let token = self.auth.get_valid_token(account).await?;
144 mail::get_categories(&self.http, &self.base_url, &token, message_id).await
145 }
146
147 pub async fn set_categories(
149 &self,
150 account: &str,
151 message_id: &str,
152 categories: &[String],
153 ) -> Result<(), ClientError> {
154 let token = self.auth.get_valid_token(account).await?;
155 mail::set_categories(&self.http, &self.base_url, &token, message_id, categories).await
156 }
157
158 pub async fn move_message(
160 &self,
161 account: &str,
162 message_id: &str,
163 destination: &str,
164 ) -> Result<(), ClientError> {
165 let token = self.auth.get_valid_token(account).await?;
166 mail::move_message(&self.http, &self.base_url, &token, message_id, destination).await
167 }
168
169 pub async fn list_mail_folders(&self, account: &str) -> Result<Vec<MailFolder>, ClientError> {
171 let token = self.auth.get_valid_token(account).await?;
172 mail::list_mail_folders(&self.http, &self.base_url, &token).await
173 }
174
175 pub async fn create_mail_folder(
177 &self,
178 account: &str,
179 display_name: &str,
180 ) -> Result<MailFolder, ClientError> {
181 let token = self.auth.get_valid_token(account).await?;
182 mail::create_mail_folder(&self.http, &self.base_url, &token, display_name).await
183 }
184
185 pub async fn list_child_folders(
187 &self,
188 account: &str,
189 parent_id: &str,
190 ) -> Result<Vec<MailFolder>, ClientError> {
191 let token = self.auth.get_valid_token(account).await?;
192 mail::list_child_folders(&self.http, &self.base_url, &token, parent_id).await
193 }
194
195 pub async fn create_child_folder(
197 &self,
198 account: &str,
199 parent_id: &str,
200 display_name: &str,
201 ) -> Result<MailFolder, ClientError> {
202 let token = self.auth.get_valid_token(account).await?;
203 mail::create_child_folder(&self.http, &self.base_url, &token, parent_id, display_name).await
204 }
205
206 pub async fn delete_mail_folder(
209 &self,
210 account: &str,
211 folder_id: &str,
212 ) -> Result<(), ClientError> {
213 let token = self.auth.get_valid_token(account).await?;
214 mail::delete_mail_folder(&self.http, &self.base_url, &token, folder_id).await
215 }
216
217 pub async fn send_mail(&self, account: &str, message: &Outgoing) -> Result<(), ClientError> {
219 let token = self.auth.get_valid_token(account).await?;
220 mail::send_mail(&self.http, &self.base_url, &token, message).await
221 }
222
223 pub async fn reply_message(
225 &self,
226 account: &str,
227 message_id: &str,
228 comment: &str,
229 ) -> Result<(), ClientError> {
230 let token = self.auth.get_valid_token(account).await?;
231 mail::reply_message(&self.http, &self.base_url, &token, message_id, comment).await
232 }
233
234 pub async fn reply_all_message(
236 &self,
237 account: &str,
238 message_id: &str,
239 comment: &str,
240 ) -> Result<(), ClientError> {
241 let token = self.auth.get_valid_token(account).await?;
242 mail::reply_all_message(&self.http, &self.base_url, &token, message_id, comment).await
243 }
244
245 pub async fn forward_message(
247 &self,
248 account: &str,
249 message_id: &str,
250 to: &[String],
251 comment: &str,
252 ) -> Result<(), ClientError> {
253 let token = self.auth.get_valid_token(account).await?;
254 mail::forward_message(&self.http, &self.base_url, &token, message_id, to, comment).await
255 }
256
257 pub async fn list_drafts(
259 &self,
260 account: &str,
261 limit: usize,
262 skip: usize,
263 ) -> Result<InboxPage, ClientError> {
264 let token = self.auth.get_valid_token(account).await?;
265 mail::list_drafts(&self.http, &self.base_url, &token, account, limit, skip).await
266 }
267
268 pub async fn create_draft(
270 &self,
271 account: &str,
272 message: &Outgoing,
273 ) -> Result<String, ClientError> {
274 let token = self.auth.get_valid_token(account).await?;
275 mail::create_draft(&self.http, &self.base_url, &token, message).await
276 }
277
278 pub async fn create_reply_draft(
280 &self,
281 account: &str,
282 message_id: &str,
283 comment: &str,
284 ) -> Result<String, ClientError> {
285 let token = self.auth.get_valid_token(account).await?;
286 mail::create_reply_draft(&self.http, &self.base_url, &token, message_id, comment).await
287 }
288
289 pub async fn create_reply_all_draft(
291 &self,
292 account: &str,
293 message_id: &str,
294 comment: &str,
295 ) -> Result<String, ClientError> {
296 let token = self.auth.get_valid_token(account).await?;
297 mail::create_reply_all_draft(&self.http, &self.base_url, &token, message_id, comment).await
298 }
299
300 pub async fn create_forward_draft(
302 &self,
303 account: &str,
304 message_id: &str,
305 to: &[String],
306 comment: &str,
307 ) -> Result<String, ClientError> {
308 let token = self.auth.get_valid_token(account).await?;
309 mail::create_forward_draft(&self.http, &self.base_url, &token, message_id, to, comment)
310 .await
311 }
312
313 pub async fn send_draft(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
315 let token = self.auth.get_valid_token(account).await?;
316 mail::send_draft(&self.http, &self.base_url, &token, message_id).await
317 }
318
319 pub async fn update_draft(
321 &self,
322 account: &str,
323 message_id: &str,
324 message: &Outgoing,
325 ) -> Result<(), ClientError> {
326 let token = self.auth.get_valid_token(account).await?;
327 mail::update_draft(&self.http, &self.base_url, &token, message_id, message).await
328 }
329
330 pub async fn delete_message(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
333 let token = self.auth.get_valid_token(account).await?;
334 mail::delete_message(&self.http, &self.base_url, &token, message_id).await
335 }
336
337 pub async fn add_attachment(
339 &self,
340 account: &str,
341 message_id: &str,
342 name: &str,
343 content_type: &str,
344 bytes: &[u8],
345 ) -> Result<String, ClientError> {
346 let token = self.auth.get_valid_token(account).await?;
347 mail::add_attachment(
348 &self.http,
349 &self.base_url,
350 &token,
351 message_id,
352 name,
353 content_type,
354 bytes,
355 )
356 .await
357 }
358
359 pub async fn delete_attachment(
361 &self,
362 account: &str,
363 message_id: &str,
364 attachment_id: &str,
365 ) -> Result<(), ClientError> {
366 let token = self.auth.get_valid_token(account).await?;
367 mail::delete_attachment(
368 &self.http,
369 &self.base_url,
370 &token,
371 message_id,
372 attachment_id,
373 )
374 .await
375 }
376
377 pub async fn get_message(
379 &self,
380 account: &str,
381 message_id: &str,
382 ) -> Result<pidge_core::FullMessage, ClientError> {
383 let token = self.auth.get_valid_token(account).await?;
384 mail::get_message(&self.http, &self.base_url, &token, account, message_id).await
385 }
386
387 pub async fn fetch_message_headers(
389 &self,
390 account: &str,
391 message_id: &str,
392 ) -> Result<Vec<(String, String)>, ClientError> {
393 let token = self.auth.get_valid_token(account).await?;
394 mail::fetch_message_headers(&self.http, &self.base_url, &token, message_id).await
395 }
396
397 pub async fn list_attachments(
399 &self,
400 account: &str,
401 message_id: &str,
402 ) -> Result<Vec<pidge_core::Attachment>, ClientError> {
403 let token = self.auth.get_valid_token(account).await?;
404 mail::list_attachments(&self.http, &self.base_url, &token, message_id).await
405 }
406
407 pub async fn get_attachment_bytes(
409 &self,
410 account: &str,
411 message_id: &str,
412 attachment_id: &str,
413 ) -> Result<Vec<u8>, ClientError> {
414 let token = self.auth.get_valid_token(account).await?;
415 mail::get_attachment_bytes(
416 &self.http,
417 &self.base_url,
418 &token,
419 message_id,
420 attachment_id,
421 )
422 .await
423 }
424
425 pub async fn mark_read(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
427 let token = self.auth.get_valid_token(account).await?;
428 mail::mark_read(&self.http, &self.base_url, &token, message_id).await
429 }
430
431 pub async fn list_calendars(
435 &self,
436 account: &str,
437 ) -> Result<Vec<pidge_core::Calendar>, ClientError> {
438 let token = self.auth.get_valid_token(account).await?;
439 calendars::list_calendars(&self.http, &self.base_url, &token, account).await
440 }
441
442 pub async fn list_calendar_view(
444 &self,
445 account: &str,
446 calendar_id: Option<&str>,
447 start: chrono::DateTime<chrono::Utc>,
448 end: chrono::DateTime<chrono::Utc>,
449 limit: usize,
450 ) -> Result<events::EventsPage, ClientError> {
451 let token = self.auth.get_valid_token(account).await?;
452 events::list_calendar_view(
453 &self.http,
454 &self.base_url,
455 &token,
456 account,
457 calendar_id,
458 start,
459 end,
460 limit,
461 )
462 .await
463 }
464
465 pub async fn get_event(
467 &self,
468 account: &str,
469 event_id: &str,
470 ) -> Result<pidge_core::Event, ClientError> {
471 let token = self.auth.get_valid_token(account).await?;
472 events::get_event(&self.http, &self.base_url, &token, account, event_id).await
473 }
474
475 pub async fn create_event(
477 &self,
478 account: &str,
479 calendar_id: Option<&str>,
480 new_event: &events::NewEvent,
481 ) -> Result<String, ClientError> {
482 let token = self.auth.get_valid_token(account).await?;
483 events::create_event(&self.http, &self.base_url, &token, calendar_id, new_event).await
484 }
485
486 pub async fn update_event(
488 &self,
489 account: &str,
490 event_id: &str,
491 new_event: &events::NewEvent,
492 ) -> Result<(), ClientError> {
493 let token = self.auth.get_valid_token(account).await?;
494 events::update_event(&self.http, &self.base_url, &token, event_id, new_event).await
495 }
496
497 pub async fn move_time(
499 &self,
500 account: &str,
501 event_id: &str,
502 start: chrono::DateTime<chrono::Utc>,
503 end: chrono::DateTime<chrono::Utc>,
504 tz: &str,
505 ) -> Result<(), ClientError> {
506 let token = self.auth.get_valid_token(account).await?;
507 events::move_time(&self.http, &self.base_url, &token, event_id, start, end, tz).await
508 }
509
510 pub async fn delete_event(&self, account: &str, event_id: &str) -> Result<(), ClientError> {
512 let token = self.auth.get_valid_token(account).await?;
513 events::delete_event(&self.http, &self.base_url, &token, event_id).await
514 }
515
516 pub async fn cancel_event(
518 &self,
519 account: &str,
520 event_id: &str,
521 comment: &str,
522 ) -> Result<(), ClientError> {
523 let token = self.auth.get_valid_token(account).await?;
524 events::cancel_event(&self.http, &self.base_url, &token, event_id, comment).await
525 }
526
527 pub async fn rsvp_event(
529 &self,
530 account: &str,
531 event_id: &str,
532 kind: events::RsvpKind,
533 comment: &str,
534 send_response: bool,
535 ) -> Result<(), ClientError> {
536 let token = self.auth.get_valid_token(account).await?;
537 events::rsvp_event(
538 &self.http,
539 &self.base_url,
540 &token,
541 event_id,
542 kind,
543 comment,
544 send_response,
545 )
546 .await
547 }
548
549 pub async fn move_event_to_calendar(
551 &self,
552 account: &str,
553 event_id: &str,
554 destination_calendar_id: &str,
555 ) -> Result<(), ClientError> {
556 let token = self.auth.get_valid_token(account).await?;
557 events::move_event_to_calendar(
558 &self.http,
559 &self.base_url,
560 &token,
561 event_id,
562 destination_calendar_id,
563 )
564 .await
565 }
566}