こんにちは、なかにしです。
皆様はメールの送受信、何で実装してますか?
フロントエンドしか使えない状況だと EmailJS のようなSaasを、バックエンドが使える場合はライブラリなどで実装されるかと思います。
私もバックエンドが使える場合は基本的にnodemailer などで実装するのですが、折角なのであまり使ったことないものを使おうかなーと思い、Amazon SESを選択しました。
今回はその記事になります。
Amazon SESとは
Amazonのサービスの1つで、メール送信 Saas/Paas です。
Amazonいわく、
高可用性で低価格なEメール送信サービス
だそうです。
何かをつくって動かすときは、クラウドサービスを使うことが多いと思うので、Emailもついでにできると便利ですね。
料金
詳しくは こちら 。
▼ 2025年6月現在
送信:1,000 件あたり$0.10
受信:1,000 件あたり$0.10
安ッ。
大規模なサイト以外は、10円~30円/月 くらいで済みそうですね。
やってみる
フロントの実装は EmailJS とほぼ変わりません。
それをバックエンドで受け取って、
バックエンドからAmazon SESにリクエストを送ってメール送信をする感じですね。
バックエンドが必要なので、Next.jsで実装します。
SESの設定をする
AWSにログインし、SESを選択します。
「SESをはじめる」的なボタンがあるので、押下します。
いろいろ設定していきます。
▼ まずは送信元となるメールアドレス。

▼ 次に送信元となるドメイン
今回はたまたま余っているドメインがあったので、それを利用します。

▼ なんかオプション
(開封率とかみれるっぽいです。すごい)

▼ 最後に確認画面

登録は完了したみたいです。
ここから、「未解決のタスク」を解決していきます。

テストメール送信
テストメールを送信してみます。

諸々入力して…

※From-addressとCCを同じメールアドレスになるようにします。
理由は、まだテスト環境なので、認証済のメールアドレスしか送受信できない為です。
現在は、送信元として設定したメールアドレスのみ認証済なので、送信元、受取先ともに同じメールアドレスを使用します。
入力したら、送信!
▼ 送れたらしいです。

▼ 届いたらしいです。
(迷惑メールに入りました。)

本番アクセスのリクエスト
ドメインの検証が終わったら、本番アクセスのリクエストができるようになりました。

▼ ポチポチ設定していきます

▼ どこで使うのーって言われました。
今回はテストなのでローカルを選びます。
vercelなどのIaasにデプロイして動かす場合は、
AWS の外部で実行されるアプリケーションを選びます。

発行したアクセスキーとシークレットキーは控えておきます。
アクセスユーザーの設定
Amazon SESにアクセスできるユーザーを設定していきます。
IAM > ユーザー > ユーザーの新規作成で作成します。

※SESの許可ポリシーを忘れずに!!
ユーザー作成が終わりましたが、アクセスキーがありません。

ユーザーを押下し、アクセスキーを発行します。
発行したアクセスIDと、シークレットキーは後ほど使うので、控えておきます。

メールテンプレートの作成
メールテンプレートを作成し、AWSに登録します。
現在は、何も登録されていません。

テンプレートの登録には、 AWS CLIが必要です。
以下よりダウンロードします。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions
Windowsの場合は、インストーラを起動していつも通りポチポチします。
私はすべてデフォルトで Install しました。
以下コマンドでバージョンが出れば、完了です。
aws --version
続いて、aws cliのコマンドを使うため、クレデンシャルを登録します。
aws config
先ほど作成したIAMのID, SECRET_KEYなどを入力します。

好きな場所に、テンプレートを作成します。
{
"Template": {
"TemplateName": "test-template-1",
"SubjectPart": "{{name}}様 / HPからのお問い合わせです。",
"HtmlPart": "<h1>こんにちは、{{name}}さん!</h1><p>あなたのコードは <b>{{code}}</b> です。</p>",
"TextPart": "これはテキストメールです。\nコード: {{code}}"
}
}
作成したテンプレートを、aws cli で送ります。
私は「template.json」という名前で作成したので、そのファイルを指定しています。
aws ses create-template --cli-input-json file://template.json --region us-east-1
登録されました。

登録した中身は、get-template コマンドで見れます。
aws ses get-template --template-name test-template-1 --region us-east-1
ちゃんと登録されていました。
PS C:\Users\hiro\OneDrive\Desktop\ses\aa\email-template> aws ses get-template --template-name test-template-1 --region us-east-1
{
"Template": {
"TemplateName": "test-template-1",
"SubjectPart": "{{name}}様 / HPからのお問い合わせです。",
"TextPart": "これはテキストメールです。\nコード: {{code}}",
"HtmlPart": "<h1>こんにちは、{{name}}さん!</h1><p>あなたのコードは <b>{{code}}</b> です。</p>"
}
}
フォームを準備する(Next.js)
Next.jsでテンプレートを準備
npx create-next-app
フロントエンドにフォームを作成
"use client";
import { useState } from "react";
export default function Home() {
const [form, setForm] = useState({ name: "", email: "", code: "" });
const [status, setStatus] = useState<string | null>(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setStatus(null);
const res = await fetch("/api/send", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(form),
});
const data = await res.json();
setStatus(data.message);
};
return (
<div style={{ padding: "2rem", width: "40%", backgroundColor: "skyblue" }}>
<h1>お問い合わせふぉーむ</h1>
<form
onSubmit={handleSubmit}
style={{
display: "flex",
flexDirection: "column",
gap: "4rem",
marginTop: "2rem",
}}
>
<input
type="text"
placeholder="お名前"
value={form.name}
onChange={(e) => setForm({ ...form, name: e.target.value })}
required
style={{ border: "1px solid" }}
/>
<input
type="email"
placeholder="メールアドレス"
value={form.email}
onChange={(e) => setForm({ ...form, email: e.target.value })}
required
style={{ border: "1px solid" }}
/>
<textarea
placeholder="コード"
value={form.code}
onChange={(e) => setForm({ ...form, code: e.target.value })}
required
style={{ border: "1px solid" }}
/>
<button
type="submit"
style={{
border: "1px solid",
padding: "1rem",
width: "40%",
backgroundColor: "white",
}}
>
送信
</button>
{status && <p>{status}</p>}
</form>
</div>
);
}
バックエンドにメール送信用のAPIを作成します。
今回は、/api/sendに作成しました。
import { SESClient, SendTemplatedEmailCommand } from "@aws-sdk/client-ses";
import { NextRequest, NextResponse } from "next/server";
const ses = new SESClient({
region: process.env.AWS_REGION,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});
export async function POST(req: NextRequest) {
if (req.method !== "POST") return NextResponse.json({ nice: "Nice" });
const { name, code, email } = await req.json();
const command = new SendTemplatedEmailCommand({
Source: process.env.SES_FROM_EMAIL!,
Destination: {
ToAddresses: [email],
},
Template: "test-template-1",
TemplateData: JSON.stringify({
name,
code,
}),
});
try {
await ses.send(command);
return NextResponse.json(
{ message: "テンプレートメール送信成功" },
{ status: 200 }
);
} catch (err) {
console.error(err);
return NextResponse.json(
{ message: "送信失敗", error: err },
{ status: 500 }
);
}
}
環境変数ファイルも忘れずに
# IAM情報
AWS_ACCESS_KEY_ID=[IAMユーザのID]
AWS_SECRET_ACCESS_KEY=[IAMユーザのSECRET_KEY]
AWS_REGION=[メールテンプレートがあるリージョン]
# 送信元アドレス
SES_FROM_EMAIL=[送信元メールアドレス]
メールを送る
いよいよメールを送ります。
フォームに入力して、送信!

届きました。

さいごに
ちゃんとドメインの設定とかをすれば、迷惑メールには入らないそうです。
EmailJSやNodemailerと比べると、結構手順が多かったです。
まぁ、本来このくらいかかるんでしょうね。
EmailJS や Nodemailer が簡単すぎるだけで。
AWS や Google Cloud(旧GCP)などのクラウドサービスは基本的に
①専用ユーザを作成(クレデンシャルを控える)
②CLIをインストール
③クレデンシャルを登録
④ローカルから設定を送る
の流れになります。
手順は多いですが、Google Cloudで同じようなことをやっていたので、そこまで迷わずにサクッとできました。
まぁでも考えることも多いですし、
気軽に選ぶ選択肢ではないかなーという所感です。
しかしながら、ちゃんとした所だと十分選択肢になり得るので、「やったことある」は大事です。
今後も有名どころは触っておきたいなーと改めて思いました。
次は AWS Lambdaかなー。
今回はここまで!
Enjoy Hacking!!