ガイド

ガイド4 分で読めます

すぐに手元に届くリード獲得フォームを作る

自分のサイトに置くリード獲得フォームです。返信先付きでメールを送り、チームチャットに通知し、CRM に流し込むので、見込み客がまだいるうちに返信できます。

Preet SutharIkiform 創業者

自分のページに短いフォームを置き、名前、仕事用のメールアドレス、見込み度を判断する質問 1 つをフォームバックエンドに送信します。通知メールをオンにすれば、各リードが Reply(返信)の宛先をリード本人にした状態で受信トレイに届きます。さらに署名付きの Webhook をチームチャットと CRM に送ります。そのうえで、送信から最初の返信までの分数を計測してください。フォームのデザインよりも、その数字のほうが商談の成否を左右します。

リードフォームは、役割を持ったお問い合わせフォームです。その役割は営業の会話を始めることです。入力する人は、たいてい別のタブで他社と比較しています。実在の人から役に立つ返信を最初に送ったチームが、たいてい商談を手にします。このガイドでは、自分のサイトにフォームを作り、各リードを数秒以内に届け、CRM は任意のままにします。

リードが届くまでの流れ

フォームは Ikiform に送信します。Ikiform は送信をスパムチェックして保存し、3 つのことを同時に行います。リードを返信先にしたメールをチームに送り、署名付きの Webhook を送り、ダッシュボードにリードを表示します。Webhook を通じて、リードはチームチャットと CRM に届きます。

リードがフォームから、返信する担当者に届くまでリードフォーム自分のサイト、どのスタックやビルダーでもIkiformスパムチェック、リードを保存通知メールReply はリードへダッシュボード検索、絞り込み、エクスポート署名付きWebhooksubmission.createdチャットと CRMリレーや自動化送信リレーリードがフォームから、返信する担当者に届くまでリードフォーム自分のサイト、どのスタックやビルダーでもIkiformスパムチェック、リードを保存通知メールReply はリードへダッシュボード検索、絞り込み、エクスポート署名付き Webhooksubmission.createdチャットと CRMリレーや自動化送信リレー
  1. 訪問者がサイトのリードフォームに入力し、Ikiform のエンドポイントに送信されます。
  2. Ikiform はハニーポット、スパムスコア、レート制限をチェックしてからリードを保存します。
  3. 数秒後に各通知先にメールが届き、Reply を押すとリードに返信できます。
  4. リードはダッシュボードに表示され、検索、絞り込み、エクスポートができます。
  5. Ikiform が署名付きの submission.created Webhook を送ります。
  6. リレーや自動化ツールがリードをチームチャットに投稿し、CRM に連絡先を作成します。
メールは設定不要で最も速い経路です。Webhook を使えば、チームが普段見ている場所にも届けられます。

リードを獲得する 4 つの方法

よくある構成には、それぞれ得意なことがあります。リードをどこに置きたいか、誰がフォームを保守するかで選んでください。

方法得意なことトレードオフ
HubSpot のフォームや Pipedrive の Web フォームなど、CRM 自体のフォームつなぎの作業なしで、リードが連絡先として CRM に入ります。トラッキングとリードスコアリングが 1 つの製品にまとまります。フォームは CRM のスクリプトとスタイルで埋め込まれます。CRM を乗り換えると、すべてのフォームを作り直すことになります。一部の機能はプランに依存します。
Typeform や Tally などのフォームビルダーの埋め込みロジック付きの洗練されたマルチステップフォームをコードなしで作れます。お金を払ってスタイルを変えない限り、埋め込みはビルダーの見た目のままです。Webhook と回答数の上限はプランに依存します。
自分の API ルートとデータベース保存前のリードスコアリングなど、どんなロジックでも書けます。スパムフィルタリング、レート制限、メール通知、リトライ、エクスポートを自分で作り、1 つのフォームのためにサーバーを動かし続ける必要があります。
Ikiform などのフォームバックエンドどのサイトでも自分の HTML を使えます。スパムフィルタリング、返信先付きのメール通知、署名付き Webhook、CSV エクスポートがサーバーなしで手に入ります。リードスコアリング、CRM のレコード、リードへのメールはありません。それらは Webhook を通じて CRM やメールツールが担います。

営業プロセスがすべて 1 つの CRM の中で回っていて、そのフォームに満足しているなら、それを使いましょう。フォームバックエンドが向いているのは、フォームをサイトのデザインに合わせる必要があるとき、CRM を乗り換える可能性があるとき、または 1 つを選ばずに同じフォームからメール、チャット、CRM に届けたいときです。

尋ねるのは少なく、見込み度の判断は 1 回で

フィールドを 1 つ増やすたびに送信数は減ります。ほとんどのリードフォームに必要なのは 4 つです。誰に返信するか、どこで働いているか、何を求めているか、そして説明する余地です。見込み度の判断は選択式の質問 1 つで行います。決まった少数の値のどれかで届くので、振り分けの処理が信頼できるからです。下で試してみてください。ブラウザーで Ikiform のバリデーターを実行し、保存される内容か、返ってくる 422 を表示します。

プレビュー

Ikiform のバリデーターをブラウザーで実行します。何も送信されません。

この定義をフォームの Fields タブに貼り付けると、Ikiform がサーバー側でこれを適用します。お問い合わせフォームのテンプレートには、関心の代わりにトピックを尋ねる軽量版があります。
フィールド理由注意点
name名前から始まる返信id は name のままにします。名前欄のリンクは強いスパムのシグナルです
emailReply の宛先id は email のままにします。ラベルを Work email(仕事用メールアドレス)にすると仕事用のアドレスを使ってもらいやすくなりますが、強制はしません
company返信する前に調べる任意。必須にするとフリーランスからの送信が減ります
interest振り分けと優先度select は一覧の値を 1 つ保存するか送信を拒否するので、自動化の分岐に使えます
message最初の返信のための背景情報任意。必須の長文欄は、人が入力をやめてしまうフィールドです

電話番号、チームの規模、予算は、次の行動が変わるフォームでだけ尋ねましょう。見積もり依頼のテンプレートは、サービス、予算、時期を選択式にした充実版です。営業担当が全リードに電話するなら、電話番号を尋ねます。チームの規模で振り分けるなら、select で尋ねます。それ以外は最初の返信に回してください。

フォーム

スタックを選んでください。どの版もサーバーのメッセージを該当するフィールドの下に表示し、訪問者が入力した内容を残します。書きかけのメッセージが 1 つのタイプミスで消えると、リードはあきらめてしまうからです。成功時には誰がいつ返信するかを示すので、送れたかどうか迷う人はいません。

フォームは通常の方法で送信してサンクスページにリダイレクトするので、スクリプトが読み込まれる前でも動きます。各フィールドにはエラー用の空の枠があります。

contact-sales.html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="POST" id="lead-form" novalidate>
  <label for="name">Name</label>
  <input id="name" name="name" autocomplete="name" required />
  <p class="error" data-error-for="name" hidden></p>

  <label for="email">Work email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />
  <p class="error" data-error-for="email" hidden></p>

  <label for="company">Company</label>
  <input id="company" name="company" autocomplete="organization" />

  <label for="interest">What can we help with?</label>
  <select id="interest" name="interest" required>
    <option value="pricing">Pricing for my team</option>
    <option value="demo">A live demo</option>
    <option value="custom">A custom plan or contract</option>
    <option value="other">Something else</option>
  </select>

  <label for="message">Anything we should know?</label>
  <textarea id="message" name="message" rows="4"></textarea>
  <p class="error" data-error-for="message" hidden></p>

  <input type="hidden" name="page" value="pricing" />
  <input type="hidden" name="_redirect" value="https://example.com/thanks" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Talk to sales</button>
</form>

スクリプトは訪問者をページにとどめます。サーバーから返った各フィールドのエラーをそのフィールドの下に表示し、成功するとフォームを、誰がいつ返信するかを伝える 1 行に差し替えます。

lead-form.js
const form = document.getElementById("lead-form");

function showErrors(fields) {
  form.querySelectorAll("[data-error-for]").forEach((slot) => {
    const message = fields[slot.dataset.errorFor]?.[0];
    slot.textContent = message ?? "";
    slot.hidden = !message;
  });
}

form.addEventListener("submit", async (event) => {
  event.preventDefault();
  const button = form.querySelector("button");
  button.disabled = true;
  button.textContent = "Sending";
  try {
    const response = await fetch(form.action, {
      method: "POST",
      headers: { Accept: "application/json" },
      body: new FormData(form),
    });
    const result = await response.json();
    if (result.ok) {
      const thanks = document.createElement("p");
      thanks.setAttribute("role", "status");
      thanks.textContent = `Thanks, ${form.elements.name.value.trim().split(" ")[0]}. A person on our team will reply to ${form.elements.email.value} within one working day.`;
      form.replaceWith(thanks);
      return;
    }
    showErrors(result.error.fields ?? {});
    if (!result.error.fields) alert(result.error.message);
  } catch {
    alert("Something went wrong. Email sales@example.com and we'll pick it up.");
  }
  button.disabled = false;
  button.textContent = "Talk to sales";
});
  • frm_xxxxxxxxxxxxxxxx をダッシュボードにある自分のフォームの ID に置き換えます。
  • 非表示の _gotcha 入力欄はハニーポットです。人には見えず、すべての入力欄を埋めるボットは自らスパムだと名乗ることになります。
  • 非表示の page 入力欄は、料金ページ、機能ページ、キャンペーンのランディングページなど、リードがどのページから来たかを記録します。フィールドを定義している場合は page を任意のテキストフィールドとして追加してください。そうしないと送信は Unknown field で拒否されます。
  • サーバー版は訪問者の Origin ヘッダーを転送します。サーバー側の fetch は何も送らず、Ikiform は無料の localhost テストをこのヘッダーで判定するからです。
  • プレーンな HTML フォームを自分のサンクスページに着地させるには、Redirect after submit か、Allowed domains のいずれかを指す _redirect 入力欄が必要です。
サーバー側の版はシークレットキー付きで送信するので、Ikiform は Allowed domains と人間確認をスキップします。その場合はすべての送信がサーバーの IP から来るため、訪問者ごとに 1 分あたり 5 件という Standard の制限が、全訪問者をまとめて数えることになります。サーバー経由で送信するフォームには Relaxed か Custom のレート制限を選び、IKIFORM_SECRET_KEY はサーバー専用の環境変数に置いてください。

各フレームワークの設定はドキュメントで詳しく解説しています:Next.js、Astro、SvelteKit、Nuxt、React、Vue、サーバーからの送信、プレーンな HTML。

数分以内にリードに連絡する

フォームは簡単な部分です。売れるリードフォームと集めるだけのリードフォームを分けるのは、送信から人による返信までの時間です。うまくいっているときの流れは次のとおりです。

リードの送信から最初の返信までの数分間送信0 秒保存1 秒未満メールとチャット数秒後返信する受信トレイからキュー返信リードの送信から最初の返信までの数分間送信0 秒保存1 秒未満メールとチャット数秒後返信する受信トレイからキュー返信
  1. リードがフォームを送信します。
  2. Ikiform はそれを保存し、1 秒を大きく下回る時間でブラウザーに応答します。
  3. 数秒後、通知メールと Webhook がキューから送られます。
  4. チームの誰かが受信トレイで Reply を押すか、チャットの mailto リンクを押すと、返信がリードに届きます。
メールまではすべて数秒です。最後の矢印だけは自分で制御でき、商談を勝ち取るのもそこです。

受信トレイから返信する

各通知メールは返信先アドレスをリードに設定します。Ikiform はまず _replyto フィールドから、次に email、email_address、your_email、reply_to、contact_email という名前のフィールドから取得します。フィールドの id を email にしておけば、Reply は Ikiform ではなくリードに届きます。件名は New submission: にフォーム名を付けたものなので、Talk to sales のようにフォームの用途に合わせた名前を付け、その件名で絞り込んでリードにラベルやスターを付けましょう。

フォームの通知設定で、フォームごとに最大 10 件の通知先を追加できます。ワークスペースのメンバーか、先にメールで確認する外部アドレスです。誰も担当していない共有エイリアスではなく、実際に返信する人に送ってください。5 つの受信トレイに届いて誰も引き受けないリードは、1 つの受信トレイに届いたリードより長く待たされます。

通知メールはフォームごとに 1 時間あたり 50 通まで(ワークスペース作成から 7 日未満の間は 10 通)で、その時間の残りは 1 通のダイジェストにまとめられます。通常のリードフォームではまず届きません。届きそうなキャンペーンを実施するなら、Webhook でリードをチャットにも送ってください。

チームがいる場所に通知する

メールは、誰かが受信トレイを担当していればうまくいきます。チャット中心のチームは、リードがそこに表示されたほうが速く返信します。Slack、Microsoft Teams、Discord の手順に従って Webhook を追加してください。メッセージに mailto: リンクを入れておけば、引き受けた人がワンクリックで返信できます。

尋ねた内容で振り分ける

interest は一覧の値しか受け付けないので、小さなリレーでも安心して分岐できます。このルートはデモの依頼と契約の質問をそれぞれ専用のチャンネルに送り、それ以外はメインの営業チャンネルに送ります。

app/api/leads/route.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";

const CHANNELS: Record<string, string | undefined> = {
  demo: process.env.SLACK_DEMO_WEBHOOK,
  custom: process.env.SLACK_ENTERPRISE_WEBHOOK,
};

export async function POST(request: Request) {
  const payload = await request.text();
  let event;
  try {
    event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.IKIFORM_WEBHOOK_SECRET! });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
  if (event.type !== "submission.created") return new Response(null, { status: 204 });

  const lead = event.data.fields;
  const interest = String(lead.interest ?? "other");
  const target = CHANNELS[interest] ?? process.env.SLACK_SALES_WEBHOOK!;
  const text = [
    `*${lead.name}* from ${lead.company || "an unknown company"} wants: ${interest}`,
    `Reply: mailto:${lead.email}`,
    lead.message ? `> ${String(lead.message).slice(0, 300)}` : "",
  ]
    .filter(Boolean)
    .join("\n");

  const response = await fetch(target, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ text }),
  });
  if (!response.ok) return new Response(`Slack answered ${response.status}`, { status: 502 });
  return new Response(null, { status: 204 });
}
  • verifyWebhook が署名とタイムスタンプをチェックするので、他人が偽のリードをチャンネルに投稿することはできません。
  • Slack が落ちているときに 502 を返すと、Ikiform は同じ配信を同じ webhook-id で約 3 日間リトライします。
  • 選択肢のラベルは自由に変えて構いません。リレーや自動化が依存したら、その値は変えないでください。

パイプラインにゴミを入れない

リードフォームには特有のスパムが集まります。SEO、被リンク獲得、開発の外注を売り込んでくる人たちです。最速の返信を無駄にするので、誰かに届く前に除外しましょう。

防御防げるもの設定
ハニーポットすべての入力欄を埋めるボット非表示の _gotcha 入力欄
スパムスコアseo services などの既知の売り込みフレーズ(+2)、名前の中のリンク(+3)、3 つ以上のリンク(+2)、繰り返し(+3)。5 でスパムなし
レート制限ループで送信するスクリプトフォームを Strict(訪問者ごとに 10 分あたり 2 件)に設定します。本物のリードが 10 分間に 2 回送信することはまずありません
許可ドメイン他のサイトからの送信Allowed domains に自分のドメインを追加する
人間確認本物のブラウザーで動くボットSpam check を Ikiform に設定します。その場合 fetch 版には challenge() のトークンが必要です

スパムにも本物のリードと同じ成功の応答が返り、メールも Webhook も送られず、使用量にも数えられません。つまり、誤判定されたリードも静かに埋もれます。週に 1 回は Spam フィルターを確認してください。スパムではないとマークすると、その時点でメールと Webhook が送られます。スパム対策のドキュメントにすべてのシグナルが載っています。

リードの出どころを把握する

各送信には、ページのオリジンとリファラーがすでに記録されており、Webhook には meta.origin と meta.referrer として含まれます。キャンペーンのタグには少し手助けが必要です。訪問者はあるページに着地して、別のページで送信することがよくあるからです。このスニペットは utm_ パラメーターを非表示の入力欄にコピーし、セッションの間覚えておきます。

attribution.html
<input type="hidden" name="utm_source" />
<input type="hidden" name="utm_medium" />
<input type="hidden" name="utm_campaign" />

<script>
  const params = new URLSearchParams(location.search);
  for (const key of ["utm_source", "utm_medium", "utm_campaign"]) {
    let value = params.get(key);
    try {
      if (value) sessionStorage.setItem(key, value);
      else value = sessionStorage.getItem(key);
    } catch {}
    const input = document.querySelector(`#lead-form [name="${key}"]`);
    if (input && value) input.value = value.slice(0, 200);
  }
</script>

フレームワークでは、同じパラメーターをサーバーで URL から読み取り、非表示の入力欄として描画します。フィールドを定義している場合は、各 utm_ の id を任意のテキストフィールドとして追加してください。_ で始まる名前は保存されないので、残したいデータには使わないでください。

リードが次に目にするもの

Ikiform はフォームに入力した本人にメールを送りません。通知メールはあなたとチームだけに届くので、自動返信、確認メール、ダブルオプトインはありません。それらは Webhook をきっかけにメールツールから送ってください。リードフォームならそれで問題ないことが多いです。自動のメールより、すぐに届く個人的な返信のほうが効果的です。それでも即時の受付通知を送りたいなら、Webhook が連絡先を作成したときに CRM やメールツールから送れば、返信や配信停止を 1 か所で管理できます。

何を送るにしても、ページ上の成功メッセージは約束です。誰がいつまでに返信するかを書き、それを守ってください。1 営業日と書いて 10 分で返信するフォームは信頼を得ます。10 分と書いて翌日に返信するフォームは信頼を失います。

CRM にリードを入れる

ワンクリックの連携はありません。どのツールにも、署名付きの Webhook で直接、または Zapier や n8n などの自動化ツールを経由して届けます。CRM の場合は、リレーが Ikiform の決まった形の Webhook ボディを CRM の連絡先作成の呼び出しに変換するということです。HubSpot や Pipedrive にリードを送るでは、重複とリトライも含めて両方を説明しています。CRM が必要になるまでは、ダッシュボードと毎週の CSV エクスポートで十分なパイプラインになります。

状況に合わせて選ぶ

上の構成はどんなリードにも使えます。以下のページでは、特定の種類のリードで変わる点と、リードを CRM に入れる方法を扱います。

動作を確認する

ページに集客する前に、これを一通り確認してください。Ikiform に無料プランはありません。テストは無料です。プランのないワークスペースでも、localhost からのテスト送信を月 50 件まで受け付けます。本番運用するには、500 件で月 $6 からの Pro を選ぶか、買い切りにしてください。10,000 件で $49、または 50,000 件で $149 で、クレジットに有効期限はありません。料金を参照してください。

  1. フォームの Allowed domains に自分のサイトのドメインを追加し、開発中は localhost も追加します。空のままにすると、どこからの送信も受け付けます。
  2. ページのフォームに入力して送信します。自分のサンクスページか、Ikiform のサンクスページに移動します。
  3. ダッシュボードで Submissions を開きます。送ったすべてのフィールドを含む新しい送信データがあります。
  4. 各受信者の受信トレイを確認します。件名は New submission: にフォーム名が続いたもので、Reply を押すと入力したアドレス宛てのメッセージが開きます。
  5. Webhook を追加した場合は、Webhooks でエンドポイントを開きます。配信が succeeded になり、サーバーの応答が表示されます。
  6. ハニーポットを埋めて _gotcha=bot で送信します。成功の応答は返りますが、送信データはスパムとして保存され、メールも Webhook も送られません。
  7. 何も届かない場合は、ダッシュボードのステータスフィルターを Spam に切り替えてください。スパムにも本物の送信と同じ成功の応答が返ります。
  8. 時間を測ります。スマートフォンから送信し、メールとチャットのメッセージが届くまでの時間を記録します。

トラブルシューティング

問題対処法
Reply の宛先がリードではなく Ikiform のアドレスになるフォームに、Ikiform がリードのメールアドレスと認識するフィールドがありません。フィールド名を email に変えるか、アドレスを入れた _replyto フィールドを送ってください。認識される名前:email、email_address、your_email、reply_to、contact_email。
page や utm_source で Unknown field 付きの 422 になるフォームにフィールド定義があり、非表示の入力欄がそこに含まれていません。任意のテキストフィールドとして追加するか、入力欄を削除してください。
422 validation_failed送信がフォームのフィールド定義に合っていません。error.fields に各フィールドと理由が示されます。入力欄の name をフィールド ID に合わせてください。
403 origin_not_allowed が返る、またはすべての送信がスパムになるページのドメインがフォームの Allowed domains にありません。ドメインと、ローカルテスト用の localhost を追加してください。登録したドメインのサブドメインは許可されます。
429 rate_limited1 人の訪問者がフォームのレート制限を超えて送信しました。Standard では訪問者ごとに 1 分あたり 5 件までです。Retry-After まで待つか、共有の IP 1 つから送信するフォームには Relaxed か Custom を選んでください。
403 challenge_requiredフォームのスパムチェックが Ikiform に設定されていて、fetch の送信にトークンがありませんでした。送信のたびに @ikiform/sdk の challenge(formId) でトークンを取得するか、チェックをオフにしてください。
送信データはダッシュボードにあるのに、メールも Webhook も届かないスパムとして保存されています。スパムでは何も送られません。Spam フィルターで開いて理由を確認し、スパムではないとマークすると、メールと Webhook が送られます。
受信者に通知メールが届かないワークスペース外のアドレスは、Ikiform が送るメールから先に確認を済ませる必要があります。確認済みかどうかを確かめ、次に受信者の迷惑メールフォルダーを確認してください。

よくある質問

手順で詰まったときや、あなたの状況に合うガイドがほしいときはメールでどうぞ: hello@ikiform.com