AWS SDKを使ってGolangからSES経由でメールを送る

MMMサーバサイドエンジニアの柳沼です。
お世話になっております。
夏が来ましたが、北海道はまだかなり涼しいです。

最近Golangを使ってWeb APIをスクラッチ開発しています。
そんな中で、Amazon SES (Simple Email Service) を使ってメールを送らなければいけない箇所があり、やり方を紹介します。

AWS SDK for Go を導入する

いい感じのライブラリがあれば使ってしまおうと思っていたのですが、どうやらなさそう(Goはライブラリの選定に悩むことが多いですね…)だったため、SDKを使います。

今回必要なのはAWS SDK for Goです。
インストールは普通に

1
$ go get github.com/aws/aws-sdk-go/aws/...

でもいいのですが、SESで使用するものだけで十分なため、以下のようにインストールしました。

1
$ go get github.com/aws/aws-sdk-go/aws
$ go get github.com/aws/aws-sdk-go/aws/session
$ go get github.com/aws/aws-sdk-go/services/ses

これで、SESで必要なパッケージだけインストールすることができます。

事前準備

今回は以下の環境変数が必要です。事前に設定しておいてください。

1
AWS_ACCESS_KEY_ID: AWSのアクセスキーID
AWS_SECRET_KEY: AWSのシークレットキー
AWS_SES_ENDPOINT: SESのエンドポイント。以下参照。
AWS_REGION: SESのリージョン。以下参照。

エンドポイントとリージョンはこちらを見て設定してください。
今回はリージョンが US East (N. Virginia) だったため、

1
AWS_SES_ENDPOINT: email.us-east-1.amazonaws.com
AWS_REGION: us-east-1

と設定しました。

また、SESでverifyされているメールアドレスを用意しておいてください。

コード

SDKでは基本的に、セッションを作って、サービスを作って、サービスから各メソッドを呼び出す、というフローを踏みます。SESでも例外ではありません。
セッションはSDKを使用するための設定オブジェクトのようなもので、以下のように作ります。

1
sess := session.NewSession()

ただし、引数に *aws.Config{} を渡すこともできます。
引数がない場合は、上で定義した環境変数から各情報を取得し、セッションが作られます。

サービスは、sessを使って以下のように作成します。

1
svc := ses.New(sess)

次に、inputを作成します。inputを作るためには最低限、Destination, Message, Sourceが必要です。
Destinationは、送り先の情報,
Messageは、titleとbody,
Sourceは送り元の情報を持ちます。こちらには、上述のverify済メールアドレスを使います。

以下のように作成してください。

1
input := &ses.SendEmailInput{
    Destination: &ses.Destination{
        ToAddresses: []*string{
            aws.String("toaddress@example.com"),
        },
    },
    Message: &ses.Message{
        Body: &ses.Body{
            Text: &ses.Content{
                Charset: aws.String("UTF-8"),
                Data:    aws.String("ここにメッセージのボディを埋め込んでください。\nで改行が可能です。"),
            },
        },
        Subject: &ses.Content{
            Charset: aws.String("UTF-8"),
            Data:    aws.String("メッセージの件名"),
        },
    },
    Source:        aws.String("fromaddress@example.com"),
}

あとはこれを、

1
svc.SendEmail(input)

のように送信します。全体のコードは以下です。

1
package main

import (
  "errors"
  "github.com/aws/aws-sdk-go/aws"
  "github.com/aws/aws-sdk-go/aws/session"
  "github.com/aws/aws-sdk-go/service/ses"
  "log"
)

func main() {
	from := "from@example.jp"
	to := "to@example.jp"
	title := "メール件名"
	body := "メール本文"
	err := SendEmail(from, to, title, body)
	if err != nil {
		log.Println("mail sending error")
	}
}

func SendEmail(from string, to string, title string, body string) error {
  svc := ses.New(session.NewSession())
  input := &ses.SendEmailInput{
    Destination: &ses.Destination{
      ToAddresses: []*string{
        aws.String(to),
      },
    },
    Message: &ses.Message{
      Body: &ses.Body{
        Text: &ses.Content{
          Charset: aws.String("UTF-8"),
          Data:    aws.String(body),
        },
      },
      Subject: &ses.Content{
        Charset: aws.String("UTF-8"),
        Data:    aws.String(title),
      },
    },
    Source: aws.String(from),
  }
  _, err := svc.SendEmail(input)
  if err != nil {
    return errors.New(err.Error())
  }
  return nil
}

Destinationはこちらのように、CCやBCCを入れることも可能です。

まとめ

AWS SDK for Goを初めて使ったのですが、インタフェースがシンプルで使いやすかったです。
今後もAWSをGoから使っていこうと思います。

このエントリーをはてなブックマークに追加