How to Send Emails with Go

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting up SMTP
  4. Sending Plain Text Emails
  5. Sending HTML Emails
  6. Sending Email with Attachments
  7. Conclusion


Introduction

In this tutorial, we will learn how to send emails using Go programming language. We will cover various scenarios like sending plain text emails, sending HTML emails, and even sending emails with attachments. By the end of this tutorial, you will be able to integrate email functionality into your Go applications.

Prerequisites

Before starting this tutorial, you should have basic knowledge of Go programming language. Additionally, you need to have Go installed on your machine.

Setting up SMTP

To send emails, we need to connect to an SMTP server. In this tutorial, we will use the net/smtp package in Go, which provides the necessary tools for interfacing with SMTP servers.

First, let’s import the net/smtp package:

import (
    "net/smtp"
)

To connect to an SMTP server, we need to provide its address and port. We also need to authenticate with our username and password. Here’s an example of how to set up an SMTP client:

func setupSMTPClient() (*smtp.Client, error) {
    auth := smtp.PlainAuth("", "[email protected]", "your-password", "smtp.example.com")
    client, err := smtp.Dial("smtp.example.com:587")
    if err != nil {
        return nil, err
    }
    if err := client.Auth(auth); err != nil {
        return nil, err
    }
    return client, nil
}

Make sure to replace "[email protected]", "your-password", and "smtp.example.com" with your own email, password, and SMTP server address.

Sending Plain Text Emails

Now that we have set up our SMTP client, let’s see how to send a plain text email:

func sendPlainTextEmail() error {
    client, err := setupSMTPClient()
    if err != nil {
        return err
    }
    defer client.Quit()

    // Set the sender and recipient email addresses
    from := "[email protected]"
    to := []string{"[email protected]"}

    // Set the email subject and body
    subject := "Hello from Go!"
    body := "This is a plain text email sent from Go."

    // Compose the email message
    msg := "From: " + from + "\r\n" +
        "To: " + strings.Join(to, ",") + "\r\n" +
        "Subject: " + subject + "\r\n" +
        "\r\n" +
        body + "\r\n"

    // Send the email
    if err := client.Mail(from); err != nil {
        return err
    }
    for _, address := range to {
        if err := client.Rcpt(address); err != nil {
            return err
        }
    }
    w, err := client.Data()
    if err != nil {
        return err
    }
    _, err = w.Write([]byte(msg))
    if err != nil {
        return err
    }
    err = w.Close()
    if err != nil {
        return err
    }

    return nil
}

In the above code, we set up the sender and recipient email addresses, the email subject, and the email body. We then compose the email message and send it using the client.Mail, client.Rcpt, and client.Data methods.

Sending HTML Emails

If you want to send HTML emails, you can modify the code slightly to include HTML content in the email body. Here’s an example:

func sendHTMLEmail() error {
    client, err := setupSMTPClient()
    if err != nil {
        return err
    }
    defer client.Quit()

    from := "[email protected]"
    to := []string{"[email protected]"}

    subject := "Hello from Go!"
    body := "<html><body><h1>This is an HTML email sent from Go.</h1></body></html>"

    msg := "From: " + from + "\r\n" +
        "To: " + strings.Join(to, ",") + "\r\n" +
        "Subject: " + subject + "\r\n" +
        "MIME-version: 1.0;\r\n" +
        "Content-Type: text/html; charset=\"UTF-8\";\r\n" +
        "\r\n" +
        body + "\r\n"

    if err := client.Mail(from); err != nil {
        return err
    }
    for _, address := range to {
        if err := client.Rcpt(address); err != nil {
            return err
        }
    }
    w, err := client.Data()
    if err != nil {
        return err
    }
    _, err = w.Write([]byte(msg))
    if err != nil {
        return err
    }
    err = w.Close()
    if err != nil {
        return err
    }

    return nil
}

In the above code, we added the MIME-version and Content-Type headers to indicate that the email contains HTML content. We also set the email body as an HTML string.

Sending Email with Attachments

To send an email with attachments, we need to use the mime/multipart package in Go. Here’s an example:

func sendEmailWithAttachments() error {
    client, err := setupSMTPClient()
    if err != nil {
        return err
    }
    defer client.Quit()

    from := "[email protected]"
    to := []string{"[email protected]"}

    subject := "Hello from Go!"
    body := "This is an email with attachment sent from Go."

    // Compose the email message
    buf := new(bytes.Buffer)
    writer := multipart.NewWriter(buf)

    // Create the email headers
    headers := make(map[string]string)
    headers["From"] = from
    headers["To"] = strings.Join(to, ",")
    headers["Subject"] = subject
    headers["MIME-version"] = "1.0"
    headers["Content-Type"] = writer.FormDataContentType()

    // Write the headers to the buffer
    for key, value := range headers {
        _ = writer.WriteField(key, value)
    }

    // Add the email body
    _ = writer.WriteField("Body", body)

    // Add attachments
    fileContents, _ := ioutil.ReadFile("attachment.txt") // Replace with the path to your attachment file
    fileWriter, _ := writer.CreateFormFile("attachment", "attachment.txt")
    _, _ = fileWriter.Write(fileContents)

    // Close the writer
    _ = writer.Close()

    // Send the email
    if err := client.Mail(from); err != nil {
        return err
    }
    for _, address := range to {
        if err := client.Rcpt(address); err != nil {
            return err
        }
    }
    w, err := client.Data()
    if err != nil {
        return err
    }
    _, err = w.Write(buf.Bytes())
    if err != nil {
        return err
    }
    err = w.Close()
    if err != nil {
        return err
    }

    return nil
}

In the above code, we create a multipart.Writer to handle the MIME structure of the email. We add the email headers and body using WriteField(), and then add the attachment using CreateFormFile() and Write(). Finally, we send the email as usual.

Conclusion

In this tutorial, we learned how to send emails using Go. We covered the basics of setting up an SMTP client and sending plain text emails, HTML emails, and emails with attachments. With this knowledge, you can now incorporate email functionality into your Go applications. Experiment with different email libraries and explore additional features to enhance your email-sending capabilities.