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]
|
[dependencies]
|
||||||
axum = "0.7.9"
|
axum = "0.7.9"
|
||||||
chrono = { version = "0.4.38", features = ["serde"] }
|
chrono = { version = "0.4.39", features = ["serde"] }
|
||||||
serde = { version = "1.0.215", features = ["derive"] }
|
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"
|
serde_json = "1.0.133"
|
||||||
sqlx = { version = "0.8.2", features = ["chrono", "macros", "postgres", "runtime-tokio-rustls"] }
|
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"] }
|
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 database;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod feature;
|
pub mod feature;
|
||||||
|
pub mod mail;
|
||||||
pub mod routing;
|
pub mod routing;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
@ -26,12 +27,12 @@ impl Default for DatabaseConfig {
|
||||||
|
|
||||||
if header == "[database_config]" {
|
if header == "[database_config]" {
|
||||||
Self {
|
Self {
|
||||||
connection_pool_size: database_configs.pop().unwrap().parse().unwrap(),
|
address: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||||
backend: database_configs.pop().unwrap(),
|
username: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||||
database: database_configs.pop().unwrap(),
|
password: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||||
password: database_configs.pop().unwrap(),
|
database: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||||
username: database_configs.pop().unwrap(),
|
backend: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||||
address: database_configs.pop().unwrap(),
|
connection_pool_size: database_configs.pop_front().unwrap().parse().unwrap(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("Database Config File Must Include [database_config] at the First Line")
|
panic!("Database Config File Must Include [database_config] at the First Line")
|
||||||
|
@ -50,7 +51,7 @@ impl Default for ServerConfig {
|
||||||
|
|
||||||
if header == "[server_config]" {
|
if header == "[server_config]" {
|
||||||
Self {
|
Self {
|
||||||
address: server_configs.pop().unwrap(),
|
address: server_configs.pop_front().unwrap().parse().unwrap(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("Server Config File Must Include [server_config] at the First Line")
|
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;
|
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_file = File::open(file_location).unwrap();
|
||||||
let mut toml_ingredients = String::default();
|
let mut toml_ingredients = String::default();
|
||||||
toml_file.read_to_string(&mut toml_ingredients).unwrap();
|
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
|
let parsed = toml_ingredients
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ingredient| {
|
.map(|ingredient| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue