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"),
};