Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sending email leads to an os error (invalid token) #893

Open
nkrofta opened this issue Jul 29, 2023 · 6 comments
Open

Sending email leads to an os error (invalid token) #893

nkrofta opened this issue Jul 29, 2023 · 6 comments

Comments

@nkrofta
Copy link

nkrofta commented Jul 29, 2023

Hi, I am trying to use lettre to send emails via the outlook smtp server smtp.office365.com:587. However, the send(...) function of AsyncSmtpTransport returns an error which I believe to be a bug.

The following code snippet shows the relevant part of my code:

pub struct MailTask {
    pub receiver: Mailbox,
    pub message: String
}

pub struct Mailman {
    mailbox_outlet: mpsc::Receiver<MailTask>,
    mail_account: Mailbox,
    transport: AsyncSmtpTransport<Tokio1Executor>,
    shutdown: ShutdownReceiver
}

impl Mailman {

    pub fn new(smtp_server: String, smtp_port: u16, mail_account: Mailbox, smtp_username: String, smtp_password: String, shutdown: ShutdownReceiver) -> (Mailman, mpsc::Sender<MailTask>) {
        let (mailbox, mailbox_outlet) = mpsc::channel(MAILBOX_SIZE);
        let credentials = Credentials::new(smtp_username, smtp_password);
        let transport: AsyncSmtpTransport<Tokio1Executor> = 
            AsyncSmtpTransport::<Tokio1Executor>::relay(&smtp_server)
            .unwrap()
            .port(smtp_port)
            .credentials(credentials)
            .build();
        let mailman = Mailman { mailbox_outlet, mail_account, transport, shutdown };
        (mailman, mailbox)
    }

    async fn deliver_mail(&self, task: MailTask) -> anyhow::Result<()> {
        let email = Message::builder()
            .from(self.mail_account.clone())
            .to(task.receiver)
            .subject("Email confirmation")
            .header(ContentType::TEXT_PLAIN)
            .body(task.message)
            .unwrap();
        self.transport.send(email).await.context("Failed to send mail")?;
        Ok(())
    }

}

The error (wrapped in an anyhow::Result with context "Failed to send mail"):

Failed to send mail

Caused by:
    0: Connection error: Connection error: Das Token, das der Funktion übergeben wurde, ist ungültig. (os error -2146893048)
    1: Connection error: Das Token, das der Funktion übergeben wurde, ist ungültig. (os error -2146893048)
    2: Das Token, das der Funktion übergeben wurde, ist ungültig. (os error -2146893048)

The German part means "The token given to the function is invalid." in English.
I am using Windows 11 and lettre v0.10.4.

@paolobarbolini
Copy link
Member

Could you try using an SMTP server from a different provider in order to figure out whether it's a Microsoft issue or something else?

@nkrofta
Copy link
Author

nkrofta commented Jul 30, 2023

I've just tested it with Gmail, same outcome.

@paolobarbolini
Copy link
Member

Are you by any chance putting in the port number together with the hostname parameter of relay?

@nkrofta
Copy link
Author

nkrofta commented Jul 30, 2023

You mean like "smtp.office365.com:587"? No, it's just "smtp.office365.com"

@rbaprado
Copy link

rbaprado commented Sep 6, 2023

I am facing the same problem using AWS SES

Reference snippet:

    // Build the message
    let email = Message::builder()
        .from(from_mailbox)
        .to(to_mailbox)
        .subject(subject)
        .multipart(
            MultiPart::alternative() // This is composed of two parts.
                .singlepart(
                    SinglePart::builder()
                        .header(header::ContentType::TEXT_PLAIN)
                        .body(String::from(body_txt)), // Every message should have a plain text fallback.
                )
                .singlepart(
                    SinglePart::builder()
                        .header(header::ContentType::TEXT_HTML)
                        .body(String::from(body_html)),
                ),
        )
        .unwrap();

    // Setup credentials
    let creds = Credentials::new(SETTINGS.smtp_user.clone(), SETTINGS.smtp_password.clone());

    // Open SMTP connection
    let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay(&SETTINGS.smtp_host)
        .unwrap()
        .credentials(creds)
        .port(SETTINGS.smtp_port)
        .build();

    // Send the email
    let send_result = mailer.send(email).await;

@rbaprado
Copy link

rbaprado commented Sep 6, 2023

Solved (at least for my case): changed relay() to starttls_relay()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants