/ backend / src / services / email_service.rs
email_service.rs
 1  use std::sync::Arc;
 2  
 3  use crate::services::google_api_service;
 4  use crate::services::google_api_service::GoogleApiError;
 5  use crate::util::config::{EmailConfig, GoogleEmailConfig};
 6  
 7  #[derive(Debug, thiserror::Error)]
 8  pub enum EmailError {
 9      #[error("Google API error")]
10      GoogleApiError(#[from] GoogleApiError),
11  }
12  
13  pub enum EmailProvider {
14      None,
15      Stdout,
16      Google(Arc<GoogleEmailConfig>),
17  }
18  
19  impl From<&EmailConfig> for EmailProvider {
20      fn from(config: &EmailConfig) -> Self {
21          match config {
22              EmailConfig::None => EmailProvider::None,
23              EmailConfig::Stdout => EmailProvider::Stdout,
24              EmailConfig::Google(config) => EmailProvider::Google(config.clone()),
25          }
26      }
27  }
28  
29  impl EmailProvider {
30      pub async fn send_email(
31          &self,
32          receiver_email: &str,
33          subject: &str,
34          content: &str,
35      ) -> Result<(), EmailError> {
36          match self {
37              EmailProvider::None => Ok(()),
38              EmailProvider::Stdout => stdout_send_email(receiver_email, subject, content).await,
39              EmailProvider::Google(config) => {
40                  google_send_email(config, receiver_email, subject, content).await
41              }
42          }
43      }
44  }
45  
46  async fn stdout_send_email(
47      receiver_email: &str,
48      subject: &str,
49      content: &str,
50  ) -> Result<(), EmailError> {
51      log::info!("stdout set as email provider, printing email now.");
52      println!(
53          "## EMAIL ##
54  To: {}
55  Subject: {}
56  
57  {}      
58          ",
59          receiver_email, subject, content
60      );
61  
62      Ok(())
63  }
64  
65  pub async fn google_send_email(
66      config: &GoogleEmailConfig,
67      receiver_email: &str,
68      subject: &str,
69      content: &str,
70  ) -> Result<(), EmailError> {
71      let token = google_api_service::retrieve_token(config)
72          .await
73          .map_err(|err| {
74              error!("Failed to retrieve token from google, err: {}", err);
75              err
76          })?;
77  
78      google_api_service::send_email(receiver_email, subject, content, &token, config)
79          .await
80          .map_err(|err| {
81              error!("Failed to send email, err: {}", err);
82              err
83          })?;
84  
85      Ok(())
86  }