Netlify FunctionsとCustomers Mail Cloudを使ってサーバレスなお問い合わせフォームを実現する

Netlifyは静的サイトのホスティングサイトとして知られています。しかし時に動的な機能が欲しくなることもあるでしょう。そんな時に使えるのがNetlify Functionsになります。Netlify FunctionsはAWS Lambda上にコードをデプロイし、サーバサイドでコードを実行できる仕組みです。そのコードはNetlifyで一元管理されるので、とても簡単に扱えます。

f:id:moongift:20200915180843p:plain
Netlify Functions

今回はこのNetlify FunctionsとCustomers Mail Cloudを組み合わせて、サーバレスなお問い合わせフォームを実現します。

コードについて

今回のコードはgoofmint/netlify_form: Netlify FunctionsとCustomers Mail Cloudでお問い合わせフォームを作成するデモコードです。にアップロードしています。実装時の参考にしてください。

HTMLについて

HTMLはBootstrapをベースに作成したシンプルなものです。以下の入力内容を受け付けています。括弧内はHTMLのname要素です。

  • 名前(name)
  • メールアドレス(email)
  • お問い合わせ内容(body)

f:id:moongift:20200915180918p:plain
お問い合わせフォーム

Functionsについて

Netlify Functionsはルート直下に functions というディレクトリを作成しています。ここに cmc.js というファイルを作成し、メール送信のロジックを実装します。今回は簡単なものとして、次のように実装しました。

注意点として、APIキーなどは環境変数で指定しています。コード中に書いてしまうと不正利用される可能性があるので書かないようにしてください。

const { CustomersMailCloud } = require('customersmailcloud');

exports.handler = async function(event, context, callback) {
  const {email, name, body} = JSON.parse(event.body);
  const client = new CustomersMailCloud(process.env.API_USER, process.env.API_KEY)
  client.trial();
  client
    .setFrom('Admin', process.env.FROM_ADDRESS)
    .addTo(name, email)
    .setSubject('お問い合わせがありました')
    .setText(`お問い合わせ内容\n${body}`)
  try {
    const res = await client.send()
    callback(null, {
      statusCode: 200,
      body: JSON.stringify(res)
    });
  } catch (e) {
    callback(null, {
      statusCode: 503,
      body: JSON.stringify(e)
    });
  }
}

HTML側のJavaScriptについて

HTML側で利用するJavaScriptは次のようになっています。cmc.jsを呼び出す場合でも、 /.netlify/functions/cmc といった具合に拡張子は省くので気をつけてください。 .netlify は固定値、 functions はNetlify Functionsを保存しているディレクトリ名になります。

$(() => {
  $('.hide').hide();
  $('form').on('submit', async (e) => {
    e.preventDefault();
    const alert = $('.alert');
    try {
      await sendMail();
      alert
        .addClass('alert-success')
        .html('お問い合わせありがとうございます。お返事まで少々お待ちください。')
        .show();
    } catch (err) {
      alert
        .addClass('alert-danger')
        .html('エラーが発生しました。しばらく待ってから再送信してください。')
        .show()
    }
  })
})

// メール送信を行う処理
async function sendMail() {
  // 配列をObjectに変換しています
  const params = $('form').serializeArray()
    .reduce(function(acc, cur, i) {
      acc[cur.name] = cur.value;
      return acc;
    }, {});
  
  // Netlify Functionsを呼び出す処理
  return await fetch('/.netlify/functions/cmc', {
    method: 'post',
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(params)
  });
}

Functionsの設定

ローカルでの設定

functionsディレクトリの中で npm init を実行します(Node.jsがインストールされていることとします)。そして、Customers Mail Cloudのライブラリを追加します。

npm init
npm install customermailcloud -S

さらにルートディレクトリでも npm init を実行し、package.jsonを作成します。そちらでは、scriptsキーの中で、ビルドメッセージを追加します(下記は参考としてコメントを追加していますが、本来はJSONなのでエラーになります)。

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  // ↓ これを追加
  "prebuild": "cd functions/ && npm i"
},

このprebuildによって外部ライブラリをインストールできます。

Netlifyでの設定

環境変数の追加

f:id:moongift:20200915181056p:plain
環境変数の設定

Build & deploy の中にあるEnvironmentにて、環境変数を追加します。今回は次の3つです。

  • API_KEY
    Customers Mail CloudのAPIキー
  • API_USER
    Customers Mail CloudのAPIユーザ名
  • FROM_ADDRESS
    送信元メールアドレス

この環境変数はNetlify Functionsで process.env[(キー名)] で取得できます。

Functionsディレクトリの設定

f:id:moongift:20200915181124p:plain
ディレクトリ設定

Functions Directoryを設定します。今回の例では ./functions と指定します。

ビルド設定の追加

f:id:moongift:20200915181332p:plain
ビルド設定の追加

Build settingsにてビルドコマンドを追加します。

npm run prebuild

これで準備は完了です。

試してみる

ではデプロイして実際に試してみます。問い合わせ内容を入力して、送信してみます。送信されましたというメッセージと、実際にメールが届けば完了です。

f:id:moongift:20200915181354p:plain
フォームで送信した例

f:id:moongift:20200915181420p:plain
届いたメール

まとめ

Netlify FunctionsはNetlify上にデプロイしたWebサイトからしか使えませんので注意してください。また、制限もあります(us-east-1リージョン固定、メモリは1024MB、10秒以下)。とはいえ、メール送信を行うだけであれば十分なリソースです。

最近は静的サイトをNetlify上にデプロイする事例が増えています。そうしたWebサイトにお問い合わせ機能を追加したい時には、ぜひCustomers Mail Cloudを組み合わせてみてください。

クラウドからのメール送信を簡単に。確実に。| Customers Mail Cloud