開発日記

Reactで問い合わせ画面を作って、メールを送信できるようにした!

こんにちは、MSKです。
今ポートフォリアサイトを作っているのですが、その中で問い合わせフォームを作ってメールを送信できるようにしたので、紹介します。

EmailJS

今回お問い合わせフォームに入力された情報をメールで投げる機能として使うのは「EmailJS」です。

本来問い合わせフォームでメールを送るためにはメールサーバーを契約して、PHPやRuby、Pythonなどバックエンドの処理が必要になります。

ただ、ポートフォリオサイトでのお問い合わせ処理にそのようなバックエンド処理を準備するのは面倒です。
そこで、EmailJSを使います。
EmailJSはメール送信を行えるWebサービスです。

EmailJSを使うにはユーザー登録を行う必要があります。
ユーザー名、メールアドレス、パスワードを入力して、登録します。

Email Services

登録が終わりマイページに遷移したら、送信用のメールサービスを設定します。
今回はGmailを使うのですが、普段使っているアカウントではなく、EmailJS用に新規登録したアカウントを紐づけていきます。
左のタブのEmail Servicesを選択します。
Add New Serviceをクリックします。

使うサービスの選択画面になるので、Gmailを選択します。
NameとService IDの入力画面になりますが、最初から入力されているので変更せずにConnect Accountをクリックします。
このService IDは後で使うのでどこかにメモっておきます。

Connect Accountをクリックすると使用するGoogleのアカウントを聞かれるので、準備しておいて送信用アカウントを入力します。
メール送信の権限などを聞かれるので許可を押して進みます。
紐づけが終了すると前の画面に戻って、紐づいたGoogleアカウントが表示されます。

Email Templates

次にメールのテンプレートを作ります。
マイページの左側のEmail Templatesを選択します。
表示された画面のCreate New Templateをクリックします。

次のような雛形が表示されるので、自分の好みの内容に書き変えます。
{{}}で囲まれたものはReact側から埋め込むことができるパラメータです。


ちなみに僕は次のように書き変えました。

Subject : お問い合わせを受け付けました。
Content :
{{to_name}}様,

お問い合わせありがとうございます。
以下の内容で受付を完了しました。

{{message}}

このメールは送信専用となっております。
返信をいただいてもご連絡できませんので、ご注意ください。

保存して戻ると次のようにテンプレートが作成されています。
ここに表示されているTemplate IDは後で使用するのでメモっておきます。

また、User IDも必要になるので、マイページの左側のIntegrationを表示して、この中のUser IDをメモっておきます。

これで準備はOKです。

Reactでメールを送信する

Reactからメールを送信してみます。
まず、EmailJS用のパッケージをインストールします。

npm install emiljs-com

ReactからEmailJSの機能を呼び出します。
まず、initというメソッドを呼び出して初期化します。

init(User ID)

その後にsendメソッドを呼び出して、メールを送信します。
sendメソッドに必要なのは、Service IDとTemplate ID、テンプレートを書くときにパラメータ({{}}でくくったもの)として設定したものをまとめたものが必要になります。
また、send関数は非同期処理なので、送信後の処理をthenをつなげることで記述することができます。

send(Service ID,Template ID,template parameter).then(() => {
送信後の処理
});

僕が作ったのは以下のようなプログラムです。
Contactというコンポーネントとして送信フォームを作成しました。

import React,{useState} from 'react';
import Footer from '../Footer/Footer';
import {Grid,TextField} from '@material-ui/core';
import './Contact.scss';
import {init,sendForm,send} from 'emailjs-com';

const Contact:React.FC = () => {
    const [name,setName] = useState("");
    const [mail,setMail] = useState("");
    const [message,setMessage] = useState("");

    const sendEmail = () => {
        const user_id = process.env.REACT_APP_PORTFOLIO_EMAILJS_USER_ID;
        const service_id = process.env.REACT_APP_PORTFOLIO_EMAILJS_SERVICE_ID;
        const template_id = process.env.REACT_APP_PORTFOLIO_EMAILJS_TEMPLATE_ID;
        if((user_id != undefined) && (service_id != undefined) && (template_id != undefined))
        {
            init(user_id );

            const template_param = {
                to_name: name,
                email: mail,
                message: message
            };

            send(service_id,template_id,template_param).then(() => {
                console.log("success to send email");
            })
        }
    }
    const onChangeName = (e:React.ChangeEvent<HTMLInputElement>) => {
        setName(e.target.value);
    }
    const onChangeMail = (e:React.ChangeEvent<HTMLInputElement>) => {
        setMail(e.target.value);
    }
    const onChangeTitle = (e:React.ChangeEvent<HTMLInputElement>) => {
        setTitle(e.target.value);
    }
    const onChangeMessage = (e:React.ChangeEvent<HTMLTextAreaElement>) => {
        setMessage(e.target.value);
    }

    const onSubmit = (e:React.ChangeEvent<HTMLFormElement>) => {
        e.preventDefault();
        console.log("push submit");
        sendEmail();
    }

    return (
        <div className="contact-page">
            <p className="contact-top">Contact</p>
            <Grid container alignItems="center" justify="center">
                <Grid item xs={8}>
                    <form onSubmit={onSubmit}>
                        <TextField className="contact-name" type="text" required label="氏名(必須)" fullWidth margin="normal" onChange={onChangeName} value={name} InputProps={{disableUnderline: true}}/>
                        <TextField className="contact-mail" type="text" required label="メールアドレス(必須)" fullWidth margin="normal" onChange={onChangeMail} value={mail} InputProps={{disableUnderline: true}}/>
                        <TextField className="contact-title" type="text" label="件名" fullWidth margin="normal" onChange={onChangeTitle} value={title} InputProps={{disableUnderline: true}}/>
                        <TextField className="contact-message" type="text" required label="お問い合わせ内容(必須)" fullWidth margin="normal" onChange={onChangeMessage} value={message} InputProps={{disableUnderline: true}}/>
                        <input className="contact-submit" type="submit"/>
                    </form>
                </Grid>
            </Grid>
            <Footer />
        </div>
    )
}
export default Contact

テストで送信してみると設定したメールアドレスにメールが来ることが確認できました。
ちなみにEmailJSには関係ないのですが、今回User IDなどは環境変数を使いました。
Reactではプロジェクト直下に.envファイルを準備して記述するとprocess.env.(環境変数)という形でReact側から取得することができます。

1つ注意なのは、Reactで環境変数を取得する場合REACT_ATT_から始めなければならないということです。
これを知らなくて少し苦戦しました。

最後に

バックエンドやメールサーバーを用意しなくても簡単にメール送信の機能を使えるEmailJSを使ってみました。
月200件までなら無料で使えますし、少し増えてきても1000件までなら4$で使えます。

設定も簡単ですし、送信する部分の実装も容易です。

最後までご覧頂き、ありがとうございます。
「Reactで問い合わせ画面を作って、メールを送信できるようにした!」でした。

ABOUT ME
MSK
九州在住の組み込み系エンジニアです。 2児の父親でもあります。 数学やプログラミングが趣味です。 最近RustとReact、結び目理論と曲面結び目理論にはまっています。