🎃

Go で SES を使ってメールを送る際ローカルで確認する方法

に公開

何をするのか

Go で AWS SES SDK V2 を使ってメールを送信するときローカルで送信の確認をしたいと思います。
送信だけするすごく簡単な例を書きます。

何を使うのか

  • go
  • aws-sdk-go-v2
  • aws-ses-v2-local
  • bun

実装

まずは docker-compose.ymlを作ります

bunを使い凄く簡単にaws-ses-v2-localのコンテナーを立てるのが可能です。

docker-compose.yml
services:
  mail:
    image: oven/bun:1
    ports:
      - 8005:8005
    command: bunx aws-ses-v2-local@2.5.1 --host=0.0.0.0

AWSConfig用のファイルを作ります

/internal/awsconfig/awsconfig.goを作ります。

awsconfig.go
package awsconfig

import (
	"context"

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

// NewAWSConfigはregionとendpointを受け取り、AWS configを返します。
func NewAWSConfig(ctx context.Context, region, endpoint string) (aws.Config, error) {
	return config.LoadDefaultConfig(
		ctx,
		config.WithRegion(region),
		config.WithBaseEndpoint(endpoint),
	)
}

// NewDefaultAWSConfigはデフォルトのregionとendpointを使用してAWS configを返します。
func NewDefaultAWSConfig(ctx context.Context) (aws.Config, error) {
	return NewAWSConfig(ctx, "ap-northeast-1", "http://localhost:8005")
}

Mailのファイルを作ります

/mail/mail.goを作ります。

mail.go
package mail

import (
	"context"
	"fmt"

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

type Mail interface {
	SendEmail(ctx context.Context, title, content, to, from string) error
}

type mail struct {
	client *sesv2.Client
}

func NewMail(cfg aws.Config) Mail {
	return &mail{
		client: sesv2.NewFromConfig(cfg),
	}
}

// SendEmail メールを送信します。
func (m *mail) SendEmail(ctx context.Context, title string, content string, to string, from string) error {
	_, err := m.client.SendEmail(ctx, &sesv2.SendEmailInput{
		Destination: &types.Destination{
			ToAddresses: []string{to},
		},
		FromEmailAddress: aws.String(from),
		Content: &types.EmailContent{
			Simple: &types.Message{
				Subject: &types.Content{
					Data: aws.String(title),
				},
				Body: &types.Body{
					Text: &types.Content{
						Data: aws.String(content),
					},
				},
			},
		},
	})
	if err != nil {
		return fmt.Errorf("failed to send email: %w", err)
	}

	return nil
}

Mail ファイルを作ります

/mai.goを作ります。

main.go
package main

import (
	"context"
	"go-mail/internal/awsconfig"
	"go-mail/mail"
	"log"
)

func main() {
	ctx := context.Background()

	// 基本 AWSConfig を生成する
	cfg, err := awsconfig.NewDefaultAWSConfig(ctx)
	if err != nil {
		log.Fatalf("failed to load AWS config: %v", err)
	}
	// メールインスタンスを生成する
	m := mail.NewMail(cfg)

	// メールを送信する
	err = m.SendEmail(ctx, "Test mail subject", "Test mail body", "kopher@kopher.com", "kopher@kopher.co.jp")
	if err != nil {
		log.Fatalf("failed to send email: %v", err)
	}
}

動作確認

では、動作確認してみましょう!

  1. コンテナーを立ち上げます
docker-compose up -d
  1. メール送信プログラム実行します
go run main.go
  1. ブラウザで確認
    http://localhost:8005/ で確認できます

全体コード

https://github.com/kopher1601/go-studies/tree/main/go-mail

Discussion