DEV Community

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

Posted on • Edited on

2

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

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

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!

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay