feat: ✨ send_mail
This commit is contained in:
parent
b3b93ab0cc
commit
032a19931d
5 changed files with 101 additions and 14 deletions
|
@ -16,9 +16,10 @@ strip = "symbols"
|
|||
|
||||
[dependencies]
|
||||
axum = "0.7.9"
|
||||
chrono = { version = "0.4.38", features = ["serde"] }
|
||||
serde = { version = "1.0.215", features = ["derive"] }
|
||||
chrono = { version = "0.4.39", features = ["serde"] }
|
||||
lettre = { version = "0.11.11", default-features = false, features = ["builder", "smtp-transport", "tokio1-rustls-tls"] }
|
||||
serde = { version = "1.0.216", features = ["derive"] }
|
||||
serde_json = "1.0.133"
|
||||
sqlx = { version = "0.8.2", features = ["chrono", "macros", "postgres", "runtime-tokio-rustls"] }
|
||||
tokio = { version = "1.41.1", features = ["full"] }
|
||||
tokio = { version = "1.42.0", features = ["rt-multi-thread"] }
|
||||
tower-http = { version = "0.6.2", features = ["cors"] }
|
||||
|
|
8
configs/mail_config.toml
Normal file
8
configs/mail_config.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
[mail_config]
|
||||
name = "Ahmet Kaan Gümüş"
|
||||
mail_address = "mail@mail.com"
|
||||
username = "username"
|
||||
password = "password"
|
||||
relay_address = "localhost"
|
||||
port = 587
|
||||
starttls = true
|
15
src/lib.rs
15
src/lib.rs
|
@ -1,6 +1,7 @@
|
|||
pub mod database;
|
||||
pub mod error;
|
||||
pub mod feature;
|
||||
pub mod mail;
|
||||
pub mod routing;
|
||||
pub mod server;
|
||||
pub mod utils;
|
||||
|
@ -26,12 +27,12 @@ impl Default for DatabaseConfig {
|
|||
|
||||
if header == "[database_config]" {
|
||||
Self {
|
||||
connection_pool_size: database_configs.pop().unwrap().parse().unwrap(),
|
||||
backend: database_configs.pop().unwrap(),
|
||||
database: database_configs.pop().unwrap(),
|
||||
password: database_configs.pop().unwrap(),
|
||||
username: database_configs.pop().unwrap(),
|
||||
address: database_configs.pop().unwrap(),
|
||||
address: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||
username: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||
password: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||
database: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||
backend: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||
connection_pool_size: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||
}
|
||||
} else {
|
||||
panic!("Database Config File Must Include [database_config] at the First Line")
|
||||
|
@ -50,7 +51,7 @@ impl Default for ServerConfig {
|
|||
|
||||
if header == "[server_config]" {
|
||||
Self {
|
||||
address: server_configs.pop().unwrap(),
|
||||
address: server_configs.pop_front().unwrap().parse().unwrap(),
|
||||
}
|
||||
} else {
|
||||
panic!("Server Config File Must Include [server_config] at the First Line")
|
||||
|
|
77
src/mail.rs
Normal file
77
src/mail.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
use lettre::{
|
||||
message::header::ContentType,
|
||||
transport::smtp::{self, authentication::Credentials},
|
||||
AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor,
|
||||
};
|
||||
|
||||
use crate::utils::naive_toml_parser;
|
||||
|
||||
const MAIL_CONFIG_FILE_LOCATION: &str = "./configs/mail_config.toml";
|
||||
|
||||
pub struct MailConfig {
|
||||
name: String,
|
||||
mail_address: String,
|
||||
username: String,
|
||||
password: String,
|
||||
relay_server: String,
|
||||
port: u16,
|
||||
starttls: bool,
|
||||
}
|
||||
|
||||
impl Default for MailConfig {
|
||||
fn default() -> Self {
|
||||
let (header, mut mail_configs) = naive_toml_parser(MAIL_CONFIG_FILE_LOCATION);
|
||||
|
||||
if header == "[mail_config]" {
|
||||
Self {
|
||||
name: mail_configs.pop_front().unwrap().parse().unwrap(),
|
||||
mail_address: mail_configs.pop_front().unwrap().parse().unwrap(),
|
||||
username: mail_configs.pop_front().unwrap().parse().unwrap(),
|
||||
password: mail_configs.pop_front().unwrap().parse().unwrap(),
|
||||
relay_server: mail_configs.pop_front().unwrap().parse().unwrap(),
|
||||
port: mail_configs.pop_front().unwrap().parse().unwrap(),
|
||||
starttls: mail_configs.pop_front().unwrap().parse().unwrap(),
|
||||
}
|
||||
} else {
|
||||
panic!("Mail Config File Must Include [mail_config] at the First Line")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_mail(
|
||||
receiver: &String,
|
||||
subject: &String,
|
||||
body: &String,
|
||||
) -> Result<smtp::response::Response, smtp::Error> {
|
||||
let mail_config = MailConfig::default();
|
||||
|
||||
let message = Message::builder()
|
||||
.from(
|
||||
format!("{} <{}>", mail_config.name, mail_config.mail_address)
|
||||
.parse()
|
||||
.unwrap(),
|
||||
)
|
||||
.to(format!("<{}>", receiver).parse().unwrap())
|
||||
.subject(subject)
|
||||
.header(ContentType::TEXT_PLAIN)
|
||||
.body(body.to_owned())
|
||||
.unwrap();
|
||||
|
||||
let credentials = Credentials::new(
|
||||
mail_config.username.to_owned(),
|
||||
mail_config.password.to_owned(),
|
||||
);
|
||||
|
||||
let mailer = match mail_config.starttls {
|
||||
true => AsyncSmtpTransport::<Tokio1Executor>::starttls_relay(&mail_config.relay_server),
|
||||
false => AsyncSmtpTransport::<Tokio1Executor>::relay(&mail_config.relay_server),
|
||||
};
|
||||
|
||||
let mailer = mailer
|
||||
.unwrap()
|
||||
.credentials(credentials)
|
||||
.port(mail_config.port)
|
||||
.build();
|
||||
|
||||
mailer.send(message).await
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
use std::{fs::File, io::Read};
|
||||
use std::{collections::VecDeque, fs::File, io::Read};
|
||||
|
||||
use crate::error::ForumInputError;
|
||||
|
||||
pub fn naive_toml_parser(file_location: &str) -> (String, Vec<String>) {
|
||||
pub fn naive_toml_parser(file_location: &str) -> (String, VecDeque<String>) {
|
||||
let mut toml_file = File::open(file_location).unwrap();
|
||||
let mut toml_ingredients = String::default();
|
||||
toml_file.read_to_string(&mut toml_ingredients).unwrap();
|
||||
let mut toml_ingredients = toml_ingredients.lines().collect::<Vec<&str>>();
|
||||
let mut toml_ingredients = toml_ingredients.lines().collect::<VecDeque<&str>>();
|
||||
|
||||
let header = toml_ingredients.remove(0).trim_end().to_string();
|
||||
let header = toml_ingredients.pop_front().unwrap().trim_end().to_string();
|
||||
let parsed = toml_ingredients
|
||||
.iter()
|
||||
.map(|ingredient| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue