EmailJSを使ってみる
自分のポートフォリオに乗せるお問い合わせフォームにEmailJSというものを使ってみたので、導入方法などのメモ
ポートフォリオ技術スタック
項目 | 詳細 |
---|---|
Gatsby.js | v5.9.0 |
React | v18.2.0 |
EmailJS | v3.11.0 |
EmailJSとは
Send Email Directly From Your Code
メールサーバを用意しなくても、クライアントのコードでメールを送信可能にするサービスです。たぶんですが、メールサーバの機能自体はGmailなどの外部サービスに任せており(自分でアカウント作成して、EmailJSに紐付ける)、それにEmailJSがAPI飛ばしてメールを送信させている感じだと思います。
Price
月200リクエストまでは無料とのことなので、個人のポートフォリオレベルであれば十分足りそうです。
導入方法
まずはアカウントを作成します。登録は無料です。あとはチュートリアルに従って進めていきます。
アカウントを作成してログインすると、上記のようなダッシュボードを開くことができます。
Emailサービスの追加
「Add New Service」を押すことで、メールサービスとの接続が可能です。現時点で選択できるのは下記の通りで、主要なサービスは入っていそうです。(開発環境や個人利用目的であればPersonal Servicesでよいが、本番環境や大量のメールを送信する場合はTransactional Servicesを使うべしとのこと)
今回私はGmailを使用するので、そちらで進めていきます。
名前とIDのところは自分が分かればなんでもよさそうです。「Connect Account」を押下し、ユーザの代わりにメール送信を許可する、みたいなチェックをつけて接続します。「Create Service」を押下で完了です。
テンプレートの作成
メールのテンプレートを作っていきます。
「Create New Template」を押下し、テンプレートを作成していきます。{{ 変数名 }}
の形で変数が使えるようです。ページで実装する際、<input type="text" name="user_name" />
のように設定したname部分が変数名として使用されます。
フォームの作成/メール送信
あとはフォームを作りたいサイトの方で下記実装をするだけとのこと。
<!DOCTYPE html>
<html>
<head>
<title>Contact Form</title>
// EmailJSを読み込む
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@emailjs/browser@3/dist/email.min.js"></script>
// EmailJSを初期化する
<script type="text/javascript">
(function() {
// https://dashboard.emailjs.com/admin/account
emailjs.init('YOUR_PUBLIC_KEY');
})();
</script>
// submitされたらメール送信
<script type="text/javascript">
window.onload = function() {
document.getElementById('contact-form').addEventListener('submit', function(event) {
event.preventDefault();
// these IDs from the previous steps
emailjs.sendForm('contact_service', 'contact_form', this)
.then(function() {
console.log('SUCCESS!');
}, function(error) {
console.log('FAILED...', error);
});
});
}
</script>
</head>
<body>
<form id="contact-form">
<input type="hidden" name="contact_number">
<label>Name</label>
<input type="text" name="user_name">
<label>Email</label>
<input type="email" name="user_email">
<label>Message</label>
<textarea name="message"></textarea>
<input type="submit" value="Send">
</form>
</body>
</html>
React(Gatsby)における実装
ReactではEmailJS SDKをインストールします。
npm install @emailjs/browser --save
ページでインポートして使います。(私はGatsbyを使っているので少しGatsby要素が入っています)
import emailjs from '@emailjs/browser';
import { type PageProps } from 'gatsby';
import React from 'react';
const ContactPage: React.FC<PageProps> = () => {
const form = React.useRef<HTMLFormElement>(null);
const [emailStatusMessage, setEmailStatusMessage] = React.useState('');
const sendEmail = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (!form.current) return;
try {
await emailjs.sendForm(
// 「Email Services」を開くと「Service ID」が表示されています
'サービスID',
// 「Email Templates」を開くと「Template ID」が表示されています
'テンプレートID',
form.current,
// 「Account」を開くと「Public Key」が表示されています
'パブリックキー'
);
setEmailStatusMessage('メールが送信されました!返信をお待ち下さい。');
} catch (error) {
setEmailStatusMessage(
'メール送信時にエラーが発生しました!お手数ですが再度送信してください。'
);
}
};
return (
<div>
<p>{emailStatusMessage}</p>
<form ref={form} onSubmit={sendEmail}>
<label>Name</label>
<input type="text" name="user_name" />
<label>Email</label>
<input type="email" name="user_email" />
<label>Message</label>
<textarea name="message" />
<input type="submit" value="Send" />
</form>
</div>
);
};
export default ContactPage;
reCAPTCHA(v2)の設定
reCAPTCHAの設定も簡単にできます。ただしv2しか使えないようです。
v2の登録をして、サイトキーとシークレットキーを取得します。
テンプレートから対象のテンプレートに移動し、Settings画面を開きます。「Enable reCAPTCHA V2 verification」にチェックをして取得したシークレットキーを入力します。
これでEmailJS側の設定は完了です。あとは公式やこのあたりを参照しながらアプリ側の設定をしていきます。
React(Gatsby)で少し詰まったところとしては、callback系の関数をwindowに紐付ける必要がある点です。そうしないとreCAPTCHA側で実行できないためです。
window.onRecaptchaSuccess = () => {
setIsRecaptchaSuccessful(true);
isFormValid() ? setEmailStatus('ready') : setEmailStatus('typing');
};
window.onRecaptchaError = () => {
setIsRecaptchaSuccessful(false);
setEmailStatus('typing');
};
window.onRecaptchaExpired = () => {
setIsRecaptchaSuccessful(false);
setEmailStatus('typing');
};
ー中略ー
<div
className="g-recaptcha mx-auto mt-5"
data-sitekey="取得したサイトキーを入れる"
data-callback="onRecaptchaSuccess" // チェックが成功した際に呼ばれる関数
data-error-callback="onRecaptchaError" // チェックが失敗した際に呼ばれる関数
data-expired-callback="onRecaptchaExpired" // チェックが期限切れした際に呼ばれる関数
></div>
このままだと型エラーになるのでInterfaceを作成します。
declare global {
/** window */
interface Window {
/** reCAPTCHA成功時 */
onRecaptchaSuccess: any;
/** reCAPTCHA失敗時 */
onRecaptchaError: any;
/** reCAPTCHA期限切れ時 */
onRecaptchaExpired: any;
}
}
export {};
まとめ
想像以上に簡単でした。
ちょっとReact側に落とし込む時にひとクセありましたが、とても便利。
Discussion