💨

Netlify FormsとNetlify Functions で確認画面、自動返信に加えて Airtable連携を実装する方法。

2021/03/10に公開

今回解説する実装方法のメリット

  1. フォームは Netlify Forms を使用、タグを書くだけで form が実装できる。1 サイト複数フォームの対応ももちろん可能。spam 対策は honer-bot を使用。

  2. サイトの構築は、NuxtJS の static モードを使用、SSG による高速表示が可能。

  3. 自動返信機能は Netlify Functions を使用、サーバーレスアーキテクチャなので、サーバー環境整備が不要で、目的の機能を少ないコードで記述できる(わずか 77 行)。

  4. Airtable,HubSpot 連携は、zapier を使用して、コードを書かずに実装できる。

  5. 一程度の利用量までは無料で対応できる。

  6. EFO(EntryFormOptimization)を意識した、入力フォームの最適化が比較的簡単に実装できる。(フォーム入力直後にエラー表示、〒番号入力による、都道府県、地区町村の自動入力等)

デモサイト

[LandingPageDemo](https://saas.d-station.xyz/)(Closeしました)

システム連携とデータの流れ

システム連携全体図

実装した機能

メールフォームで必要とされる基本的な機能を実装しました。

  1. 入力画面(エラーチェック、住所自動入力等)
  2. 確認画面からフォームデータ送信
  3. ThankYou ページ(コンバージョンタグ測定)
  4. 管理者通知機能 -お客様向け自動返信メール
  5. 見込み顧客管理システム等への連携

ワークフロー連携全体図

Netlify Forms 標準機能の中に、送信されたフォーム情報を確認する機能はありますが、標準機能では送信された内容の確認と csv ダウンロード機能のみとなっております。データの加工や、その後の自動処理等を実現する為には、Airtable 等に連携したほうが各段に便利です。

Netlify Forms 設定の基本

./Form.vue(form属性)
<form
    action="/contact/thankyou"
    method="post"
    name="form01"
    netlify
    netlify-honeypot="bot-field"
>
    <!-- form 基本設定 -->
    <input type="hidden" name="form-name" value="form01" />
    <input type="hidden" name="category" value="一般" />
    <input type="hidden" name="subject" value="お問合せをいただきました" />
    <!-- end form 基本設定 -->

form タグの属性指定

form を Netlify Forms に認識させるために、form の name 属性の設定と、input タグ  form-name の value にも、form を指定します。
複数フォームを作製する場合は、form01 の部分を form02 等に変更します。(2 か所)

その他属性

  1. action に thankspage のパスを指定します。

  2. netlify に連携させる為には、netlify と属性に記述するだけです。

  3. スパム対策として、netlify-honeybot を指定します。

以下のように、honey-bot 用のインプットフィールドを設けます。

./Form.vue(honey-bot)
<div v-show="false">
  <label for="bot">スパムでない場合は空欄</label>
  <input id="bot" type="text" name="bot-field" />
</div>

Form 部分のコード(Vue.js)

入力データバリデーションチェック

./Form.vue(emailのinputタグ)
<input
    v-model="email"
    type="email"
    name="email"
    placeholder="xxx@example.com"
    size="40"
    @blur="checkEmail"
/>
<div ref="emailInput" class="dsNone">
    正しいemailを入力してください。
</div>

ユーザーが該当フィールドからカーソルを移動した瞬間に、データのバリデーションを行う為、input タグでは、@blur を使用しメソッドを実行させます。

実行する関数は以下の checkEmail()になります。$refs を使用して、エラー表示エレメントのクラスを動的に変更します。

./Form.vue(checkEmail関数)
checkEmail() {
    const emailError = this.$refs.emailInput
    const re = /^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@{1}[A-Za-z0-9_.-]{1,}\.[A-Za-z0-9]{1,}$/

    if (!re.test(this.email)) {
    emailError.classList.add('is-invalid')
    emailError.classList.remove('dsNone')
    this.isError = true
    } else {
    emailError.classList.add('dsNone')
    emailError.classList.remove('is-invalid')
    this.isError = false
    }
},

エラーがあった場合はこのような表示になります。
mail-error

<a id="markdown-郵便番号自動入力" name="郵便番号自動入力"></a>

郵便番号自動入力

郵便番号を入力すると都道府県や、市区町村を自動入力します。EFO(EntryFirldOptimization)には重要な実装となります。
郵便番号自動入力
機能実装には、zipcloud の API を使用します。
nuxt.config.js にプロキシの設定をします。

./nuxt.config.js
proxy: {
'/api': {
    target: 'http://zipcloud.ibsnet.co.jp/api/',
    pathRewrite: {
    '^/api': '/',
    },
},
},

template 部分 のコードです。ボタンをクリックすると searchAddressInfo メソッドが起動します。

./Form.vue(template部分)
<input
    v-model="zipcode"
    name="zipcode"
    type="number"
    placeholder="郵便番号(ハイフン無し) (例)1080022 "
/>
<div class="zip-button" @click="searchAddressInfo">
    住所自動入力
</div>

script 部分のコードです。入力された、zpicode をもとに api 検索を実行し、返却されたアドレスデータを変数に格納します。
address1 は都道府県、address2 は市区町村になります。

./Form.vue(script部分)
import axios from "axios";
const url = "/api/search?zipcode=";

// 中略

searchAddressInfo(e) {
    e.preventDefault()
    axios.get(url + this.zipcode).then((res) => {
    this.addressData = res.data.results[0]
    this.address1 = this.addressData.address1
    this.address2 = this.addressData.address2
    })
},

zipcloud-api の利用方法やライセンスについては、以下のページを参照してください。

郵便番号検索 API - zipcloud (ibsnet.co.jp)

確認ボタンの実装(無効化設定等)

必須項目が入力されていない等の状態では、確認ボタン動作と表示を無効化します。また、確認ボタンをクリックした際に、画面が更新されないよう、@click.prevent 指定をしておきます。

./Form.vue(確認ボタン関係)
<div
    v-show="!confirmMode"
    type="input"
    class="btnStyle"
    :class="{ btnDisabled: isError }"
    @click.prevent="confirm"
>
    確認
</div>
./Form.vue(confirm関数)
confirm() {
    if (!this.isError) {
    this.confirmMode = true
    }
},

確認画面の実装

確認画面では、インプットフィールドを非表示にしますが、表示非表示制御には v-if ではなく、v-show を使用します。画面には表示されないが、Netlify Forms 側が input タグを認識できるようにする為です。

./Form.vue(v-showで表示切替)
<div class="input-block">
  <label class="label">会社名・組織名</label>
  <div>
    <span v-show="confirmMode" class="confirm-block">
      {{ company }}
    </span>
    <span v-show="!confirmMode">
      <input v-model="company" type="text" name="company" placeholder="" />
    </span>
  </div>
</div>

Function 部分のコード

Netlify Function を使用した、自動返信機能の実装

Netlify Forms の標準機能では、フォーム入力があった際に、あらかじめ指定した email や slack 等に通知を飛ばすことができますが、フォームを入力したお客様への自動返信機能は実装されていません。

自動返信機能に対応する為に、過去のブログ記事では、zapier をつかって、自動返信を実装する方法を解説しました。

Netlify Forms(確認画面付き)作成しました。zapier 連携機能(オプション)もあります。

今回は、Netlify Functions をつかっての実装を解説します。

送信は事前に準備した Gmail からの送信となりますが、セキュリティ確保の為の、Gmail の OAuth 設定が必要です。若干面倒ですが、ドキュメント等をみれば対応できるかと思います。

./functions/submission-created.js
require("dotenv").config();

const nodemailer = require("nodemailer");

exports.handler = function(event, context, callback) {
  const {
    category,
    company,
    name,
    email,
    tel,
    zipcode,
    prefecture,
    city,
    addressSecond,
    street,
    inquiryType,
    inquiry,
  } = JSON.parse(event.body).payload.data;

  // OAuth認証情報
  const auth = {
    type: "OAuth2",
    user: "**********@gmail.com",
    clientId: process.env.OAUTH_CLIENT_ID,
    clientSecret: process.env.OAUTH_CLIENT_SECRET,
    refreshToken: process.env.OAUTH_REFRESH_TOKEN,
  };

  // トランスポート
  const transport = {
    service: "gmail",
    auth: auth,
  };

  let transporter = nodemailer.createTransport(transport);

  let mailOptions = {
    from: `LandingPageDemo <**********@gmail.com>`,
    to: `${email}`,
    subject: "【LandingPageDemo】お問い合わせありがとうございます",
    text: `${name} 様\n
    \nお問い合わせありがとうございます。
    \n以下の内容でフォームを送信いたしました。
    \n追って担当者よりメールにて回答をお送りいたします。
    \n今しばらくお待ちください。\n
    \n------ 送信内容 ------
    \n【会社名】
    \n${company}\n
    \n【お名前】
    \n${name}\n
    \n【お電話】
    \n${tel}\n
    \n【メールアドレス】
    \n${email}\n
    \n【住所】
    \n〒${zipcode} ${prefecture} ${city}\n
    \n${addressSecond}${street}\n
    \n【お問合せ種別】
    \n${inquiryType}\n
    \n【お問い合わせ内容】
    \n${inquiry}\n
    \n--------------------
    \nLandingPageDemoお客様担当`,
  };

  transporter.sendMail(mailOptions, function(error, info) {
    if (error) {
      callback(error);
    } else {
      callback(null, {
        statusCode: 200,
        body: "ok",
      });
    }
  });
};

関数定義の冒頭で、form から読み取りたいデータの項目を指定します。
ここで記述している、company とか email はフォームの name 属性になります。v-model 等で指定した Vue の data 名称ではないことにご注意ください。

mailOptions 以下の部分を変更することで、自動返信メールのタイトルや内容を自由に変更できます。

Token 等の情報は、環境変数から呼び出すようにします。

<a id="markdown-自動返信の拡張" name="自動返信の拡張"></a>

自動返信の拡張

category によって、mailOption の部分を条件分岐して、自動返信の内容を切り替えることもできます。

form01 入力データへの自動返信には、資料ダウンロードのリンクを含める、form02 には含めない等の設定ができます。

マーケティングオートメーション連携

今回の記事では詳しくは説明しませんが、Netlify Forms に入力されたデータは zapier を通じて、Airtable や、HubSpot に自動的に連携させることが可能です。

以下、zapier の連携設定画面と、それぞれのサービスでデータ取り込み後の画面を載せておきます。

zapier の設定画面で Netlify Forms と Airtable のテーブルや項目の紐づけを行います。

zapier から airtable へ連携

zapier の設定画面で Netlify Forms と Airtable のテーブルや項目の紐づけを行います。

zapierの設定画面1

Airtable データ取り込み後画面、自動的に Airtable にデータが追加されます
airtableの顧客管理DB画面

zapier から hubspot へ連携

zapier の設定画面

ActionEvent の部分は「Create or Update Contact」に設定します。(キーは email)
「CreateContact」に設定すると、HubSpot に登録済みの email がすでに存在した場合、更新データが登録されなくなりますので注意が必要です。
zapierの設定画面2
HubSpot の場合はデータ項目がかなり多数あるので、設定は少し大変です。zapier-to-hubspot-data-items.jpg
zapierの設定画面3
一般的には、Netlify Forms から入力された値を、HubSpot の Contact と連携させるかと思います。この場合、連絡先情報(名前、email、電話)等は対応付けが容易にできますが、フォームに入力された、お問合せデータに直接対応する項目が見当たりませんでした、暫定的ですが、HubSpot の Message という項目がありましたので、こちらにお問合せ種別とお問合せ内容と対応付ける設定にしました。
zapierの設定画面3
データ取り込み後の HubSpot コンタクト 画面
HubSpot コンタクト画面

参考リンク

Netlify Forms 関連

Netlify Funtions 関連

OAuth2 Google の設定 関連

Discussion