リード獲得フォーム

リード獲得フォーム2 分で読めます

ファイルアップロードなしで見積もり依頼フォームを作る

資料をアップロードではなく共有リンクで受け取り、すべての依頼に期限を付け、リンクの多いリードがスパムにならないようにする見積もり依頼フォームです。

Preet SutharIkiform 創業者

Ikiform は 422 files_not_supported でファイルアップロードを拒否するので、資料は url フィールドで共有フォルダーへのリンクとして求めます。サービスと予算は選択式にして、すべての依頼が同じ形で届くようにし、成功メッセージで回答までの期間を約束します。そのうえで各依頼を期限付きでチームに送り、約束を守れるようにします。

見積もり依頼ならではの違い

見積もり依頼には資料が付いてきます。概要書、間取り図、部品の一覧表、昨年のデザインなどです。よくある答えはファイル入力欄ですが、ここではうまくいきません。それを前提に設計する前に、理由を知っておく価値があります。

ファイルアップロードにはまだ対応していません。ファイル付きの送信には 422 files_not_supported が返ります。拒否されるのはファイルだけでなく送信全体なので、PDF を添付した訪問者は、フォームがエラーを表示して入力内容を残さない限り、入力したものをすべて失います。共有リンクならこの問題を避けられ、独自の利点もあります。依頼主は送信後にファイルを追加でき、サイズの上限もなく、大きなものが受信トレイにたまることもありません。

見積もり依頼フォームでのファイル入力欄とリンクのフィールドの比較ファイル入力欄リンクのフィールドbrief.pdf を添付multipart で送信422files_not_supported何も保存されないメールも Webhook もなしフォルダーのリンクurl フィールド201https として検証見積もり依頼メールとチャットにリンク訪問者が送るものIkiform がすること受け取るもの見積もり依頼フォームでのファイル入力欄とリンクのフィールドの比較ファイル入力欄リンクのフィールドbrief.pdfを添付multipartで送信422files_not_supported何も保存されないメールもWebhookもなしフォルダーのリンクurlフィールド201httpsとして検証見積もり依頼メールとチャットにリンク訪問者が送るものIkiformがすること受け取るもの
  1. ファイル入力欄では、訪問者が brief.pdf を添付し、ブラウザーが multipart で送信します。
  2. Ikiform は 422 files_not_supported で送信全体を拒否します。
  3. 何も保存されないので、メールも Webhook も送られません。
  4. リンクのフィールドでは、訪問者が共有フォルダーへのリンクを貼り付けます。
  5. Ikiform は有効な https の URL であることを確認し、依頼を保存します。
  6. リンクは通知メールとチャットに届き、チームの誰でも開けます。
同じ依頼で、結果は 2 通り。フォルダーのリンクを求めれば、ファイルがフォームを通ることはありません。

フィールド

見積もり依頼のテンプレートには、電話番号、会社、時期を含むすべてのフィールドがあります。下の版はそれを絞り込み、リンクのフィールドを追加したものです。http: のリンクや、drive.google.com だけのリンクを入れて、url フィールドの応答を試してみてください。

プレビュー

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

概要書、モックアップ、仕様書を入れた共有フォルダー。リンクを知っている全員が閲覧できるように設定してください。

files_url は https_only 付きの url フィールドなので、drive.google.com/... だけなら https://drive.google.com/... として保存され、http: のリンクは拒否されます。
フィールドこの形にしている理由
files_urlファイルごとのフィールドではなく、フォルダーへのリンク 1 つ。中身は依頼主が管理し、あとから追加できます
service誰が見積もるかを決めます。ラベルを変えても値は変わらないので、振り分けが安定します
budget任意で、何も送らない Not sure yet の選択肢付き。予算を必須にするとリードを失います
details必須で、20 文字以上。見積もりには範囲が必要で、それを得るのがここです

フォーム

素の HTML です。type="url" でスマートフォンに適切なキーボードが表示され、ヘルプテキストでフォルダーの共有方法を伝えるので、最初のリンクが非公開だったときのやり取りが 1 往復減ります。

quote.html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="POST">
  <label for="name">Name</label>
  <input id="name" name="name" autocomplete="name" required />

  <label for="email">Work email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />

  <label for="service">What do you need?</label>
  <select id="service" name="service" required>
    <option value="design">Design</option>
    <option value="development">Development</option>
    <option value="both">Design and development</option>
  </select>

  <label for="budget">Budget</label>
  <select id="budget" name="budget">
    <option value="">Not sure yet</option>
    <option value="under_5k">Under $5,000</option>
    <option value="5k_20k">$5,000 to $20,000</option>
    <option value="over_20k">Over $20,000</option>
  </select>

  <label for="files_url">Link to your files</label>
  <input id="files_url" name="files_url" type="url" inputmode="url" placeholder="https://drive.google.com/..." aria-describedby="files-help" />
  <p id="files-help">A shared folder with the brief, mockups or specs. Set it so anyone with the link can view.</p>

  <label for="details">What should the quote cover?</label>
  <textarea id="details" name="details" rows="5" minlength="20" required></textarea>

  <input type="hidden" name="_redirect" value="https://example.com/quote/thanks" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Request a quote</button>
</form>
古いフォームから引き継いだ <input type="file"> があれば削除してください。空のものは無視されます。ファイルが選ばれていると、multipart や FormData の送信は全体が失敗し、素の urlencoded のフォームはファイル名だけを送ります。どちらの場合もファイルは届きません。

見積もりフォームは、本物のリードが意図してリンクを送る唯一の場所で、リンクはスパムの兆候です。すべてのフィールドを合わせてリンクが 3 つ以上あるとスコアに 2 が加わります。url フィールドは完全な https:// のリンクとして保存されるので、数に入ります。

依頼に含まれるものスコア結果
フォルダーのリンク0受信
フォルダーのリンクと、details の中のリンク 2 つ+2受信
同じ 3 つのリンクを、24 時間以内に同じフィールドで再送+2 と +35 でスパム

3 行目は、最初の送信が失敗したと思った本物の人です。だからこそ、リンクのフィールドは 3 つではなく 1 つにし、成功の状態は見間違えようのないものにすべきです。Spam フィルターは毎週確認してください。依頼をスパムではないとマークすると、その時点でメールと Webhook が送られます。

すべての依頼に期限を付ける

成功メッセージは 2 営業日以内の見積もりを約束しています。この Cloudflare Worker が、その約束をチームが見える日付に変えます。Webhook を検証し、created_at から期限を計算し、ファイルのリンク付きで依頼を見積もり用のチャンネルに投稿します。

src/index.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";

function addWorkingDays(from: Date, days: number) {
  const date = new Date(from);
  while (days > 0) {
    date.setUTCDate(date.getUTCDate() + 1);
    const day = date.getUTCDay();
    if (day !== 0 && day !== 6) days -= 1;
  }
  return date.toISOString().slice(0, 10);
}

export default {
  async fetch(request: Request, env: { IKIFORM_WEBHOOK_SECRET: string; SLACK_QUOTES_WEBHOOK: string }) {
    const payload = await request.text();
    let event;
    try {
      event = await verifyWebhook({ payload, headers: request.headers, secret: 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 quote = event.data.fields;
    const due = addWorkingDays(new Date(event.data.created_at), 2);
    const lines = [
      `Quote due *${due}*: ${quote.service} for ${quote.name} (${quote.budget ?? "budget not given"})`,
      quote.files_url ? `Files: ${quote.files_url}` : "No files linked. Ask for them in the first reply.",
      `Reply: mailto:${quote.email}`,
    ];

    const response = await fetch(env.SLACK_QUOTES_WEBHOOK, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ text: lines.join("\n") }),
    });
    if (!response.ok) return new Response(`Slack answered ${response.status}`, { status: 502 });
    return new Response(null, { status: 204 });
  },
};
  • 営業日は UTC の土曜日と日曜日を除きます。休日を考慮して見積もるなら、休日を追加してください。
  • files_url がない場合は、空の行ではなく、最初の返信でファイルを求めるようにというリマインダーが出ます。
  • Slack が失敗したときに 502 を返すと Ikiform が同じ配信をリトライするので、依頼が失われません。

Worker の URL を Webhooks に追加し、whsec_ のシークレットを IKIFORM_WEBHOOK_SECRET にコピーし、Slack の URL をシークレットとして保存します。受信 Webhook の作り方は Slack のガイドにあります。

動作を確認する

  1. Google ドライブか Dropbox のフォルダーのリンクを付けて送信します。通知メールのリンクをプライベートウィンドウで開き、閲覧できることを確認します。
  2. http: のリンクで送信します。送信は 422 で拒否され、メッセージに files_url が示されます。
  3. テンプレートで type="file" を検索し、Ikiform に送信する見積もりフォームから該当するものをすべて削除します。
  4. 見積もり用のチャンネルを確認します。メッセージに 2 営業日後の期限とファイルのリンクが表示されます。
  5. 通知メールで Reply を押します。フォームに入力されたアドレス宛てに書けます。

ハマりどころ

  • 非公開のリンク。 いちばんよくある失敗は、所有者しか開けないリンクです。ヘルプテキストで共有方法を伝え、アクセス権は待たずに最初の返信で求めてください。
  • ファイルはあるがフォルダーがない依頼主。 最初のメールに添付ファイル付きで返信してもらいましょう。reply-to のおかげで、ファイルはチームとの通常のメールのスレッドに入ります。
  • 長い作業範囲。 通知メールに表示される値は 500 文字までです。details の全文はダッシュボードと Webhook にあります。
  • 受付メールはない。 Ikiform はフォームに入力した人にはメールを送りません。ページ上のメッセージが受付の連絡になるので、回答までの期間を具体的にしてください。

よくある質問

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