Add attachment to Message::Builder() in Lettre email-sender

Hey

I am using Lettre which is a crate to send mails.

lettre = "0.10.0-alpha.4"
lettre_email = "0.9.4"

This is my code which works:

    let email = Message::builder()
                .from(from.parse().unwrap())
                .reply_to(to.parse().unwrap())
                .to(to.parse().unwrap())
                .subject(subject)
                .header(lettre::message::header::ContentType::TEXT_HTML)
                .body(email_html)
                .unwrap();

            let mailer = SmtpTransport::unencrypted_localhost();

But I nowhere, really nowhere, seem to find even one example on how to add an inline attachment (CID) to Message::Builder()...

Does someone how to do this?

Hey ONiel,

Take a look at the Attachment builder here https://docs.rs/lettre/0.10.0-rc.4/lettre/message/struct.Attachment.html, available with the crate feature builder.

There is an example in there to create an attachment:

use std::fs;

use lettre::message::{Attachment, header::ContentType};

let filename = String::from("invoice.pdf");
let filebody = fs::read("invoice.pdf")?;
let content_type = ContentType::parse("application/pdf").unwrap();
let attachment = Attachment::new(filename).body(filebody, content_type);

You can then attach this to the body of your email builder using multipart:

let email = Message::builder()
                .from(from.parse().unwrap())
                .reply_to(to.parse().unwrap())
                .to(to.parse().unwrap())
                .subject(subject)
		.multipart(
		    MultiPart::mixed()
			.singlepart(SinglePart::builder()
			    .header(header::ContentType::TEXT_HTML)
			    .body(email_html)
			)
			.singlepart(attachment)
		)
                .unwrap();

For more information on more complex multiparts, see here: https://docs.rs/lettre/0.10.0-rc.4/lettre/message/index.html#complex-mime-body

1 Like

Seems to work perfectly! Thanks!

This is my full code:

pub async fn send_mail(&self, from: String, to: String, subject: String, text: String) {
            let kaddo_logo_filename = "kaddo-logo".to_string();
            let kaddo_logo_filebody =
                std::fs::read("./templates/assets/media/email/kaddo.png".to_string()).unwrap();
            let kaddo_logo_attachment = Attachment::new_inline(kaddo_logo_filename.to_string())
                .body(
                    kaddo_logo_filebody,
                    ContentType::parse("image/png").unwrap(),
                );

            let facebook_logo_filename = "facebook-logo".to_string();
            let facebook_logo_filebody =
                std::fs::read("./templates/assets/media/email/facebook.png".to_string()).unwrap();
            let facebook_logo_attachment =
                Attachment::new_inline(facebook_logo_filename.to_string()).body(
                    facebook_logo_filebody,
                    ContentType::parse("image/png").unwrap(),
                );

            let instagram_logo_filename = "instagram-logo".to_string();
            let instagram_logo_filebody =
                std::fs::read("./templates/assets/media/email/instagram.png".to_string()).unwrap();
            let instagram_logo_attachment =
                Attachment::new_inline(instagram_logo_filename.to_string()).body(
                    instagram_logo_filebody,
                    ContentType::parse("image/png").unwrap(),
                );

            let linkedin_logo_filename = "linkedin-logo".to_string();
            let linkedin_logo_filebody =
                std::fs::read("./templates/assets/media/email/linkedin.png".to_string()).unwrap();
            let linkedin_logo_attachment =
                Attachment::new_inline(linkedin_logo_filename.to_string()).body(
                    linkedin_logo_filebody,
                    ContentType::parse("image/png").unwrap(),
                );

            let email_template_html: String =
                std::fs::read_to_string("./templates/email-templates/main-template.html")
                    .unwrap()
                    .parse()
                    .unwrap();

            let email_html: String = email_template_html.replace("%text%", &text);

            let email = Message::builder()
                .from(from.parse().unwrap())
                .reply_to(to.parse().unwrap())
                .to(to.parse().unwrap())
                .subject(subject)
                .multipart(
                    MultiPart::mixed()
                        .singlepart(
                            SinglePart::builder()
                                .header(header::ContentType::TEXT_HTML)
                                .body(email_html),
                        )
                        .singlepart(kaddo_logo_attachment)
                        .singlepart(facebook_logo_attachment)
                        .singlepart(instagram_logo_attachment)
                        .singlepart(linkedin_logo_attachment),
                )
                .unwrap();

            let mailer = SmtpTransport::unencrypted_localhost();

            match mailer.send(&email) {
                Ok(_) => println!("Email sent successfully!"),
                Err(e) => panic!("Could not send email: {:?}", e),
            }
        }

(Let me know if this can be written more short or elegant).

In the HTML of the mail, I just did:

...
<img src="cid:kaddo-logo" alt="Kaddo">
<img src="cid:facebook-logo" alt="Facebook">
...

Works like a charm!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.