DEV Community

Cover image for Send email with GO + AWS SES for multiple recipents and many attached files
Rafael Firmino
Rafael Firmino

Posted on • Updated on

Send email with GO + AWS SES for multiple recipents and many attached files

This is a simple example how send email for many recipients and add many attachments using SES

package main

import (
    "fmt"
    "log"
    "strings"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ses"
)

type EmailData struct {
    From      string
    Recipient Recipient
    Subject   string
    Body      string
    Attachs   map[string][]byte
}

type Recipient struct {
    To  []string
    Cc  []string
    Bcc []string
}

func main() {
    sesClient, err := getSesClient()
    if err != nil {
        fmt.Println(err)
    }

    emailData := EmailData{
        From: "teste@example.com.br",
        Recipient: Recipient{
            To:  []string{"teste2@example.com.br"},
            Cc:  []string{"teste2@example.com.br", "teste3@example.com.br"},
            Bcc: []string{"teste4@example.com.br"},
        },
        Subject: "Subject Example",
        Body:    "Body Example",
        Attachs: map[string][]byte{
            "file1": []byte("attach1"),
            "file2": []byte("attach2"),
            "file3": []byte("attach3"),
            "file4": []byte("attach4"),
        },
    }
    _, err = sesClient.SendRawEmail(emailData.MountEmail())
    if err != nil {
        log.Fatal("error for send email:", err)
    }

}

func (e *EmailData) MountEmail() *ses.SendRawEmailInput {
    header := fmt.Sprintf("From: %s\r\n", e.From)
    header += fmt.Sprintf("To: %s\r\n", strings.Join(e.Recipient.To, ", "))
    header += fmt.Sprintf("Cc: %s\r\n", strings.Join(e.Recipient.Cc, ", "))
    header += fmt.Sprintf("Subject: %s\r\n", strings.Join(e.Recipient.Bcc, ", "))
    header += "MIME-Version: 1.0\r\n"
    header += "Content-Type: multipart/mixed; boundary=\"Boundary\"\r\n\r\n"

    //BodyPart
    bodyPart := fmt.Sprintf("--Boundary\r\n")
    bodyPart += fmt.Sprintf("Content-Type: text/plain; charset=\"UTF-8\"\r\n")
    bodyPart += fmt.Sprintf("Content-Disposition: inline\r\n\r\n")
    bodyPart += fmt.Sprintf("%s\r\n\r\n", e.Body)

    attachmentParts := ""
    for filename, attachment := range e.Attachs {
        attachmentPart := fmt.Sprintf("--Boundary\r\n")
        attachmentPart += fmt.Sprintf("Content-Type: application/octet-stream\r\n")
        attachmentPart += fmt.Sprintf("Content-Disposition: attachment; filename=\"%s\"\r\n\r\n", filename)
        attachmentPart += string(attachment) + "\r\n"
        attachmentParts += attachmentPart
    }

    endPart := fmt.Sprintf("\r\n--Boundary--")
    rawMessage := header + bodyPart + attachmentParts + endPart
    email := &ses.SendRawEmailInput{
        RawMessage: &ses.RawMessage{
            Data: []byte(rawMessage),
        },
    }

    return email
}

func getSesClient() (*ses.SES, error) {
    awsSession, err := session.NewSession(&aws.Config{
        Region: aws.String("us-east-1"),
    })
    if err != nil {
        fmt.Println(err)
        return nil, err
    }
    sesClient := ses.New(awsSession)

    return sesClient, err
}
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
nigel447 profile image
nigel447

thanks for writing this, a totally insignificant typo where I am sure you meant to write Recipient instead of Recipiente in the Recipient type declaration, thanks again

Collapse
 
rafaelgfirmino profile image
Rafael Firmino

Thanks!