Working Version of EmailService
This commit is contained in:
@@ -5,6 +5,8 @@ use std::env;
|
|||||||
pub struct ConfigEmail {
|
pub struct ConfigEmail {
|
||||||
pub smtp_server: String,
|
pub smtp_server: String,
|
||||||
pub smtp_port: u16,
|
pub smtp_port: u16,
|
||||||
|
pub smtp_name: String,
|
||||||
|
pub smtp_email: String,
|
||||||
pub smtp_username: String,
|
pub smtp_username: String,
|
||||||
pub smtp_password: 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 username = env::var("SMTP_USERNAME").expect("SMTP_USERNAME must be set");
|
||||||
let password = env::var("SMTP_PASSWORD").expect("SMTP_PASSWORD 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_server: server,
|
||||||
smtp_port: port.parse::<u16>().unwrap(),
|
smtp_port: port.parse::<u16>().unwrap(),
|
||||||
|
smtp_name: name,
|
||||||
|
smtp_email: email,
|
||||||
smtp_username: username,
|
smtp_username: username,
|
||||||
smtp_password: password,
|
smtp_password: password,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
pub mod config_auth;
|
pub mod config_auth;
|
||||||
pub mod config_server;
|
|
||||||
pub mod config_email;
|
pub mod config_email;
|
||||||
|
pub mod config_server;
|
||||||
|
|||||||
@@ -1,13 +1,35 @@
|
|||||||
|
use crate::model::generic_response::GenericResponse;
|
||||||
use crate::model::send_message::{MessageAuthor, SendMessage};
|
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};
|
use axum::{http::StatusCode, response::IntoResponse, Extension, Json};
|
||||||
|
|
||||||
|
|
||||||
pub async fn send_message(
|
pub async fn send_message(
|
||||||
Extension(auther): Extension<MessageAuthor>,
|
Extension(email_service): Extension<EmailService>,
|
||||||
|
Extension(author): Extension<MessageAuthor>,
|
||||||
Json(payload): Json<SendMessage>,
|
Json(payload): Json<SendMessage>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let mut response = payload.clone();
|
let mut package = payload.clone();
|
||||||
response.author = Some(auther).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(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -16,7 +16,9 @@ fn configure_message_endpoint(router: Router) -> Router {
|
|||||||
.route("/message", post(send_message))
|
.route("/message", post(send_message))
|
||||||
.layer(middleware::from_fn(auth_middleware))
|
.layer(middleware::from_fn(auth_middleware))
|
||||||
.layer(Extension(AuthService::new(config_auth::get_config_auth())))
|
.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 {
|
fn configure_health_endpoint(router: Router) -> Router {
|
||||||
|
|||||||
@@ -1,41 +1,65 @@
|
|||||||
use lettre::{
|
|
||||||
transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message,
|
|
||||||
Tokio1Executor,
|
|
||||||
};
|
|
||||||
use crate::config::config_email::ConfigEmail;
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct EmailService {
|
pub struct EmailService {
|
||||||
mailer: AsyncSmtpTransport<Tokio1Executor>
|
name: String,
|
||||||
|
email: String,
|
||||||
|
mailer: AsyncSmtpTransport<Tokio1Executor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EmailService {
|
impl EmailService {
|
||||||
pub fn new(config_email: ConfigEmail) -> Self {
|
pub fn new(config_email: ConfigEmail) -> Self {
|
||||||
EmailService {
|
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()
|
.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)
|
.port(config_email.smtp_port)
|
||||||
.build()
|
.build(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_email_smtp(
|
pub async fn send_email_smtp(&self, m: SendMessage) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
&self,
|
let sender = m.author.clone().unwrap();
|
||||||
from: &str,
|
let sender_mailbox = Mailbox::new(
|
||||||
to: &str,
|
Some(sender.name), sender.email.parse::<Address>().unwrap()
|
||||||
subject: &str,
|
);
|
||||||
body: String,
|
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
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()
|
let email = Message::builder()
|
||||||
.from(from.parse()?)
|
.from(sender_mailbox.clone())
|
||||||
.to(to.parse()?)
|
.to(recipient_mailbox.clone())
|
||||||
.subject(subject)
|
.subject(m.subject)
|
||||||
.body(body.to_string())?;
|
.body(body.to_string())?;
|
||||||
|
|
||||||
self.mailer.send(email).await?;
|
self.mailer.send(email).await?;
|
||||||
|
|
||||||
Ok(())
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user