Open joepio opened 2 years ago
I've managed to get mail-send
working with a local SMTP server (although not properly embedded in Atomic-Server).
But if I use mailin_embedded
, the process doesn't exit:
use mailin_embedded::{AuthMechanism, Handler, Server, SslConfig};
use tracing::info;
use crate::errors::AtomicServerResult;
#[derive(Clone)]
struct MailHandler {}
impl Handler for MailHandler {}
const ADDRESS: &str = "127.0.0.1:12041";
const ADDRESS_MAILCATCHER: &str = "127.0.0.1:1025";
pub fn start_mail_server() -> AtomicServerResult<()> {
let handler = MailHandler {};
let mut server = Server::new(handler);
let address = ADDRESS;
server
.with_name("example.com")
.with_auth(AuthMechanism::Plain)
.with_ssl(SslConfig::None)
.map_err(|e| format!("Mail SSL error: {e}"))?
.with_addr(address)
.map_err(|e| format!("Mail address error: {e}"))?;
tokio::spawn(async move { send_mail().await });
tokio::task::spawn_blocking(move || {
info!("Starting mail server at {address}");
// TODO: stop this process on ctrl+C
server.serve().expect("Failed to start mail server");
});
Ok(())
}
I've got an SMTP client in atomic-lib working, so we can use it from Endpoint plugins.
However, I'm having doubts on the API to use for send_mail. Specifically, I'm not sure if I should use async
(#424)
Since the plugin itself is not async, the code becomes pretty verbose, and we're cloning the Store
:
let store_clone = store.clone();
tokio::spawn(async move {
store_clone
.send_email(message)
.await
.unwrap_or_else(|e| tracing::error!("Error sending email: {}", e));
});
If it was just sync, we'd get something like this, but the response would have to wait for the SMTP server. Slow!
store.send_email(message)?;
But in the future, we should expect plugins to do async stuff without blocking the whole thread.
At some point, we'll want to send e-mails. For notifications, registrations, or newsletters, for example.
Usecases for sending mails
your export is ready to download
Usecases for receiving mail
Implementation
I think it makes sense to offer an e-mail API at the plugin level. Not sure what that means, as at the very least, some sort of server listening to a specific set of ports will need to be started. Maybe
atomic-lib
may need a runtime, too, at some point, as now onlyatomic-server
does.Plugins should be able to send e-mails. That means that plugins need access to the mailed functions and SMTP connection state. So that probably means that we need the mailer to be available from
Db
. We could set amailer
Db::init
, which means we need some extra arguments there, or we could set it on a separate function, atDb::set_mailer
.Email for registration / verification
VerificationRequest
resource that represents this URL, we need to make sure that it is not indexed, similar toInvites
. See #235Crates
mail-send
orlettre
. I'm having a hard time shutting it down, though.