Introduced e-mail parsing and minor error handling for encoding or parsing issues
This commit is contained in:
parent
5ac1425b44
commit
ad3245f884
3 changed files with 58 additions and 3 deletions
|
@ -11,6 +11,7 @@ serde = "1.0.144"
|
||||||
serde_yaml = "0.9.10"
|
serde_yaml = "0.9.10"
|
||||||
|
|
||||||
postbus = "0.2.0"
|
postbus = "0.2.0"
|
||||||
|
mailparse = "0.13.8"
|
||||||
ruma = "0.6.4"
|
ruma = "0.6.4"
|
||||||
matrix-sdk = "0.5.0"
|
matrix-sdk = "0.5.0"
|
||||||
|
|
||||||
|
|
56
src/main.rs
56
src/main.rs
|
@ -1,5 +1,6 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use mailparse::ParsedMail;
|
||||||
use matrix_sdk::Client;
|
use matrix_sdk::Client;
|
||||||
use postbus::{Handler, SmtpService, SmtpState, command::Mailbox};
|
use postbus::{Handler, SmtpService, SmtpState, command::Mailbox};
|
||||||
use crate::config::Mapping;
|
use crate::config::Mapping;
|
||||||
|
@ -56,8 +57,61 @@ impl Handler for ToMatrixConverter {
|
||||||
}
|
}
|
||||||
async fn save(&self, state: &SmtpState) -> bool {
|
async fn save(&self, state: &SmtpState) -> bool {
|
||||||
for recipient in &state.recipients {
|
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:<br>{}", &state.data),
|
||||||
|
&self.matrix_clients, &self.mappings).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mail_to_plain_message(mail: &ParsedMail, from: &Option<Mailbox>, 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<Mailbox>, to: &Mailbox) -> String {
|
||||||
|
format!("<b>From</b> {} <b>to</b> {}<br><b>Subject:</b> {}<hline>{}",
|
||||||
|
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) => "<b>WARNING! E-mail content could not be decoded.<b>".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)
|
||||||
}
|
}
|
|
@ -84,7 +84,7 @@ async fn client_from_mxid(mxid: &str, clients: &Vec<Client>) -> Option<Client> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(from_mail: &Option<Mailbox>, recipient: &Mailbox, content: &str, clients: &Vec<Client>, mappings: &Vec<Mapping>) {
|
pub async fn send(from_mail: &Option<Mailbox>, recipient: &Mailbox, plain_content: &str, html_content: &str, clients: &Vec<Client>, mappings: &Vec<Mapping>) {
|
||||||
for mapping in mappings {
|
for mapping in mappings {
|
||||||
let mut applies = true;
|
let mut applies = true;
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ pub async fn send(from_mail: &Option<Mailbox>, recipient: &Mailbox, content: &st
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match room.send(RoomMessageEventContent::text_html(content, content), None).await {
|
match room.send(RoomMessageEventContent::text_html(plain_content, html_content), None).await {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_e) => println!("Sending message failed"),
|
Err(_e) => println!("Sending message failed"),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue