botserver/src/email/mod.rs

82 lines
2.3 KiB
Rust
Raw Normal View History

2025-10-06 20:06:43 -03:00
use actix_web::{post, web, HttpResponse, Result};
use lettre::{
message::header::ContentType,
transport::smtp::authentication::Credentials,
Message,
SmtpTransport,
Transport
};
2025-10-06 10:30:17 -03:00
use log::info;
2025-10-06 20:06:43 -03:00
use serde::{Deserialize, Serialize};
2025-10-06 10:30:17 -03:00
2025-10-06 20:06:43 -03:00
#[derive(Debug, Serialize, Deserialize)]
pub struct EmailRequest {
pub to: String,
2025-10-06 10:30:17 -03:00
pub subject: String,
2025-10-06 20:06:43 -03:00
pub body: String,
2025-10-06 10:30:17 -03:00
}
2025-10-06 20:06:43 -03:00
#[derive(Clone)]
pub struct EmailConfig {
pub from: String,
pub server: String,
pub port: u16,
pub username: String,
pub password: String,
}
async fn send_email_impl(
config: &EmailConfig,
to: &str,
subject: &str,
body: &str,
) -> Result<(), Box<dyn std::error::Error>> {
2025-10-06 10:30:17 -03:00
let email = Message::builder()
2025-10-06 20:06:43 -03:00
.from(config.from.parse()?)
.to(to.parse()?)
2025-10-06 10:30:17 -03:00
.subject(subject)
2025-10-06 20:06:43 -03:00
.header(ContentType::TEXT_PLAIN)
.body(body.to_string())?;
2025-10-06 10:30:17 -03:00
let creds = Credentials::new(config.username.clone(), config.password.clone());
2025-10-06 20:06:43 -03:00
let mailer = SmtpTransport::relay(&config.server)?
2025-10-06 10:30:17 -03:00
.port(config.port)
.credentials(creds)
2025-10-06 20:06:43 -03:00
.build();
2025-10-06 10:30:17 -03:00
2025-10-06 20:06:43 -03:00
match mailer.send(&email) {
Ok(_) => {
info!("Email sent to {}", to);
Ok(())
2025-10-06 10:30:17 -03:00
}
Err(e) => {
2025-10-06 20:06:43 -03:00
log::error!("Failed to send email: {}", e);
Err(Box::new(e))
2025-10-06 10:30:17 -03:00
}
}
}
2025-10-06 20:06:43 -03:00
#[post("/email/send")]
2025-10-06 10:30:17 -03:00
pub async fn send_email(
2025-10-06 20:06:43 -03:00
config: web::Data<crate::config::AppConfig>,
payload: web::Json<EmailRequest>,
) -> Result<HttpResponse> {
let email_request = payload.into_inner();
match send_email_impl(&config.email, &email_request.to, &email_request.subject, &email_request.body).await {
Ok(_) => Ok(HttpResponse::Ok().json(serde_json::json!({"status": "sent"}))),
Err(e) => Ok(HttpResponse::InternalServerError().json(serde_json::json!({"error": e.to_string()})))
}
2025-10-06 10:30:17 -03:00
}
2025-10-06 20:06:43 -03:00
#[post("/email/test")]
pub async fn test_email(
config: web::Data<crate::config::AppConfig>,
) -> Result<HttpResponse> {
match send_email_impl(&config.email, &config.email.from, "Test Email", "This is a test email from BotServer").await {
Ok(_) => Ok(HttpResponse::Ok().json(serde_json::json!({"status": "test_sent"}))),
Err(e) => Ok(HttpResponse::InternalServerError().json(serde_json::json!({"error": e.to_string()})))
}
2025-10-06 10:30:17 -03:00
}