Lines
82 %
Functions
22.22 %
Branches
100 %
use crate::{
error::{Error, Result},
mail_config::MailConfig,
};
use lettre::{
message::{
header::{ContentType, MessageId, MimeVersion},
Mailbox,
},
transport::{
file::FileTransport,
smtp::{authentication::Credentials, extension::ClientId},
Message, SmtpTransport, Transport,
use std::path::PathBuf;
/// This struct holds information about how to connect to the smtp server.
/// It also handles creating mails and storing sent mails in project folders.
pub struct Mailer {
config: MailConfig,
}
fn addr(mail: &str, name: Option<&str>) -> Result<Mailbox> {
Ok(Mailbox::new(
name.map(|n| n.to_string()),
mail.parse()
.map_err(|e| Error::Msg(format!("Cannot parse mail address {}: {}", mail, e)))?,
))
impl Mailer {
pub fn new(config: MailConfig) -> Result<Self> {
Ok(Self { config })
/// Send a mail to the contact person of a proposal.
/// A CC is sent to the NLnet alias for managing the project.
/// The Reply-To is also set to that alias.
/// The mail is saved in the `mail/` folder in the project directory.
pub fn send_mail(
&self,
subject: &str,
body: &str,
to_mail: &str,
to_name: &str,
cc: &[&str],
) -> std::result::Result<(), Box<dyn std::error::Error>> {
let mut builder = Message::builder();
builder = builder.to(addr(to_mail, Some(to_name))?);
for cc in cc {
builder = builder.cc(addr(cc, None)?);
let email = builder
.header(ContentType::TEXT_PLAIN)
.header(MessageId::from(format!(
"{}@{}",
uuid::Uuid::new_v4(),
self.config.mail_server
)))
.header(MimeVersion::new(1, 0))
.from(addr(&self.config.sender, None)?)
.subject(subject)
.body(body.to_string())?;
let mail_dir = "out".to_string();
std::fs::create_dir_all(&mail_dir).map_err(|e| Error::Io {
source: e,
path: PathBuf::from(&mail_dir),
})?;
let file_transport = FileTransport::new(mail_dir);
file_transport.send(&email)?;
if !self.config.testing {
let credentials =
Credentials::new(self.config.username.clone(), self.config.password.clone());
let mailer = SmtpTransport::relay(&self.config.mail_server)?
.hello_name(ClientId::Domain(self.config.mail_server.clone()))
.credentials(credentials)
.build();
mailer.send(&email)?;
Ok(())