initial commit
This commit is contained in:
commit
9e38b07589
|
@ -0,0 +1 @@
|
||||||
|
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "website-form"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
lettre = "0.11.7"
|
||||||
|
axum = "0.7.5"
|
||||||
|
serde = { version = "1.0.201", features = ["derive"] }
|
||||||
|
serde_json = "1.0.117"
|
||||||
|
axum-server = "0.6.0"
|
|
@ -0,0 +1,81 @@
|
||||||
|
use axum::{
|
||||||
|
extract::Form,
|
||||||
|
handler::post,
|
||||||
|
response::Html,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use axum_server;
|
||||||
|
|
||||||
|
use lettre::message::Message;
|
||||||
|
use lettre::transport::smtp::SmtpTransport;
|
||||||
|
use lettre::{AsyncSmtpTransport, AsyncTransport, Tokio1Executor};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct FormData {
|
||||||
|
name: String,
|
||||||
|
email: String,
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
let app = Router::new().route("/submit-email", post(handle_form));
|
||||||
|
|
||||||
|
let addr = SocketAddr::from(([127, 0, 0, 1], 6900));
|
||||||
|
println!("Listening on {}", addr);
|
||||||
|
axum_server::Server::bind(&addr)
|
||||||
|
.serve(app.into_make_service())
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_form(Form(form): Form<FormData>) -> Html<String> {
|
||||||
|
match send_email(form).await {
|
||||||
|
Ok(_) => Html("Form submitted successfully.".to_string()),
|
||||||
|
Err(e) => Html(format!("Error sending email.")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_email(form: FormData) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let email = Message::builder()
|
||||||
|
.from(form.email.parse()?)
|
||||||
|
.to("sales@distrust.co".parse()?)
|
||||||
|
.subject("New Website Form Inquiry")
|
||||||
|
.body(format!("Name {}\nEmail: {}\nMessage: {}", form.name, form.email, form.message))?;
|
||||||
|
|
||||||
|
let mailer: AsyncSmtpTransport<Tokio1Executor> = SmtpTransport::builder_dangerous.build();
|
||||||
|
mailer.send(email).await {
|
||||||
|
Ok(_) -> Ok(());
|
||||||
|
Err(e) -> {
|
||||||
|
println!("Failed to send email: {}", e);
|
||||||
|
Err(Box::new(e) as Box<dyn std::error:Error>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use axum::body::Body;
|
||||||
|
use axum::http::{Request, StatusCode};
|
||||||
|
use axum::Router;
|
||||||
|
use tower::ServiceExt;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_handle_form() {
|
||||||
|
let app = Router::new().route("/submit-email", post(handle_form));
|
||||||
|
|
||||||
|
let response = app
|
||||||
|
.oneshot(
|
||||||
|
Request::post("submit-email")
|
||||||
|
.header("content-type", "application/x-www-form-urlencoded")
|
||||||
|
.body(Body::from("name=Lisan Al Ghaib&email=paul@atreides.com&message=The spice must flow."))
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq(response.status(), StatusCode::OK);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
use axum::{
|
||||||
|
routing::post,
|
||||||
|
Router,
|
||||||
|
Form,
|
||||||
|
response::IntoResponse,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
use lettre::{Message, SmtpTransport, Transport};
|
||||||
|
use lettre::message::Mailbox;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct FormData {
|
||||||
|
name: String,
|
||||||
|
email: String,
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
let app = Router::new().route("/submit-email", post(handle_form));
|
||||||
|
|
||||||
|
let addr = SocketAddr::from(([0, 0, 0, 0], 4200));
|
||||||
|
println!("Listening on {}", addr);
|
||||||
|
|
||||||
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:4200").await.unwrap();
|
||||||
|
axum::serve(listener, app).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_form(Form(form_data): Form<FormData>) -> impl IntoResponse {
|
||||||
|
match send_email(form_data).await {
|
||||||
|
Ok(_) => format!("Form submitted successfully"),
|
||||||
|
Err(_) => format!("Error sending email."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_email(form_data: FormData) -> Result<(), Box<dyn Error>> {
|
||||||
|
let email = Message::builder()
|
||||||
|
.from(form_data.email.parse::<Mailbox>()?)
|
||||||
|
.to("sales@distrust.co".parse()?)
|
||||||
|
.subject("New Website Form Inquiry")
|
||||||
|
.body(format!("Name: {}/nEmail: {}/nMessage: {}", form_data.name, form_data.email, form_data.message))?;
|
||||||
|
|
||||||
|
let mailer = SmtpTransport::relay("smtp.distrust.co")?
|
||||||
|
.build();
|
||||||
|
|
||||||
|
mailer.send(&email)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue