Working Version of EmailService

This commit is contained in:
2024-02-25 03:57:42 -03:00
parent 0dcb35e718
commit 0801fd5f7c
5 changed files with 83 additions and 28 deletions

View File

@@ -5,6 +5,8 @@ use std::env;
pub struct ConfigEmail {
pub smtp_server: String,
pub smtp_port: u16,
pub smtp_name: String,
pub smtp_email: String,
pub smtp_username: String,
pub smtp_password: String,
}
@@ -16,9 +18,14 @@ pub fn get_config_email() -> ConfigEmail {
let username = env::var("SMTP_USERNAME").expect("SMTP_USERNAME must be set");
let password = env::var("SMTP_PASSWORD").expect("SMTP_PASSWORD must be set");
ConfigEmail{
let name = env::var("SMTP_NAME").expect("SMTP_NAME must be set");
let email = env::var("SMTP_EMAIL").unwrap_or(username.clone());
ConfigEmail {
smtp_server: server,
smtp_port: port.parse::<u16>().unwrap(),
smtp_name: name,
smtp_email: email,
smtp_username: username,
smtp_password: password,
}

View File

@@ -1,3 +1,3 @@
pub mod config_auth;
pub mod config_server;
pub mod config_email;
pub mod config_server;

View File

@@ -1,13 +1,35 @@
use crate::model::generic_response::GenericResponse;
use crate::model::send_message::{MessageAuthor, SendMessage};
use axum::extract::State;
use crate::service::email_service::EmailService;
use axum::{http::StatusCode, response::IntoResponse, Extension, Json};
pub async fn send_message(
Extension(auther): Extension<MessageAuthor>,
Extension(email_service): Extension<EmailService>,
Extension(author): Extension<MessageAuthor>,
Json(payload): Json<SendMessage>,
) -> impl IntoResponse {
let mut response = payload.clone();
response.author = Some(auther).clone();
let mut package = payload.clone();
package.author = Some(author).clone();
(StatusCode::OK, Json(response))
match email_service.send_email_smtp(package).await {
Ok(_) => {},
Err(e) => {
return (
StatusCode::INTERNAL_SERVER_ERROR,
Json(GenericResponse {
status: StatusCode::INTERNAL_SERVER_ERROR.to_string(),
message: e.to_string(),
}),
)
},
};
return (
StatusCode::OK,
Json(GenericResponse {
status: StatusCode::OK.to_string(),
message: "Message sent".to_string(),
}),
);
}

View File

@@ -16,7 +16,9 @@ fn configure_message_endpoint(router: Router) -> Router {
.route("/message", post(send_message))
.layer(middleware::from_fn(auth_middleware))
.layer(Extension(AuthService::new(config_auth::get_config_auth())))
.layer(Extension(EmailService::new(config_email::get_config_email())))
.layer(Extension(EmailService::new(
config_email::get_config_email(),
)))
}
fn configure_health_endpoint(router: Router) -> Router {

View File

@@ -1,41 +1,65 @@
use lettre::{
transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message,
Tokio1Executor,
};
use crate::config::config_email::ConfigEmail;
use crate::model::send_message::{MessageAuthor, SendMessage};
use lettre::{transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor, Address};
use lettre::message::Mailbox;
#[derive(Clone)]
pub struct EmailService {
mailer: AsyncSmtpTransport<Tokio1Executor>
name: String,
email: String,
mailer: AsyncSmtpTransport<Tokio1Executor>,
}
impl EmailService {
pub fn new(config_email: ConfigEmail) -> Self {
EmailService {
mailer: AsyncSmtpTransport::<Tokio1Executor>::relay(&config_email.smtp_server)
name: config_email.smtp_name.clone(),
email: config_email.smtp_email.clone(),
mailer: AsyncSmtpTransport::<Tokio1Executor>::starttls_relay(&config_email.smtp_server)
.unwrap()
.credentials(Credentials::new(config_email.smtp_username, config_email.smtp_password))
.credentials(Credentials::new(
config_email.smtp_username,
config_email.smtp_password,
))
.port(config_email.smtp_port)
.build()
.build(),
}
}
async fn send_email_smtp(
&self,
from: &str,
to: &str,
subject: &str,
body: String,
) -> Result<(), Box<dyn std::error::Error>> {
pub async fn send_email_smtp(&self, m: SendMessage) -> Result<(), Box<dyn std::error::Error>> {
let sender = m.author.clone().unwrap();
let sender_mailbox = Mailbox::new(
Some(sender.name), sender.email.parse::<Address>().unwrap()
);
let recipient_mailbox = Mailbox::new(
Some(self.name.clone()), self.email.parse::<Address>().unwrap()
);
let body = self.create_email_body(&m);
let email = Message::builder()
.from(from.parse()?)
.to(to.parse()?)
.subject(subject)
.from(sender_mailbox.clone())
.to(recipient_mailbox.clone())
.subject(m.subject)
.body(body.to_string())?;
self.mailer.send(email).await?;
Ok(())
}
fn create_email_body(&self, m: &SendMessage) -> String {
let sender = m.author.clone().unwrap();
format!(
"From: {} <{}>\nTo: {} <{}>\nSubject: {}\n\n{}",
sender.name,
sender.email,
self.name,
self.email,
m.subject,
m.message
)
}
}