feat: use rust mail-parser (#104)

* feat: imp worker v2

* feat: add rust mail-parser

* feat: imp frontend v2

* feat: imp frontend v2

* feat: update doc

* feat: add mailV1Alert

* feat: remove unused
This commit is contained in:
Dream Hunter
2024-04-09 14:58:19 +08:00
committed by GitHub
parent 105d51ff91
commit def400eb09
27 changed files with 856 additions and 533 deletions

14
mail-parser-wasm/.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

View File

@@ -0,0 +1,13 @@
[package]
name = "mail-parser-wasm"
version = "0.1.6"
edition = "2021"
description = "A simple mail parser for wasm"
license = "MIT"
[lib]
crate-type = ["cdylib"]
[dependencies]
mail-parser = "0.9.3"
wasm-bindgen = "0.2.92"

View File

@@ -0,0 +1,16 @@
# mail-parser-wasm
## usage
```js
import { parse_message } from 'mail-parser-wasm'
const parsedEmail = parse_message(item.raw);
```
## build
```bash
wasm-pack build --release
wasm-pack publish
```

159
mail-parser-wasm/src/lib.rs Normal file
View File

@@ -0,0 +1,159 @@
extern crate wasm_bindgen;
use mail_parser::{MessageParser, MimeHeaders};
use wasm_bindgen::prelude::*;
#[derive(Clone)]
#[wasm_bindgen]
pub struct AttachmentResult {
content_id: String,
content_type: String,
filename: String,
content: Vec<u8>,
}
#[wasm_bindgen]
impl AttachmentResult {
#[wasm_bindgen(getter)]
pub fn content_id(&self) -> String {
self.content_id.clone()
}
#[wasm_bindgen(getter)]
pub fn content_type(&self) -> String {
self.content_type.clone()
}
#[wasm_bindgen(getter)]
pub fn filename(&self) -> String {
self.filename.clone()
}
#[wasm_bindgen(getter)]
pub fn content(&self) -> Vec<u8> {
self.content.clone()
}
}
#[wasm_bindgen]
pub struct MessageResult {
sender: String,
subject: String,
body_html: String,
text: String,
attachments: Vec<AttachmentResult>,
}
#[wasm_bindgen]
impl MessageResult {
#[wasm_bindgen(getter)]
pub fn sender(&self) -> String {
self.sender.clone()
}
#[wasm_bindgen(getter)]
pub fn subject(&self) -> String {
self.subject.clone()
}
#[wasm_bindgen(getter)]
pub fn body_html(&self) -> String {
self.body_html.clone()
}
#[wasm_bindgen(getter)]
pub fn text(&self) -> String {
self.text.clone()
}
#[wasm_bindgen(getter)]
pub fn attachments(&self) -> Vec<AttachmentResult> {
self.attachments.clone()
}
}
pub fn parse_attachment(message: &mail_parser::Message) -> Vec<AttachmentResult> {
let mut attachments: Vec<AttachmentResult> = Vec::new();
for attachment in message.attachments() {
if !attachment.is_message() {
attachments.push(AttachmentResult {
content_id: attachment
.content_id()
.map(|id| id.to_owned())
.unwrap_or(String::new()),
content_type: attachment
.content_type()
.map(|ct| {
let c_type = ct.c_type.clone().into_owned();
let c_subtype = ct.c_subtype.clone();
if c_subtype.is_none() {
return c_type;
} else {
return format!("{}/{}", c_type, c_subtype.unwrap());
}
})
.unwrap_or(String::new()),
filename: attachment
.attachment_name()
.map(|name| name.to_owned())
.unwrap_or(String::new()),
content: attachment.contents().to_vec(),
});
} else {
attachments.append(
&mut attachment
.message()
.map(|msg| parse_attachment(msg))
.unwrap_or(Vec::new()),
);
}
}
attachments
}
#[wasm_bindgen]
pub fn parse_message(raw_message: &str) -> MessageResult {
// check if the message is valid
let res = MessageParser::default().parse(raw_message);
if res.is_none() {
return MessageResult {
sender: String::new(),
subject: String::new(),
body_html: String::new(),
text: String::new(),
attachments: Vec::new(),
};
}
let message = res.unwrap();
MessageResult {
sender: message
.from()
.and_then(|from| from.first())
.map(|addr| {
if addr.name().is_some() {
return format!(
"{} <{}>",
addr.name().unwrap(),
addr.address().unwrap_or("")
);
} else {
return addr.address().unwrap_or("").to_owned();
}
})
.unwrap_or(String::new()),
subject: message
.subject()
.map(|subject| subject.to_owned())
.unwrap_or(String::new()),
body_html: message
.body_html(0)
.map(|html| html.into_owned())
.unwrap_or(String::new()),
text: message
.body_text(0)
.map(|text| text.into_owned())
.unwrap_or(String::new()),
attachments: parse_attachment(&message),
}
}