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_draft, create_forward_draft,
15 create_mail_folder, create_reply_all_draft, create_reply_draft, delete_attachment,
16 delete_message, fetch_message_headers, forward_message, get_attachment_bytes, get_message,
17 list_attachments, list_drafts, list_inbox, list_mail_folders, mark_read, mark_unread,
18 move_message, reply_all_message, reply_message, search_messages, send_draft, send_mail,
19 set_flag, update_draft,
20};
21pub use me::{Me, get_me};
22
23use crate::auth::AuthClient;
24use crate::auth::config;
25use crate::error::ClientError;
26use pidge_core::Message;
27
28pub struct GraphClient {
30 auth: AuthClient,
31 http: reqwest::Client,
32 base_url: String,
33}
34
35impl GraphClient {
36 pub fn new(auth: AuthClient) -> Result<Self, ClientError> {
37 Ok(Self {
38 auth,
39 http: reqwest::Client::builder()
40 .user_agent(format!("pidge/{}", env!("CARGO_PKG_VERSION")))
41 .build()?,
42 base_url: config::GRAPH_BASE.to_string(),
43 })
44 }
45
46 pub fn for_test(auth: AuthClient, base_url: impl Into<String>) -> Self {
47 Self {
48 auth,
49 http: reqwest::Client::new(),
50 base_url: base_url.into(),
51 }
52 }
53
54 pub fn auth(&self) -> &AuthClient {
55 &self.auth
56 }
57
58 pub async fn me(&self, access_token: &str) -> Result<Me, ClientError> {
60 get_me(&self.http, &self.base_url, access_token).await
61 }
62
63 pub async fn list_inbox(
66 &self,
67 account: &str,
68 limit: usize,
69 skip: usize,
70 unread_only: bool,
71 ) -> Result<InboxPage, ClientError> {
72 let token = self.auth.get_valid_token(account).await?;
73 list_inbox(
74 &self.http,
75 &self.base_url,
76 &token,
77 account,
78 limit,
79 skip,
80 unread_only,
81 )
82 .await
83 }
84
85 pub async fn search_messages(
87 &self,
88 account: &str,
89 query: &str,
90 limit: usize,
91 ) -> Result<Vec<Message>, ClientError> {
92 let token = self.auth.get_valid_token(account).await?;
93 search_messages(&self.http, &self.base_url, &token, account, query, limit).await
94 }
95
96 pub async fn mark_unread(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
98 let token = self.auth.get_valid_token(account).await?;
99 mail::mark_unread(&self.http, &self.base_url, &token, message_id).await
100 }
101
102 pub async fn set_flag(
104 &self,
105 account: &str,
106 message_id: &str,
107 flagged: bool,
108 ) -> Result<(), ClientError> {
109 let token = self.auth.get_valid_token(account).await?;
110 mail::set_flag(&self.http, &self.base_url, &token, message_id, flagged).await
111 }
112
113 pub async fn move_message(
115 &self,
116 account: &str,
117 message_id: &str,
118 destination: &str,
119 ) -> Result<(), ClientError> {
120 let token = self.auth.get_valid_token(account).await?;
121 mail::move_message(&self.http, &self.base_url, &token, message_id, destination).await
122 }
123
124 pub async fn list_mail_folders(&self, account: &str) -> Result<Vec<MailFolder>, ClientError> {
126 let token = self.auth.get_valid_token(account).await?;
127 mail::list_mail_folders(&self.http, &self.base_url, &token).await
128 }
129
130 pub async fn create_mail_folder(
132 &self,
133 account: &str,
134 display_name: &str,
135 ) -> Result<MailFolder, ClientError> {
136 let token = self.auth.get_valid_token(account).await?;
137 mail::create_mail_folder(&self.http, &self.base_url, &token, display_name).await
138 }
139
140 pub async fn send_mail(&self, account: &str, message: &Outgoing) -> Result<(), ClientError> {
142 let token = self.auth.get_valid_token(account).await?;
143 mail::send_mail(&self.http, &self.base_url, &token, message).await
144 }
145
146 pub async fn reply_message(
148 &self,
149 account: &str,
150 message_id: &str,
151 comment: &str,
152 ) -> Result<(), ClientError> {
153 let token = self.auth.get_valid_token(account).await?;
154 mail::reply_message(&self.http, &self.base_url, &token, message_id, comment).await
155 }
156
157 pub async fn reply_all_message(
159 &self,
160 account: &str,
161 message_id: &str,
162 comment: &str,
163 ) -> Result<(), ClientError> {
164 let token = self.auth.get_valid_token(account).await?;
165 mail::reply_all_message(&self.http, &self.base_url, &token, message_id, comment).await
166 }
167
168 pub async fn forward_message(
170 &self,
171 account: &str,
172 message_id: &str,
173 to: &[String],
174 comment: &str,
175 ) -> Result<(), ClientError> {
176 let token = self.auth.get_valid_token(account).await?;
177 mail::forward_message(&self.http, &self.base_url, &token, message_id, to, comment).await
178 }
179
180 pub async fn list_drafts(
182 &self,
183 account: &str,
184 limit: usize,
185 skip: usize,
186 ) -> Result<InboxPage, ClientError> {
187 let token = self.auth.get_valid_token(account).await?;
188 mail::list_drafts(&self.http, &self.base_url, &token, account, limit, skip).await
189 }
190
191 pub async fn create_draft(
193 &self,
194 account: &str,
195 message: &Outgoing,
196 ) -> Result<String, ClientError> {
197 let token = self.auth.get_valid_token(account).await?;
198 mail::create_draft(&self.http, &self.base_url, &token, message).await
199 }
200
201 pub async fn create_reply_draft(
203 &self,
204 account: &str,
205 message_id: &str,
206 comment: &str,
207 ) -> Result<String, ClientError> {
208 let token = self.auth.get_valid_token(account).await?;
209 mail::create_reply_draft(&self.http, &self.base_url, &token, message_id, comment).await
210 }
211
212 pub async fn create_reply_all_draft(
214 &self,
215 account: &str,
216 message_id: &str,
217 comment: &str,
218 ) -> Result<String, ClientError> {
219 let token = self.auth.get_valid_token(account).await?;
220 mail::create_reply_all_draft(&self.http, &self.base_url, &token, message_id, comment).await
221 }
222
223 pub async fn create_forward_draft(
225 &self,
226 account: &str,
227 message_id: &str,
228 to: &[String],
229 comment: &str,
230 ) -> Result<String, ClientError> {
231 let token = self.auth.get_valid_token(account).await?;
232 mail::create_forward_draft(&self.http, &self.base_url, &token, message_id, to, comment)
233 .await
234 }
235
236 pub async fn send_draft(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
238 let token = self.auth.get_valid_token(account).await?;
239 mail::send_draft(&self.http, &self.base_url, &token, message_id).await
240 }
241
242 pub async fn update_draft(
244 &self,
245 account: &str,
246 message_id: &str,
247 message: &Outgoing,
248 ) -> Result<(), ClientError> {
249 let token = self.auth.get_valid_token(account).await?;
250 mail::update_draft(&self.http, &self.base_url, &token, message_id, message).await
251 }
252
253 pub async fn delete_message(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
256 let token = self.auth.get_valid_token(account).await?;
257 mail::delete_message(&self.http, &self.base_url, &token, message_id).await
258 }
259
260 pub async fn add_attachment(
262 &self,
263 account: &str,
264 message_id: &str,
265 name: &str,
266 content_type: &str,
267 bytes: &[u8],
268 ) -> Result<String, ClientError> {
269 let token = self.auth.get_valid_token(account).await?;
270 mail::add_attachment(
271 &self.http,
272 &self.base_url,
273 &token,
274 message_id,
275 name,
276 content_type,
277 bytes,
278 )
279 .await
280 }
281
282 pub async fn delete_attachment(
284 &self,
285 account: &str,
286 message_id: &str,
287 attachment_id: &str,
288 ) -> Result<(), ClientError> {
289 let token = self.auth.get_valid_token(account).await?;
290 mail::delete_attachment(
291 &self.http,
292 &self.base_url,
293 &token,
294 message_id,
295 attachment_id,
296 )
297 .await
298 }
299
300 pub async fn get_message(
302 &self,
303 account: &str,
304 message_id: &str,
305 ) -> Result<pidge_core::FullMessage, ClientError> {
306 let token = self.auth.get_valid_token(account).await?;
307 mail::get_message(&self.http, &self.base_url, &token, account, message_id).await
308 }
309
310 pub async fn fetch_message_headers(
312 &self,
313 account: &str,
314 message_id: &str,
315 ) -> Result<Vec<(String, String)>, ClientError> {
316 let token = self.auth.get_valid_token(account).await?;
317 mail::fetch_message_headers(&self.http, &self.base_url, &token, message_id).await
318 }
319
320 pub async fn list_attachments(
322 &self,
323 account: &str,
324 message_id: &str,
325 ) -> Result<Vec<pidge_core::Attachment>, ClientError> {
326 let token = self.auth.get_valid_token(account).await?;
327 mail::list_attachments(&self.http, &self.base_url, &token, message_id).await
328 }
329
330 pub async fn get_attachment_bytes(
332 &self,
333 account: &str,
334 message_id: &str,
335 attachment_id: &str,
336 ) -> Result<Vec<u8>, ClientError> {
337 let token = self.auth.get_valid_token(account).await?;
338 mail::get_attachment_bytes(
339 &self.http,
340 &self.base_url,
341 &token,
342 message_id,
343 attachment_id,
344 )
345 .await
346 }
347
348 pub async fn mark_read(&self, account: &str, message_id: &str) -> Result<(), ClientError> {
350 let token = self.auth.get_valid_token(account).await?;
351 mail::mark_read(&self.http, &self.base_url, &token, message_id).await
352 }
353
354 pub async fn list_calendars(
358 &self,
359 account: &str,
360 ) -> Result<Vec<pidge_core::Calendar>, ClientError> {
361 let token = self.auth.get_valid_token(account).await?;
362 calendars::list_calendars(&self.http, &self.base_url, &token, account).await
363 }
364
365 pub async fn list_calendar_view(
367 &self,
368 account: &str,
369 calendar_id: Option<&str>,
370 start: chrono::DateTime<chrono::Utc>,
371 end: chrono::DateTime<chrono::Utc>,
372 limit: usize,
373 ) -> Result<events::EventsPage, ClientError> {
374 let token = self.auth.get_valid_token(account).await?;
375 events::list_calendar_view(
376 &self.http,
377 &self.base_url,
378 &token,
379 account,
380 calendar_id,
381 start,
382 end,
383 limit,
384 )
385 .await
386 }
387
388 pub async fn get_event(
390 &self,
391 account: &str,
392 event_id: &str,
393 ) -> Result<pidge_core::Event, ClientError> {
394 let token = self.auth.get_valid_token(account).await?;
395 events::get_event(&self.http, &self.base_url, &token, account, event_id).await
396 }
397
398 pub async fn create_event(
400 &self,
401 account: &str,
402 calendar_id: Option<&str>,
403 new_event: &events::NewEvent,
404 ) -> Result<String, ClientError> {
405 let token = self.auth.get_valid_token(account).await?;
406 events::create_event(&self.http, &self.base_url, &token, calendar_id, new_event).await
407 }
408
409 pub async fn update_event(
411 &self,
412 account: &str,
413 event_id: &str,
414 new_event: &events::NewEvent,
415 ) -> Result<(), ClientError> {
416 let token = self.auth.get_valid_token(account).await?;
417 events::update_event(&self.http, &self.base_url, &token, event_id, new_event).await
418 }
419
420 pub async fn move_time(
422 &self,
423 account: &str,
424 event_id: &str,
425 start: chrono::DateTime<chrono::Utc>,
426 end: chrono::DateTime<chrono::Utc>,
427 tz: &str,
428 ) -> Result<(), ClientError> {
429 let token = self.auth.get_valid_token(account).await?;
430 events::move_time(&self.http, &self.base_url, &token, event_id, start, end, tz).await
431 }
432
433 pub async fn delete_event(&self, account: &str, event_id: &str) -> Result<(), ClientError> {
435 let token = self.auth.get_valid_token(account).await?;
436 events::delete_event(&self.http, &self.base_url, &token, event_id).await
437 }
438
439 pub async fn cancel_event(
441 &self,
442 account: &str,
443 event_id: &str,
444 comment: &str,
445 ) -> Result<(), ClientError> {
446 let token = self.auth.get_valid_token(account).await?;
447 events::cancel_event(&self.http, &self.base_url, &token, event_id, comment).await
448 }
449
450 pub async fn rsvp_event(
452 &self,
453 account: &str,
454 event_id: &str,
455 kind: events::RsvpKind,
456 comment: &str,
457 send_response: bool,
458 ) -> Result<(), ClientError> {
459 let token = self.auth.get_valid_token(account).await?;
460 events::rsvp_event(
461 &self.http,
462 &self.base_url,
463 &token,
464 event_id,
465 kind,
466 comment,
467 send_response,
468 )
469 .await
470 }
471
472 pub async fn move_event_to_calendar(
474 &self,
475 account: &str,
476 event_id: &str,
477 destination_calendar_id: &str,
478 ) -> Result<(), ClientError> {
479 let token = self.auth.get_valid_token(account).await?;
480 events::move_event_to_calendar(
481 &self.http,
482 &self.base_url,
483 &token,
484 event_id,
485 destination_calendar_id,
486 )
487 .await
488 }
489}