use std::fs; use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm}; use actix_web::{post, HttpResponse}; use lettre::{ message::{header::ContentType, Attachment, MultiPart}, transport::smtp::authentication::{Credentials, Mechanism}, Message, SmtpTransport, Transport, }; #[derive(Debug, MultipartForm, Default)] struct MtForm { #[multipart(rename = "firstname")] first_name: Option>, #[multipart(rename = "lastname")] last_name: Option>, #[multipart(rename = "parentfirstname")] parent_first_name: Option>, #[multipart(rename = "parentlastname")] parent_last_name: Option>, birthdate: Option>, gender: Option>, street: Option>, city: Option>, state: Option>, zip: Option>, cellphone: Option>, parentphone: Option>, email: Option>, parentemail: Option>, school: Option>, grade: Option>, #[multipart(rename = "pastorfirstname")] pastor_first_name: Option>, #[multipart(rename = "pastorlastname")] pastor_last_name: Option>, #[multipart(rename = "churchattendance")] church_attendance: Option>, #[multipart(rename = "tfcgroup")] tfc_group: Option>, shirt: Option>, trip: Option>, #[multipart(rename = "tripnotes")] trip_notes: Option>, #[multipart(rename = "relationship-with-jesus")] relationship_with_jesus: Option>, #[multipart(rename = "testimony")] testimony: Option>, #[multipart(rename = "involvement-with-group")] involvement_with_group: Option>, #[multipart(rename = "reasons-for-trip-choice")] reasons: Option>, strengths: Option>, weaknesses: Option>, #[multipart(rename = "previous-trip-info")] previous_trip_info: Option>, #[multipart(rename = "attitude-torward-work")] attitude: Option>, #[multipart(rename = "relevant-notes")] relevant_notes: Option>, #[multipart(rename = "final-agreement")] final_agreement: Option>, registration: Option>, #[multipart(rename = "image")] file: Option, } #[post("/mt-form")] pub async fn mt_form(MultipartForm(form): MultipartForm) -> HttpResponse { let first = form.first_name.as_ref().unwrap().0.clone(); let last = form.last_name.as_ref().unwrap().0.clone(); let email_subject = format!("{} {} signed up for mission trip!", first, last); let filename_noext = String::from(format!("{}_{}", first, last)); let parent = format!( "{} {}", form.parent_first_name.as_ref().unwrap().0.clone(), form.parent_last_name.as_ref().unwrap().0.clone() ); let birthdate = form .birthdate .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let gender = form .gender .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let street = form .street .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let city = form .city .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let state = form .state .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let zip = form.zip.as_ref().unwrap_or(&Text { 0: 0 }).0.clone(); let cellphone = form .cellphone .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let parentphone = form .parentphone .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let email = form .email .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let parentemail = form .parentemail .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let school = form .school .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let grade = form .grade .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let pastor = format!( "{} {}", form.pastor_first_name .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(), form.pastor_last_name .as_ref() .unwrap_or(&Text { 0: String::from("") }) .0 .clone() ); let church_attendance = form .church_attendance .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let tfc_group = form .tfc_group .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let shirt = form .shirt .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let trip = form .trip .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let trip_notes = form .trip_notes .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let relationship = form .relationship_with_jesus .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let testimony = form .testimony .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let involvement = form .involvement_with_group .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let reasons = form .reasons .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let strengths = form .strengths .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let weaknesses = form .weaknesses .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let previous_trip = form .previous_trip_info .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let attitude = form .attitude .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let relevant = form .relevant_notes .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let final_agreement = form .final_agreement .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); let registration = form .registration .as_ref() .unwrap_or(&Text { 0: String::from(""), }) .0 .clone(); log::info!("{first} {last} signed up for mission trip!"); let email = markup::new! { @markup::doctype() html { head { title { @format!("{} {} signed up for mission trip!", first, last) } style { "table { border-collapse: collapse; width: 100% }" "td, th { padding: 8px }" "td { text-align: left; width: 70%; word-wrap: break-word }" "th { text-align: right; border-right: 1px solid #ddd }" "tr { border-bottom: 1px solid #ddd }" "h1 { text-align: center }" } } body { h1 { @format!("Mission trip form for {} {}!", first, last) } hr; table { tr { th { "Name" } td { @format!("{} {}", first, last) } } tr { th { "Parent" } td { @parent } } tr { th { "Birthdate" } td { @birthdate } } tr { th { "Gender" } td { @gender } } tr { th { "Street" } td { @street } } tr { th { "City" } td { @city } } tr { th { "State" } td { @state } } tr { th { "Zip" } td { @zip } } tr { th { "Phone" } td { @cellphone } } tr { th { "Parent Phone" } td { @parentphone } } tr { th { "Email" } td { @email } } tr { th { "Parent Email" } td { @parentemail } } tr { th { "School" } td { @school } } tr { th { "Grade" } td { @grade } } tr { th { "Pastor" } td { @pastor } } tr { th { "Church Attendance" } td { @church_attendance } } tr { th { "TFC Group" } td { @tfc_group } } tr { th { "T-Shirt Size" } td { @shirt } } tr { th { "Trip Choice" } td { @trip } } tr { th { "Extra Trip Notes" } td { @trip_notes } } tr { th { "Relationship with Jesus" } td { @relationship } } tr { th { "Testimony" } td { @testimony } } tr { th { "Involvement with TFC or Youth Group" } td { @involvement } } tr { th { "Reasons for trip choice" } td { @reasons } } tr { th { "Strengths" } td { @strengths } } tr { th { "Weaknesses" } td { @weaknesses } } tr { th { "Previous Trips" } td { @previous_trip } } tr { th { "Attitude Torward Work" } td { @attitude } } tr { th { "Other Relevant Info" } td { @relevant } } tr { th { "Final Agreement" } td { @final_agreement } } tr { th { "Registration" } td { @registration } } } } } }; let mut path: Option = Some(String::from("")); let mut file_exists = false; let mut filename = String::from(""); log::info!("{:?}", form); log::info!("{:?}", file_exists); if let Some(f) = form.file { if let Some(file) = f.file_name { if let Some(ext) = file.rsplit(".").next() { filename = format!("{}.{}", filename_noext, ext); path = Some(format!("./tmp/{}.{}", filename_noext, ext)); } else { path = Some(format!("./tmp/{}", file)); } // let path = format!("./tmp/{}", file); log::info!("saving to {}", path.clone().unwrap()); match f.file.persist(path.clone().unwrap()) { Ok(f) => { log::info!("{:?}", f); if f.metadata().unwrap().len() > 0 { file_exists = true; } } Err(e) => log::info!("{:?}: Probably a missing image", e), } } } let multi = if file_exists { let filebody = fs::read(path.clone().unwrap_or_default()); let content_type = ContentType::parse("image/jpg").unwrap(); let attachment = Attachment::new(filename).body(filebody.unwrap(), content_type); log::info!("{:?}", attachment); MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()) .singlepart(attachment) } else { MultiPart::alternative_plain_html(String::from("Testing"), email.to_string()) }; if let Ok(m) = Message::builder() .from( "TFC ADMIN " .parse() .unwrap(), ) .to("Chris Cochrun ".parse().unwrap()) .to("Ethan Rose ".parse().unwrap()) .subject(email_subject) .multipart(multi) { let sender = SmtpTransport::relay("mail.tfcconnection.org") .ok() .unwrap() .credentials(Credentials::new( "no-reply@mail.tfcconnection.org".to_owned(), "r9f36mNZFtiW4f".to_owned(), )) .authentication(vec![Mechanism::Plain]) .build(); match sender.send(&m) { Ok(res) => log::info!("{:?}", res), Err(e) => log::info!("{e}"), } } else { log::info!("Email incorrect"); } HttpResponse::Ok().body("thankyou") }