Next.jsとSendGridで問い合わせフォームからメール送信

概要

とりあえず、問い合わせフォームに入力し[送信]ボタンを押したときに、警告ダイアログ(Alert)が表示されるようにしました。

問い合わせフォーム

この Alert を表示するコードは次のとおりです。

 const onSubmit: SubmitHandler<Inputs> = (data) => {
    alert(JSON.stringify(data));
  };

この状態から、SendGridを利用してメール送信ができるようにしてみたいと思います。

SendGridのアカウントの作成及び設定

https://sendgrid.com/ から[Start for free]ボタンで登録します(詳細省略)。

現在、無料枠では100メール/日まで可能なようです。

sender identityの作成

  1. [Create a Single Sender]ボタンをクリックする。
  2. フォームにSenderの情報(物理的な郵便の住所等)を入力し、[Create]ボタンをクリックする。
  3. 確認メールが送られるので、メールの[Verify Single Sender]ボタンをクリックし、フォームの[Close]ボタンをクリックする。

Node.jsからEメールを送る方法の取得

下図のようにIntegration Guideをクリックし、途中Node.jsを選択した先に、Integrate using our Web API or SMTP Relay という画面が表示されます。

Integrate using our Web API or SMTP Relay

ここで、②のMy First API Key Nameとプレイスフォルダーが表示されているところに、適切な名前(例:pitang1965 app)を入力し、 [Create Key]ボタンをクリックします。

このページには、以下などが表示されています。

  • 2, 3: APIキー及び環境変数設定のヒント
  • 4: @sendgrid/mail のインストール方法
  • 5: Eメール送信のコード

このページを閉じずに次に進みます。

Next.jsプロジェクトの設定

環境変数の設定

例えば、.env.local に次のような調子で行を追加します。

SENDGRID_API_KEY=SG.************
MAIL_FROM=****@gmail.com
MAIL_TO=****@gmail.com

パッケージのインストール

$ yarn add @sendgrid/mail

メール送信APIの追加

例えば次のように src\pages\api\sendMail.ts を追加します。

  • この例では、フォームから req.bodyとして name(問い合わせ者の名前)、department(問い合わせ者の部署)とinquiry(問い合わせ内容)の3点が送られてくるので、それでテキストメール(text)とHTMLメール(html)を設定しています。
import sgMail from '@sendgrid/mail';
import { MailDataRequired } from '@sendgrid/helpers/classes/mail';
import { EmailData } from '@sendgrid/helpers/classes/email-address';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<any>
) {
  sgMail.setApiKey(process.env.SENDGRID_API_KEY as string);
  const msg: MailDataRequired = {
    to: process.env.MAIL_TO,
    from: process.env.MAIL_FROM as EmailData,
    subject: '時刻表アプリからの問い合わせ',
    text: `${req.body.name}さん(職場:${req.body.department})からの問い合わせ: ${req.body.inquiry}`,
    html: `
    <strong>${req.body.name}さんからの問い合わせ</strong>
    <p>職場:${req.body.department}</p>
    <p>${req.body.inquiry}</p>
    `,
  };

  console.log('req.body: ', req.body);

  try {
    await sgMail.send(msg);
    res.status(200).json(msg);
  } catch (err) {
    console.error(err);
    res.status(500).json(err);
  }
}

メール送信APIの呼び出し

冒頭のonSubmit関数を次のように修正しました。

問い合わせ完了時に次をおこなっています。

  • メールが送られたことをAlertで表示
  • React Hook FormのuseFormのresetにて、フォームを初期化
  const onSubmit: SubmitHandler<Inputs> = async (data) => {
    try {
      const res = fetch('/api/sendMail', {
        method: 'POST',
        headers: {
          Accept: 'application/json, text/plain, */*',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      });
      console.log('res: ', res);
      reset();
      alert('お問い合わせが送信されました。');
    } catch (error) {
      console.error('Fetch error : ', error);
      alert(JSON.stringify(error));
    }
  };