use lettre::message::header::ContentType;
use lettre::message::{Attachment, MultiPart, SinglePart};
use lettre::transport::smtp::authentication::Credentials;
use lettre::{Message, SmtpTransport, Transport};
use std::fs;
pub struct SendEmailBuilder<'a> {
pub from: &'a str,
pub passwd: &'a str,
pub smtp: &'a str, pub receiver: &'a str,
pub _type: &'a str, pub title: &'a str,
pub content: &'a str,
pub file_path: Option<&'a str>,
}
fn get_content(_type: &str, content: &str) -> SinglePart {
if _type == "text" {
return SinglePart::plain(content.to_string());
}
SinglePart::builder()
.header(ContentType::TEXT_HTML)
.body(content.to_string())
}
fn file_to_attachment(path: &str) -> crate::core::error2::Result<SinglePart> {
let data = fs::read(path)?;
let filename = path.split('/').next_back().unwrap_or(path);
let mime = mime_guess::from_path(path)
.first_or_octet_stream()
.essence_str()
.to_string();
let content_type = mime.parse().map_err(|e| anyhow::anyhow!("{}", e))?;
Ok(Attachment::new(filename.to_string()).body(data, content_type))
}
pub async fn do_send_email(builder: &SendEmailBuilder<'_>) -> crate::core::error2::Result<()> {
let creds = Credentials::new(builder.from.to_string(), builder.passwd.to_string());
let mailer = SmtpTransport::relay(builder.smtp)
.unwrap()
.credentials(creds)
.build();
let email = Message::builder()
.from(builder.from.parse().unwrap())
.to(builder.receiver.parse().unwrap())
.subject(builder.title)
.singlepart(get_content(builder._type, builder.content))
.map_err(|e| anyhow::anyhow!("{}", e))?;
match mailer.send(&email) {
Ok(_) => {
log::info!(
"发送邮件成功: from={}, title={}, receiver={}",
builder.from,
builder.title,
builder.receiver
);
Ok(())
}
Err(e) => {
log::error!(
"发送邮件失败: from={}, title={}, receiver={}, error_message={}, Error={:?}",
builder.from,
builder.title,
builder.receiver,
e,
e
);
Err(crate::core::error2::Error::UnexpectedError(
anyhow::anyhow!(e),
))
}
}
}
pub async fn send_email_attachment(
builder: &SendEmailBuilder<'_>,
) -> crate::core::error2::Result<()> {
let creds = Credentials::new(builder.from.to_string(), builder.passwd.to_string());
let mailer = SmtpTransport::relay(builder.smtp)
.unwrap()
.credentials(creds)
.build();
let attachment = file_to_attachment(builder.file_path.unwrap())?;
let email = Message::builder()
.from(builder.from.parse().unwrap())
.to(builder.receiver.parse().unwrap())
.subject(builder.title)
.multipart(
MultiPart::mixed()
.singlepart(get_content(builder._type, builder.content))
.singlepart(attachment),
)
.map_err(|e| anyhow::anyhow!("{}", e))?;
match mailer.send(&email) {
Ok(_) => Ok(()),
Err(e) => {
log::error!(
"发送邮件失败: from={}, title={}, receiver={}, error_message={}, Error={:?}",
builder.from,
builder.title,
builder.receiver,
e,
e
);
Err(crate::core::error2::Error::UnexpectedError(
anyhow::anyhow!(e),
))
}
}
}