From ad3245f88434456feef27e45fcd6ed86dd7c47ba Mon Sep 17 00:00:00 2001 From: "Philip (a-0)" <@ph:a-0.me> Date: Sat, 3 Sep 2022 21:02:22 +0200 Subject: [PATCH] Introduced e-mail parsing and minor error handling for encoding or parsing issues --- Cargo.toml | 1 + src/main.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/matrix.rs | 4 ++-- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 61ff008..a41a6da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ serde = "1.0.144" serde_yaml = "0.9.10" postbus = "0.2.0" +mailparse = "0.13.8" ruma = "0.6.4" matrix-sdk = "0.5.0" diff --git a/src/main.rs b/src/main.rs index 1e2c2f6..b09859b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use std::sync::Arc; use async_trait::async_trait; +use mailparse::ParsedMail; use matrix_sdk::Client; use postbus::{Handler, SmtpService, SmtpState, command::Mailbox}; use crate::config::Mapping; @@ -56,8 +57,61 @@ impl Handler for ToMatrixConverter { } async fn save(&self, state: &SmtpState) -> bool { for recipient in &state.recipients { - matrix::send(&state.from, &recipient, &state.data, &self.matrix_clients, &self.mappings).await; + match mailparse::parse_mail(state.data.as_bytes()) { + Ok(mail) => matrix::send(&state.from, &recipient, + &mail_to_plain_message(&mail, &state.from, &recipient), + &mail_to_html_message(&mail, &state.from, &recipient), + &self.matrix_clients, &self.mappings).await, + Err(e) => { + println!("{}", e); + matrix::send(&state.from, &recipient, + &format!("Error parsing e-mail. This is a dump of the whole data section:\n{}", &state.data), + &format!("Error parsing e-mail. This is a dump of the whole data section:
{}", &state.data), + &self.matrix_clients, &self.mappings).await; + } + } } true } +} + +fn mail_to_plain_message(mail: &ParsedMail, from: &Option, to: &Mailbox) -> String { + format!("From {} to {}\nSubject: {}\n---\n{}", + match from { + Some(fr) => mailbox_to_addr(fr), + None => "[unknown sender]".to_string(), + }, + mailbox_to_addr(to), + get_subject(mail), + match mail.get_body() { + Ok(body) => body, + Err(e) => "WARNING! E-mail content could not be decoded.".to_string(), + } + ) +} +fn mail_to_html_message(mail: &ParsedMail, from: &Option, to: &Mailbox) -> String { + format!("From {} to {}
Subject: {}{}", + match from { + Some(fr) => mailbox_to_addr(fr), + None => "[unknown sender]".to_string(), + }, + mailbox_to_addr(to), + get_subject(mail), + match mail.get_body() { + Ok(body) => body, + Err(e) => "WARNING! E-mail content could not be decoded.".to_string(), + } + ) +} + +fn get_subject(mail: &ParsedMail) -> String { + for header in &mail.headers { + if header.get_key() == "Subject" { + return header.get_value(); + } + } + return String::from("[no subject found]"); +} +pub fn mailbox_to_addr(mb: &Mailbox) -> String { + format!("{}@{}", mb.local, mb.domain.0) } \ No newline at end of file diff --git a/src/matrix.rs b/src/matrix.rs index e43121c..eaca4aa 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -84,7 +84,7 @@ async fn client_from_mxid(mxid: &str, clients: &Vec) -> Option { None } -pub async fn send(from_mail: &Option, recipient: &Mailbox, content: &str, clients: &Vec, mappings: &Vec) { +pub async fn send(from_mail: &Option, recipient: &Mailbox, plain_content: &str, html_content: &str, clients: &Vec, mappings: &Vec) { for mapping in mappings { let mut applies = true; @@ -151,7 +151,7 @@ pub async fn send(from_mail: &Option, recipient: &Mailbox, content: &st continue; } }; - match room.send(RoomMessageEventContent::text_html(content, content), None).await { + match room.send(RoomMessageEventContent::text_html(plain_content, html_content), None).await { Ok(_) => (), Err(_e) => println!("Sending message failed"), };