コンテンツにスキップ

AstroとResendを使用してフォーム送信を送信する

Last reviewed: 3 months ago

Developer Spotlight community contribution

Written by: Cody Walsh

Profile: LinkedIn

このチュートリアルでは、AstroとCloudflare Workers(Cloudflare SSR Adapter経由)を使用してResendからメールを送信する方法を説明します。

前提条件

このチュートリアルを進める前に、以下の設定を確認してください:

1. 新しいAstroプロジェクトを作成し、Cloudflare Adapterをインストールする:

ターミナルを開き、以下のコマンドを実行します:

Astroプロジェクトを作成
npm create cloudflare@latest my-astro-app -- --framework=astro

プロジェクトの設定を行うためのプロンプトに従い、TypeScriptの使用、TypeScriptの厳密性、バージョン管理、デプロイメントの好みのオプションを選択します。

初期インストールが完了したら、新しく作成されたプロジェクトディレクトリmy-astro-appに移動し、以下を実行してCloudflareアダプターを追加します:

Cloudflare Adapterをインストール
npm run astro add cloudflare

@astrojs/cloudflareアダプターは、Astroのサーバーサイドレンダリング(SSR)サイトとコンポーネントがCloudflare Pagesで動作するようにし、AstroのエンドポイントをCloudflare Workersのエンドポイントに変換します。

2. Resendにドメインを追加する

  1. CloudflareからResendにドメインを追加する:
    • Resendにサインアップした後、サイドメニューに移動し、Domainsをクリックします。
    • 新しいドメインを追加するボタンを探してクリックします。
    • ポップアップが表示され、ドメインを入力できます。入力後、地域を選択し、addボタンをクリックします。
    • addボタンをクリックすると、ResendからDNSレコード(DKIM、SPF、DMARC)のリストが提供されます。
  2. ResendからCloudflareにDNSレコードをコピーする:
    • Cloudflareダッシュボードに戻ります。
    • 使用するドメインを選択し、「DNS」セクションを見つけます。
    • ResendからCloudflareにDNSレコードをコピーして貼り付けます。
  3. ドメインを確認する:
    • Resendに戻り、「Verify DNS Records」ボタンをクリックします。
    • すべてが正しく設定されていれば、ドメインのステータスが「Verified」に変わります。
  4. APIキーを作成する:
    • Resendで、サイドメニューの「API Keys」オプションを見つけてクリックします。
    • 説明的な名前で新しいAPIキーを作成し、フルアクセス権限を与えます。
  5. ローカル開発とデプロイされたWorker用にAPIキーを保存する
    • ローカル開発用に、Astroプロジェクトのルートフォルダーに.envを作成し、APIキーをRESEND_API_KEY=‘Api key here’(引用符なし)として保存します。
    • デプロイされたWorker用には、CLIで以下を実行し、指示に従います。
Terminal window
npx wrangler secret put RESEND_API_KEY

3. Astroエンドポイントを作成する

src/pagesディレクトリにapiという新しいフォルダーを作成します。apiフォルダー内にsendEmail.json.tsという新しいファイルを作成します。これにより、/api/sendEmail.jsonにエンドポイントが作成されます。

以下のコードをsendEmail.json.tsファイルにコピーします。このコードは、フォーム送信を処理し、フォームデータを検証するPOSTルートを設定します。

export const prerender = false; //この行がないと動作しません
import type { APIRoute } from "astro";
export const POST: APIRoute = async ({ request }) => {
const data = await request.formData();
const name = data.get("name");
const email = data.get("email");
const message = data.get("message"); // データを検証 - 値が空でないことを確認
if (!name || !email || !message) {
return new Response(null, {
status: 404,
statusText: "正しいデータが提供されていません",
});
}
};

4. Resendを使用してメールを送信する

次に、Resend SDKをインストールする必要があります。

ResendのSDKをインストール
npm i resend

SDKがインストールされたら、ResendのAPIを使用してメールを送信する残りのコードを追加し、Resendの応答が成功したかどうかを条件付きでチェックします。

export const prerender = false; //この行がないと動作しません
import type { APIRoute } from "astro";
import { Resend } from "resend";
const resend = new Resend(import.meta.env.RESEND_API_KEY);
export const POST: APIRoute = async ({ request }) => {
const data = await request.formData();
const name = data.get("name");
const email = data.get("email");
const message = data.get("message"); // データを検証 - 値が空でないことを確認
if (!name || !email || !message) {
return new Response(
JSON.stringify({
message: `すべてのフィールドを入力してください。`,
}),
{
status: 404,
statusText: "正しいデータが提供されていません",
},
);
} // Resendに情報を送信
const sendResend = await resend.emails.send({
from: "support@resend.dev",
to: "delivered@resend.dev",
subject: `Sumbission from ${name}`,
html: `<p>こんにちは ${name}、</p><p>あなたのメッセージは受信されました。</p>`,
}); // メッセージが正常に送信された場合、200レスポンスを返します
if (sendResend.data) {
return new Response(
JSON.stringify({
message: `メッセージが正常に送信されました!`,
}),
{
status: 200,
statusText: "OK",
},
); // メッセージの送信にエラーがあった場合、500レスポンスを返します
} else {
return new Response(
JSON.stringify({
message: `メッセージの送信に失敗しました: ${sendResend.error}`,
}),
{
status: 500,
statusText: `内部サーバーエラー: ${sendResend.error}`,
},
);
}
};

5. Astroフォームコンポーネントを作成する

srcディレクトリにcomponentsという新しいフォルダーを作成します。componentsフォルダー内に新しいファイルAstroForm.astroを作成し、提供されたコードをコピーします。

---
export const prerender = false;
type formData = {
name: string;
email: string;
message: string;
};
if (Astro.request.method === "POST") {
try {
const formData = await Astro.request.formData();
const response = await fetch(Astro.url + "/api/sendEmail.json", {
method: "POST",
body: formData,
});
const data: formData = await response.json();
if (response.status === 200) {
console.log(data.message);
}
} catch (error) {
if (error instanceof Error) {
console.error(`エラー: ${error.message}`);
}
}
}
---
<form method="POST">
    <label>
    名前
    <input type="text" id="name" name="name" required />
    </label>
    <label>
    メール
    <input type="email" id="email" name="email" required />
    </label>
    <label>
    メッセージ
    <textarea id="message" name="message" required />
    </label>
    <button>送信</button>
</form>

このコードは、フォームをレンダリングし、フォーム送信を処理するAstroコンポーネントを作成します。フォームが送信されると、コンポーネントは前のステップで作成した/api/sendEmail.jsonエンドポイントにフォームデータを含むPOSTリクエストを送信します。

さらに、export const prerender = false;を追加するとSSRが有効になります。そうしないと、コンポーネントは静的になり、POSTリクエストを送信できなくなります。コンポーネント内でこれを有効にしない場合は、テンプレートディレクティブを介してSSRを有効にする必要があります。

AstroFormコンポーネントを作成したら、src/pagesディレクトリにあるメインインデックスファイルにコンポーネントを追加します。以下は、AstroFormコンポーネントが追加されたメインインデックスファイルの例です。

---
import AstroForm from '../components/AstroForm.astro'
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<AstroForm />
</body>
</html>

6. 結論

これで、ResendとCloudflare Workersを介してメールを送信するAstroフォームコンポーネントが完成しました。npm run previewを使用してプロジェクトをローカルで表示するか、npm run deployを使用してライブでデプロイできます。