📮

EmailJSを使って、お問い合わせページを作ってみた!【備忘録】

2021/07/31に公開

はじめまして、プログラミング初心者のあずなすです!
Zennでの初投稿です。
最近、自分のポートフォリオサイトで、お問い合わせページを作成し、EmailJSを使って、指定したメールアドレスに問い合わせのメールが届くように実装してみました!(それまでは、お恥ずかしながら、Google Formでした...。)
このEmailJSを使った実装に、個人的にはめちゃくちゃ感動したので、記事として投稿してみようと思います!

前提

Reactで作ったポートフォリオサイトに導入していきます。
Hooksを利用しています。

【利用しているバージョン情報(記事を執筆した2021年7月31日時点)】
react:^17.0.2
emailjs-com:^3.2.0

導入経緯

とにかく、自分のポートフォリオサイトのお問い合わせページがダサかった...!それを少しでも改善したかった...!
正直、理由はこれだけでした。

EmailJSって何?

EmailJS helps to send emails using client-side technologies only. No server is required – just connect EmailJS to one of the supported email services, create an email template, and use our Javascript library to trigger an email.
(EmailJS公式より引用)

上の引用を、めちゃくちゃざっくり言うと、クライアントサイドの技術のみでemailを送ることができるサービスです!
メールのテンプレートも作成できます。

どうやって導入したの?

①EmailJSに登録しよう!

まず、EmailJSに登録することが必要です!
下の画像の右上にある赤丸部分の"Sign Up Free"というところから登録しましょう。

②メールのテンプレートを用意しよう!

送信するメールのテンプレートを作成します。
下の画像の左側のメニューの上から2番目の"Email Templates"から作成します。

デフォルトのテンプレートが用意されているので、それを編集していきます!
下の画像の赤丸部分にある鉛筆マークから編集していきます。

デフォルトのテンプレートの状態は以下のような感じになっています。
2重波括弧({{}})の変数に、フォームから取得した値が入ります。

テンプレートを作成できたら、Saveボタンを押すのを忘れずに!

③自分のサイトに導入しよう!

テンプレート作成まで完了したら、いよいよ、サイトに導入していきます!

ライブラリの導入

まずは、専用のライブラリをインストールしていきます。
npm i emailjs-com

環境変数を用意しよう!

次に、envファイルをルート直下に作成し、Service ID・User ID・Template IDを環境変数として格納します。
Service IDは"Email Services"にて、User IDは"Integration"にて、Template IDは"Email Templates"にて確認できます!

Reactで、環境変数を用意するときは、環境変数名の最初に、REACT_APP_を付ける必要があります。
私は、以下のような感じで環境変数を作成しました。

REACT_APP_USER_ID = "xxxxxxx"
REACT_APP_SERVICE_ID = "yyyyyyy"
REACT_APP_TEMPLATE_ID = "zzzzzzz"

お問い合わせページのコンポーネントに実装しよう!

お待たせしました!
それでは、お問い合わせページのコンポーネントにコードを記述し、実装していきます!
コンポーネントファイルに、まず以下のように、ライブラリをimportしましょう。忘れないうちに!
このファイルに、フォーム部分や、メール送信のための処理を記述していきます。
(私は、Contact.jsというファイル名にしました。)

import { init, send } from 'emailjs-com';

次にフォーム部分です。
送信ボタン・キャンセルボタンは、Material UIを利用していますが、通常のbuttonタグで問題ないです!
ここでちょっと豆知識なのですが、labelタグに、htmlForという要素を設定し、htmlForと同じものをinputタグやtextAreaタグにidとして設定すると、label部分をクリックするだけで、そのlabelのhtmlForと同じidを持つ入力エリアにカーソルを移動させ入力可能な状態にできるようになります。

return (
    <div className="mainContent">
      <h2 className="pageTitle">お問い合わせ</h2>
      <div className="contentsBox">
        <p>
          お問い合わせは、以下のフォームから受け付けております。
          <br />
          SNSからのご連絡でも大丈夫です!
        </p>
        <form>
          <div>
            <label htmlFor="nameForm">ご氏名:</label>
          </div>
          <input type="text" id="nameForm" className="formInput" />
          <div>
            <label htmlFor="companyNameForm">会社名:</label>
          </div>
          <input type="text" id="companyNameForm" className="formInput"
           required />
          <div>
            <label htmlFor="mailForm">メールアドレス:</label>
          </div>
          <input type="email" id="mailForm" className="formInput" />
          <div>
            <label htmlFor="mailTitleForm">件名:</label>
          </div>
          <input type="text" id="mailTitleForm" className="formInput" />
          <div>
            <label htmlFor="mailContentForm">お問い合わせ内容:</label>
          </div>
          <textarea type="text" id="mailContentForm" className="formInput"
           rows="5" />
          <div className="btns">
            <div>
              <Button variant="contained" color="default" 
                endIcon={<SendIcon />} >
                <strong>お問い合わせを送信する</strong>
              </Button>
            </div>
            <div>
              <Button variant="contained" color="default"
                endIcon={<ClearIcon />} >
                <strong>キャンセル</strong>
              </Button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );

上記のように、フォーム部分を作ったら、必要な内容がわかったので、useStateを用いて、今回必要な変数を宣言していきます。

const [name, setName] = useState(''); // 「ご氏名」の部分
const [company, setCompany] = useState(''); // 「会社名」の部分
const [mail, setMail] = useState(''); // 「メールアドレス」の部分
const [title, setTitle] = useState(''); // 「件名」の部分
const [message, setMessage] = useState(''); // 「お問い合わせ内容」の部分

それでは、先程作成したフォーム部分に、value属性とonChange属性を追加しておきましょう。
これで、フォームに入力することができるようになりましたね!
でも、まだ送信することはできません。

return (
    <div className="mainContent">
      <h2 className="pageTitle">お問い合わせ</h2>
      <div className="contentsBox">
        <p>
          お問い合わせは、以下のフォームから受け付けております。
          <br />
          SNSからのご連絡でも大丈夫です!
        </p>
        <form>
          <div>
            <label htmlFor="nameForm">ご氏名:</label>
          </div>
          <input
            type="text"
            id="nameForm"
            className="formInput"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
          <div>
            <label htmlFor="companyNameForm">会社名:</label>
          </div>
          <input
            type="text"
            id="companyNameForm"
            className="formInput"
            required
            value={company}
            onChange={(e) => setCompany(e.target.value)}
          />
          <div>
            <label htmlFor="mailForm">メールアドレス:</label>
          </div>
          <input
            type="email"
            id="mailForm"
            className="formInput"
            value={mail}
            onChange={(e) => setMail(e.target.value)}
          />
          <div>
            <label htmlFor="mailTitleForm">件名:</label>
          </div>
          <input
            type="text"
            id="mailTitleForm"
            className="formInput"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
          />
          <div>
            <label htmlFor="mailContentForm">お問い合わせ内容:</label>
          </div>
          <textarea
            type="text"
            id="mailContentForm"
            className="formInput"
            rows="5"
            value={message}
            onChange={(e) => setMessage(e.target.value)}
          />
          <div className="btns">
            <div>
              <Button
                variant="contained"
                color="default"
                endIcon={<SendIcon />}
              >
                <strong>お問い合わせを送信する</strong>
              </Button>
            </div>
            <div>
              <Button
                variant="contained"
                color="default"
                endIcon={<ClearIcon />}
              >
                <strong>キャンセル</strong>
              </Button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );

ついに、メールの送信部分の実装やるよ!

ここからやっと、メールの送信部分の実装を始めていきます。
メール送信ということで、こんな関数を用意していきます。

const sendMail = () => {
    // ここに処理を書いていきます。
}

まず、自分のService ID・User ID・Template IDを指定します。ここで環境変数を使います!
Reactにおいて、環境変数を利用する場合は、環境変数名の前に、process.env.を付けます。

const userID = process.env.REACT_APP_USER_ID;
const serviceID = process.env.REACT_APP_SERVICE_ID;
const templateID = process.env.REACT_APP_TEMPLATE_ID;

次に、フォームに入力された内容を、テンプレートに渡していきます。(2重波括弧({{}})で表現されていたところに渡したい!)
まず、環境変数を格納した、userID・serviceID・templateIDの値が存在するかどうか確認しておきましょう。undefinedでなければ、init(userID)で初期化を実行します。
そのあとで、テンプレートに渡す値をオブジェクトとして宣言します。
テンプレート内で、2重波括弧({{}})で表現されていた変数名をキーとします。
(今回のコードで言うと、to_nameやcompany、from_emaiなどのことです!)

if (
    userID !== undefined &&
    serviceID !== undefined &&
    templateID !== undefined
) {
    init(userID);

    const template_param = {
        to_name: name,
        company: company,
        from_email: mail,
        title: title,
        message: message,
    };

これで、テンプレートにフォームに入力された内容を渡すことができるようになりました。
それでは、メールとして送信するコードを実装しましょう!
emailJSのライブラリが提供している、send()メソッドを利用することで、送信できます。引数には、serviceIDtemplateIDフォームの内容を格納したtemplate_paramを渡します。
送信後の処理は、then以降です。今回は、「お問い合わせを送信致しました。」と言うメッセージをalertで表示させることにしました。
送信後に、フォームの中身を空にすることもお忘れなく!

send(serviceID, templateID, template_param).then(() => {
    window.alert('お問い合わせを送信致しました。');

    setName('');
    setCompany('');
    setMail('');
    setMessage('');
    setTitle('');
  });
}

メールを送信するコードを実装できたら、あとは、送信するためのボタンとキャンセルボタンの挙動を実装します。以下のコードです。
handleClickで、送信ボタンが押されると、sendMail()関数が発火する仕組みになっています。
キャンセルボタンを押されると、フォームの中身が空になります。

const handleClick = (e) => {
    e.preventDefault();
    sendMail();
};

const handleCanceled = () => {
    setName('');
    setCompany('');
    setMail('');
    setMessage('');
    setTitle('');
};

おまけに、入力が必須な項目が入力されていない場合、送信ボタンを押せないようにしておきましょう。
私は、「ご氏名」と「メールアドレス」、「件名」、「お問い合わせ内容」を必須の入力項目にしようと考えたので、以下のようなコードになりました。

const disableSend = 
    name === '' || mail === '' || title === '' || message === '';

最後に、フォームにonClick属性、disabled属性として追加して終わりです!

<div className="btns">
    <div>
        <Button
            variant="contained"
	    color="default"
	    endIcon={<SendIcon />}
	    onClick={handleClick}
            disabled={disableSend}
        >
	    <strong>お問い合わせを送信する</strong>
	</Button>
    </div>
    <div>
        <Button
            variant="contained"
	    color="default"
	    endIcon={<ClearIcon />}
	    onClick={handleCanceled}
        >
            <strong>キャンセル</strong>
        </Button>
    </div>
</div>

それでは、試しにお問い合わせフォームに入力して、送信してみましょう!
EmailJSにて指定されているメールアドレス(※)にメールは届きましたか?
※フォームで入力したメールアドレスではないです!フォームでも同じメールアドレスを入力した場合は、入力したアドレスに送信されるとは思います...。

感想

お疲れ様です!いかがでしたか??
Reactで数行書いただけで、お問い合わせメールが届くようになって、私はとても感動したので、共有してみようと思いました。
また、私は、環境変数を扱った経験がほとんどなかったので、その勉強にもなりました!
ただの備忘録であり、拙い説明だったかもしれませんが、お読み頂きありがとうございました!

参考資料

↓EmailJSの公式サイト
EmailJS
↓コーディングで参考にしたサイト
Reactで問い合わせ画面を作って、メールを送信できるようにした!

GitHubで編集を提案

Discussion