mod.rs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. use anyhow::Result;
  2. use async_trait::async_trait;
  3. use reqwest::Url;
  4. #[derive(serde::Deserialize, serde::Serialize, Debug)]
  5. pub struct CompilerMeetings {
  6. items: Vec<CompilerMeeting>,
  7. }
  8. #[derive(serde::Deserialize, serde::Serialize, Debug)]
  9. pub struct Start {
  10. #[serde(rename(deserialize = "dateTime"))]
  11. date_time: String,
  12. }
  13. #[derive(serde::Deserialize, serde::Serialize, Debug)]
  14. pub struct CompilerMeeting {
  15. summary: String,
  16. #[serde(rename(deserialize = "htmlLink"))]
  17. html_link: String,
  18. #[serde(rename(deserialize = "originalStartTime"))]
  19. original_start: Option<Start>,
  20. start: Option<Start>,
  21. }
  22. #[async_trait]
  23. pub trait HttpClient {
  24. async fn get_meetings(
  25. start_date: chrono::DateTime<chrono::Local>,
  26. end_date: chrono::DateTime<chrono::Local>,
  27. ) -> Result<Vec<CompilerMeeting>>
  28. where
  29. Self: Sized;
  30. }
  31. #[async_trait]
  32. impl HttpClient for CompilerMeeting {
  33. /// Retrieve all meetings from the Rust Compiler Team Calendar in a date range
  34. /// If a Google API auth token is not provided just return
  35. // Google calendar API documentation:
  36. // https://developers.google.com/calendar/api/v3/reference/events/list
  37. // The API token needs only one permission: https://www.googleapis.com/auth/calendar.events.readonly
  38. async fn get_meetings(
  39. start_date: chrono::DateTime<chrono::Local>,
  40. end_date: chrono::DateTime<chrono::Local>,
  41. ) -> Result<Vec<CompilerMeeting>> {
  42. let api_key = match std::env::var("GOOGLE_API_KEY") {
  43. Ok(v) => v,
  44. Err(_) => {
  45. return Ok(vec![]);
  46. }
  47. };
  48. let google_calendar_id = "6u5rrtce6lrtv07pfi3damgjus%40group.calendar.google.com";
  49. let time_min = format!("{}T00:00:00+00:00", start_date.format("%F").to_string());
  50. let time_max = format!("{}T23:59:59+00:00", end_date.format("%F").to_string());
  51. let url = Url::parse_with_params(
  52. &format!(
  53. "https://www.googleapis.com/calendar/v3/calendars/{}/events",
  54. google_calendar_id
  55. ),
  56. &[
  57. // see google docs for the meaning of these values
  58. ("key", api_key),
  59. ("timeMin", time_min),
  60. ("timeMax", time_max),
  61. ("singleEvents", "true".to_string()),
  62. ],
  63. )?;
  64. let calendar = reqwest::get(url).await?.json::<CompilerMeetings>().await?;
  65. Ok(calendar.items)
  66. }
  67. }