Reputation:
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?
Upvotes: 3
Views: 5199
Reputation: 1
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{
("[email protected]"),
},
Source: aws.String("[email protected]"),
}
output, err := client.SendRawEmail(context.Background(), param)
if err != nil {
log.Println("Error: ", err)
return
}
log.Println("Sending successful, message ID: ", output.MessageId)
}
Upvotes: 0
Reputation: 17422
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.
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 := "[email protected]"
// mailFrom := os.Getenv("MAIL_FROM")
mailTo := "[email protected]"
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.
Upvotes: 4
Reputation: 5241
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 [email protected] with your "From" address.
// This address must be verified with Amazon SES.
Sender = "[email protected]"
// Replace [email protected] with a "To" address. If your account
// is still in the sandbox, this address must be verified.
Recipient = "[email protected]"
// 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)
}
Upvotes: 1
Reputation: 6345
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("[email protected]")},
},
Message: &ses.Message{
Body: &ses.Body{
Html: &ses.Content{
Data: aws.String("Body HTML")},
},
Subject: &ses.Content{
Data: aws.String("Subject"),
},
},
Source: aws.String("[email protected]"),
ReplyToAddresses: []*string{
aws.String("[email protected]"),
},
}
_, err := sesSession.SendEmail(sesEmailInput)
Upvotes: 19