use lettre::message::Mailbox; use lettre::transport::smtp::client::Tls; use lettre::{Message, SmtpTransport, Transport}; pub fn send_notification( id: i64, question: &str, notify_email: &str, ) -> Result<(), Box> { let truncated = if question.len() > 50 { format!("{}...", &question[..50]) } else { question.to_string() }; let from: Mailbox = "Q&A ".parse()?; let reply_to: Mailbox = format!("qa+{id}@extremist.software").parse()?; let to: Mailbox = notify_email.parse()?; let email = Message::builder() .from(from) .reply_to(reply_to) .to(to) .subject(format!("Q&A #{id}: {truncated}")) .body(question.to_string())?; let mailer = SmtpTransport::builder_dangerous("localhost") .tls(Tls::None) .build(); mailer.send(&email)?; Ok(()) } pub fn strip_quoted_text(body: &str) -> String { let mut result = Vec::new(); for line in body.lines() { if line.starts_with('>') { continue; } if line.starts_with("On ") && line.ends_with("wrote:") { break; } result.push(line); } result.join("\n").trim().to_string() } pub fn extract_id_from_address(to: &str) -> Result> { let addr = to.trim(); let addr = if let Some(start) = addr.find('<') { &addr[start + 1..addr.find('>').unwrap_or(addr.len())] } else { addr }; let local = addr.split('@').next().unwrap_or(""); let id_str = local .strip_prefix("qa+") .ok_or("No qa+ prefix in address")?; Ok(id_str.parse()?) }