简体   繁体   中英

How to integrate aws sdk ses in golang?

I'm using AWS to host my server in Go language. I am stuck as I'm not sure how to use their AWS SES SDK to send an email. Any ideas?

It is pretty straightforward as shown in the link from your question.

What are you having trouble with ?

Minimal Example :

Imports : github.com/aws/aws-sdk-go/aws , github.com/aws/aws-sdk-go/service/ses and github.com/aws/aws-sdk-go/aws/credentials , github.com/aws/aws-sdk-go/aws/session

awsSession := session.New(&aws.Config{
        Region:      aws.String("aws.region"),
        Credentials: credentials.NewStaticCredentials("aws.accessKeyID", "aws.secretAccessKey" , ""),
    })

sesSession := ses.New(awsSession)

sesEmailInput := &ses.SendEmailInput{
    Destination: &ses.Destination{
        ToAddresses:  []*string{aws.String("receiver@xyz.com")},
    },
    Message: &ses.Message{
        Body: &ses.Body{
            Html: &ses.Content{
                Data: aws.String("Body HTML")},
        },
        Subject: &ses.Content{
            Data: aws.String("Subject"),
        },
    },
    Source: aws.String("sender@xyz.com"),
    ReplyToAddresses: []*string{
        aws.String("sender@xyz.com"),
    },
}

_, err := sesSession.SendEmail(sesEmailInput)

Refer here for a well-documented example : https://docs.aws.amazon.com/ses/latest/DeveloperGuide/examples-send-using-sdk.html

package main

import (
    "fmt"
    
    //go get -u github.com/aws/aws-sdk-go
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ses"
    "github.com/aws/aws-sdk-go/aws/awserr"
)

const (
    // Replace sender@example.com with your "From" address. 
    // This address must be verified with Amazon SES.
    Sender = "sender@example.com"
    
    // Replace recipient@example.com with a "To" address. If your account 
    // is still in the sandbox, this address must be verified.
    Recipient = "recipient@example.com"

    // Specify a configuration set. If you do not want to use a configuration
    // set, comment out the following constant and the 
    // ConfigurationSetName: aws.String(ConfigurationSet) argument below
    ConfigurationSet = "ConfigSet"
    
    // Replace us-west-2 with the AWS Region you're using for Amazon SES.
    AwsRegion = "us-west-2"
    
    // The subject line for the email.
    Subject = "Amazon SES Test (AWS SDK for Go)"
    
    // The HTML body for the email.
    HtmlBody =  "<h1>Amazon SES Test Email (AWS SDK for Go)</h1><p>This email was sent with " +
                "<a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the " +
                "<a href='https://aws.amazon.com/sdk-for-go/'>AWS SDK for Go</a>.</p>"
    
    //The email body for recipients with non-HTML email clients.
    TextBody = "This email was sent with Amazon SES using the AWS SDK for Go."
    
    // The character encoding for the email.
    CharSet = "UTF-8"
)

func main() {
    
    // Create a new session and specify an AWS Region.
    sess, err := session.NewSession(&aws.Config{
        Region:aws.String(AwsRegion)},
    )
    
    // Create an SES client in the session.
    svc := ses.New(sess)
    
    // Assemble the email.
    input := &ses.SendEmailInput{
        Destination: &ses.Destination{
            CcAddresses: []*string{
            },
            ToAddresses: []*string{
                aws.String(Recipient),
            },
        },
        Message: &ses.Message{
            Body: &ses.Body{
                Html: &ses.Content{
                    Charset: aws.String(CharSet),
                    Data:    aws.String(HtmlBody),
                },
                Text: &ses.Content{
                    Charset: aws.String(CharSet),
                    Data:    aws.String(TextBody),
                },
            },
            Subject: &ses.Content{
                Charset: aws.String(CharSet),
                Data:    aws.String(Subject),
            },
        },
        Source: aws.String(Sender),
            // Comment or remove the following line if you are not using a configuration set
            ConfigurationSetName: aws.String(ConfigurationSet),
    }

    // Attempt to send the email.
    result, err := svc.SendEmail(input)
    
    // Display error messages if they occur.
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok {
            switch aerr.Code() {
            case ses.ErrCodeMessageRejected:
                fmt.Println(ses.ErrCodeMessageRejected, aerr.Error())
            case ses.ErrCodeMailFromDomainNotVerifiedException:
                fmt.Println(ses.ErrCodeMailFromDomainNotVerifiedException, aerr.Error())
            case ses.ErrCodeConfigurationSetDoesNotExistException:
                fmt.Println(ses.ErrCodeConfigurationSetDoesNotExistException, aerr.Error())
            default:
                fmt.Println(aerr.Error())
            }
        } else {
            // Print the error, cast err to awserr.Error to get the Code and
            // Message from an error.
            fmt.Println(err.Error())
        }
        return
    }
    
    fmt.Println("Email Sent!")
    fmt.Println(result)
}

The internet is littered with outdated SES examples for golang. Even Amazon's own code examples are outdated ( https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/ses-example-send-email.html ), and that leads developers towards the use of older documentation.

It's 2022! And this is how you implement SES.


The AWS GO SDK is on version 2
https://github.com/aws/aws-sdk-go-v2

The AWS GO SES SDK is also on version 2
https://github.com/aws/aws-sdk-go-v2/tree/main/service/sesv2

So we'll start by importing these packages. Note: Sessions from AWS GO SDK version 1 are no longer used, and have been replaced with Config.

package main

import (
  "github.com/aws/aws-sdk-go-v2/config"
  "github.com/aws/aws-sdk-go-v2/credentials"
  "github.com/aws/aws-sdk-go-v2/service/sesv2"
)

Next you'll need to setup your Amazon service key, and service secret key. This can be done multiple ways ( https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/ ). The recommended practice from Go documentation is to initialize within an init function ( https://go.dev/doc/effective_go#init ), so that's where I setup credentials.

var mailClient *sesv2.Client

func init() {
  accessKey := os.Getenv("AWS_ACCESS_KEY")
  secretKey := os.Getenv("AWS_SECRET_KEY")
  region := os.Getenv("AWS_REGION")

  amazonConfiguration, createAmazonConfigurationError :=
    config.LoadDefaultConfig(
      context.Background(),
      config.WithRegion(region),
      config.WithCredentialsProvider(
        credentials.NewStaticCredentialsProvider(
          accessKey, secretKey, "",
        ),
      ),
    )

  if createAmazonConfigurationError != nil {
    // log error
  }

  mailClient = sesv2.NewFromConfig(amazonConfiguration)
}

The final step, is to use the configured service to send an email from main or another function.

func main() {
  mailFrom := "sender@example.com"
  // mailFrom := os.Getenv("MAIL_FROM")
  mailTo := "reciever@example.com"

  charset := aws.String("UTF-8")
  mail := &sesv2.SendEmailInput{
    FromEmailAddress: aws.String(mailTo),
    Destination: &types.Destination{
      ToAddresses: []string{ mailTo },
    },
    Content: &types.EmailContent{
      Simple: &types.Message{
        Subject: &types.Content{
          Charset: charset,
          Data: aws.String("subject"),
        },
        Body: &types.Body{
          Text: &types.Content{
            Charset: charset,
            Data: aws.String("body"),
          },
        },
      },
    },
  }

  _, createMailError := mailClient.sendMail(context.Background(), mail)

  if createMailError != nil {
    // log error
  }
}

Note: I consider the need for aws.String() objects in these SDKs, the result of poor software design on the part of the Amazon Web Services team. Primitive strings "" should be used in the design instead; because (a) it's easier for developers to work with primitives (no need for pointers * and de-referencing & ), and (b) primitives use stack allocation, and have higher performance than string objects which use heap allocation.

Here is an example of sending raw email using Amazon SES v2 SDK

https://github.com/aws/aws-sdk-go-v2

Note: There are some prerequisites before you can start sending and receiving emails. Follow this

package main

import (
    "context"
    "log"
    "os"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/ses"
    "github.com/aws/aws-sdk-go-v2/service/ses/types"
)

func main() {
    // Load the shared AWS configuration (~/.aws/config)
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := ses.NewFromConfig(cfg)
    // Read any EML file
    eml, err := os.ReadFile("./example.eml")
    if err != nil {
        log.Fatal("Error: ", err)
    }

    param := &ses.SendRawEmailInput{
        RawMessage: &types.RawMessage{
            Data: eml,
        },
        Destinations: []string{
            ("pqr@outlook.com"),
        },
        Source: aws.String("abc@test.com"),
    }
    output, err := client.SendRawEmail(context.Background(), param)
    if err != nil {
        log.Println("Error: ", err)
        return
    }
    log.Println("Sending successful, message ID: ", output.MessageId)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM