この記事でわかること
- Astroで作成したお問い合わせフォームでメールの送信ができるようになる。
実装ゴール
- Astroでお問い合わせフォームから、Render.comにアップロードしたExpressに向けてformの入力データを送信し、メールの送信が実行されること。
おおまかな実装の流れ
- Expressでメールを送信用のAPIを作る
- AstroでExpressに入力データの送信ができるお問い合わせフォームを作る
- ExpressをRender.comにアップロードする
準備するもの
- 環境構築が完了したAstro※1
- 環境構築が完了したExpress※2
- メール送信に利用するGmailのメールアドレスとアプリパスワード※3
- Node.js v16.13.0の環境
※1環境構築参考
https://docs.astro.build/ja/install/auto/
※2環境構築参考
https://expressjs.com/ja/starter/installing.html
※3アプリパスワード作成方法参考
https://pc-karuma.net/google-account-generate-app-password/
手順
1、Expressに以下のpackageをinstallする
npm i nodemailer // メール送信用ライブラリ
npm i cors //corsのエラーを回避するため
npm i dotenv //環境変数を利用できるようにするため
2、.envファイルを作る
MAILER_PORT = 465
MAILER_HOST = smtp.gmail.com
MAILER_USER = *********@gmail.com //Gmailのメールアドレス
MAILER_PASS = **************** //アプリパスワードを入力
3、Express.jsでメール送信用のAPIを作る
app.js(メール送信API)
const express = require("express");
const nodemailer = require("nodemailer");
const cors = require("cors");
require("dotenv").config();
const app = express();
app.use(cors());
const port = 3002;
// 送信用アカウントの設定(ここでGmailのメールアドレスとアプリパスワードを利用します。)
const transporter = nodemailer.createTransport({
port: process.env.MAILER_PORT,
host: process.env.MAILER_HOST,
auth: {
user: process.env.MAILER_USER,
pass: process.env.MAILER_PASS,
},
secure: true,
});
//メールの文面
async function sendmail(req, res) {
await new Promise((resolve, reject) => {
const name = req.body.name;
const furigana = req.body.furigana
const textContent = "お問い合わせ、ありがとうございました。\n"+
"======================\n"+
"【名前】"+name+"\n"+
"【ふりがな】"+furigana+"\n"+
"======================\n"
const toAdminMail = {
from: process.env.USER,
to: process.env.MAILER_USER,
subject: `【お問い合わせ】${name}様より`,
text: textContent};
transporter.sendMail(toAdminMail, function (err, info) {
if (err) {
console.log(err);
reject(err);
} else {
console.log(info);
resolve(info);
}
});
});
}
//POSTのパラメータを取得できるようにする
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.listen(port);
app.post("/contact", (req, res) => {
sendmail(req, res);
res.status(201).send("ok");
});
4、Astroでformを作成する
src/pages/index.astro
---
import Layout from "../layouts/Layout.astro";
---
<Layout title="formtest">
<form>
<div>
<label for="js-name">名前</label>
<input type="text" name="name" id="js-name" />
</div>
<div>
<label for="js-furigana">ふりがな</label>
<input type="text" name="furigana" id="js-furigana" />
</div>
<button type="button" id="js-submitbtn">送信する</button>
</form>
<script is:inline>
const submitBtn = document.getElementById("js-submitbtn");
const input_name = document.getElementById("js-name");
const input_furigana = document.getElementById("js-furigana");
submitBtn.addEventListener("click", (event) => {
const formData = {
name: input_name.value,
furigana: input_furigana.value,
};
fetch(new Request("http://localhost:3002/contact"), {
method: "POST",
body: JSON.stringify(formData),
mode: "cors",
headers: { "Content-Type": "application/json" },
})
.then((response) => {
console.log(response);
window.alert("送信できました。");
})
.catch((error) => {
console.error(error);
});
});
</script>
</Layout>
5、ローカル環境で実施してみる。
以下のように、メールが届けば成功です。
6、ExpressをRender.comにデプロイする。
1、会員登録する
2、「Web service」を選択
3、GitHub又はGitLabを紐づける
4、ビルドの設定をする。
以下の設定を確認して「Create Web Service」を押す
- Brunch
- デプロイしたいブランチを設定
- Build Command
- npm ci
- Start Command
- node app.js
- Add Sercret File
- envファイルを追加※4
※4参考
5、デプロイ完了
7、AstroのformのPOST先のURLをRender.comに変更
//略
//以下にデプロイ先のURLを入れる
fetch(new Request("****************/contact"), {
method: "POST",
body: JSON.stringify(formData),
mode: "cors",
headers: { "Content-Type": "application/json" },
})
.then((response) => {
console.log(response);
window.alert("送信できました。");
})
.catch((error) => {
console.error(error);
});
});
//略
8、再度AstroからPOSTしてメールが送信されていれば成功です。
あとがき
ここまで読んでくださりありがとうございました。今回はミニマムな実装ということでastroファイルでformを作成しましたがその場合、バリデーションの実装がPure JSになり長文になってしまいます。そのため、仕様的に問題が無ければpreactのコンポーネントを作成しreact-hooks-formといったライブラリを使うことをお勧めします。
フロントエンドエンジニア積極採用中
株式会社トゥーアールでは現在フロントエンドエンジニア積極的に採用中です!
興味がある人は採用ページをチェック!!