To create and send MIME messages with attachments in Go using the net/smtp
package, you can follow the steps below:
package main
import (
"net/smtp"
"net/textproto"
"mime/multipart"
"mime/quotedprintable"
"bytes"
"io/ioutil"
)
type EmailMessage struct {
From string
To []string
Subject string
TextBody string
HTMLBody string
Attachment []Attachment
}
type Attachment struct {
Filename string
Content []byte
}
func SendEmailMessage(smtpHost string, smtpPort int, smtpUsername string, smtpPassword string, message *EmailMessage) error {
auth := smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)
// Convert the email message into MIME format
mimeMessage := messageToMIME(message)
// Connect to the SMTP server
smtpAddr := fmt.Sprintf("%s:%d", smtpHost, smtpPort)
client, err := smtp.Dial(smtpAddr)
if err != nil {
return err
}
defer client.Close()
if err = client.Auth(auth); err != nil {
return err
}
if err = client.Mail(message.From); err != nil {
return err
}
// Loop through the recipients and add them to the email
for _, recipient := range message.To {
if err = client.Rcpt(recipient); err != nil {
return err
}
}
// Create a data writer to write the email data
dataWriter, err := client.Data()
if err != nil {
return err
}
defer dataWriter.Close()
// Write the MIME message to the data writer
_, err = dataWriter.Write(mimeMessage.Bytes())
if err != nil {
return err
}
return nil
}
func messageToMIME(message *EmailMessage) *bytes.Buffer {
buffer := new(bytes.Buffer)
writer := multipart.NewWriter(buffer)
// Create a new text/plain part for the email body
textPart, _ := writer.CreatePart(textproto.MIMEHeader{
"Content-Type": []string{"text/plain; charset=utf-8"},
})
textPart.Write([]byte(message.TextBody))
// Create a new text/html part for the email body if HTML body is present
if message.HTMLBody != "" {
htmlPart, _ := writer.CreatePart(textproto.MIMEHeader{
"Content-Type": []string{"text/html; charset=utf-8"},
})
htmlPart.Write([]byte(message.HTMLBody))
}
// Add attachments to the email
for _, attachment := range message.Attachment {
part, _ := writer.CreateFormFile("attachment", attachment.Filename)
part.Write(attachment.Content)
}
writer.Close()
return buffer
}
func main() {
// Define the email message
message := &EmailMessage{
From: "[email protected]",
To: []string{"[email protected]"},
Subject: "Test Email with Attachment",
TextBody: "This is a test email with an attachment.",
HTMLBody: "<html><body><h1>This is a test email with an attachment.</h1></body></html>",
Attachment: []Attachment{
{
Filename: "example.txt",
Content: []byte("This is the content of the attachment."),
},
},
}
// Call the send email function with your SMTP details
err := SendEmailMessage("smtp.example.com", 587, "[email protected]", "password", message)
if err != nil {
fmt.Println("Error sending email:", err)
} else {
fmt.Println("Email sent successfully!")
}
}
Ensure that you replace the placeholders smtp.example.com
with your SMTP server's address, 587
with the SMTP server's port, [email protected]
with the sender's email address, and [email protected]
with the recipient's email address.