Formulaire de capture de leads

Formulaire de capture de leads6 min de lecture

Créer un formulaire de demande de devis sans envoi de fichiers

Un formulaire de demande de devis qui reçoit les briefs sous forme de liens partagés plutôt qu'en pièces jointes, fixe une échéance à chaque demande et garde les leads riches en liens hors du spam.

Preet SutharFondateur, Ikiform

Demandez le brief sous forme de lien vers un dossier partagé dans un champ url, car Ikiform refuse les envois de fichiers avec 422 files_not_supported. Gardez le service et le budget en choix fixes pour que chaque demande arrive sous la même forme, et promettez un délai dans le message de succès. Envoyez ensuite chaque demande à l'équipe avec son échéance, pour que la promesse soit tenue.

Ce qui change avec une demande de devis

Une demande de devis arrive avec du matériel : un brief, un plan, un tableur de pièces, le design de l'an dernier. La réponse habituelle est un input de fichier. Ça ne fonctionne pas ici, et il vaut mieux savoir pourquoi avant de concevoir autour.

L'envoi de fichiers n'est pas encore pris en charge. Un envoi avec un fichier reçoit 422 files_not_supported. C'est tout l'envoi qui est refusé, pas seulement le fichier : un visiteur qui joint un PDF perd donc tout ce qu'il a tapé, sauf si votre formulaire affiche l'erreur et garde sa saisie. Un lien partagé évite le problème et a ses propres avantages : le client peut ajouter des fichiers après l'envoi, il n'y a pas de limite de taille et rien de volumineux ne s'entasse dans votre boîte.

Un input de fichier comparé à un champ lien dans un formulaire de demande de devisinput de fichierchamp lienbrief.pdf jointPOST multipart422files_not_supportedrien n'est stockéni e-mail ni webhooklien de dossierchamp url201validé en httpsdemande de devislien dans l'e-mail et lechatce que le visiteur envoiece que fait Ikiformce que vous recevezUn input de fichier comparé à un champ lien dans un formulaire de demande de devisinput de fichierchamp lienbrief.pdfjointPOSTmultipart422files_not_supportedrienn'eststockénie-mailniwebhookliendedossierchampurl201validéenhttpsdemandededevisliendansl'e-mailet lechatce que levisiteurenvoiece que faitIkiformce que vousrecevez
  1. Avec un input de fichier, le visiteur joint brief.pdf et le navigateur envoie un POST multipart.
  2. Ikiform refuse tout l'envoi avec 422 files_not_supported.
  3. Rien n'est stocké, donc aucun e-mail ni webhook ne part.
  4. Avec un champ lien, le visiteur colle le lien d'un dossier partagé.
  5. Ikiform vérifie qu'il s'agit d'une URL https valide et stocke la demande.
  6. Le lien arrive dans l'e-mail de notification et dans le chat, où n'importe qui dans l'équipe peut l'ouvrir.
Même demande, deux résultats. Demandez un lien de dossier, et les fichiers ne passent jamais par le formulaire.

Les champs

Le modèle de demande de devis contient l'ensemble complet des champs, avec téléphone, entreprise et délai. La version ci-dessous l'allège et ajoute le champ lien. Essayez un lien http:, ou un simple lien drive.google.com, pour voir comment répond le champ url.

Aperçu

Exécute le validateur d'Ikiform dans votre navigateur. Rien n'est envoyé.

Un dossier partagé avec le brief, les maquettes ou les spécifications. Réglez-le pour que toute personne disposant du lien puisse le consulter.

files_url est un champ url avec https_only : un simple drive.google.com/... est donc stocké sous la forme https://drive.google.com/... et un lien http: est refusé.
ChampPourquoi cette forme
files_urlUn lien vers un dossier, pas un champ par fichier. Le client contrôle ce qu'il contient et peut y ajouter des fichiers plus tard
serviceDécide qui chiffre le devis. Les valeurs restent stables pour le routage, même si vous renommez les libellés
budgetFacultatif, avec un choix Pas encore sûr qui n'envoie rien. Un champ budget obligatoire fait perdre des leads
detailsObligatoire, au moins 20 caractères. Un devis a besoin d'un périmètre, et c'est d'ici qu'il vient

Le formulaire

HTML simple. type="url" affiche le bon clavier sur mobile, et le texte d'aide explique comment partager le dossier, ce qui évite un aller-retour quand le premier lien s'avère privé.

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>
Retirez tout <input type="file"> hérité d'un ancien formulaire. Un input vide est ignoré. Avec un fichier choisi, un envoi multipart ou FormData échoue en bloc, et un formulaire urlencoded classique n'envoie que le nom du fichier. Dans les deux cas, le fichier n'arrive jamais.

Un formulaire de devis est le seul endroit où de vrais leads envoient des liens exprès, et les liens sont un signal de spam. Trois liens ou plus sur l'ensemble des champs ajoutent 2 au score. Un champ url est stocké comme un lien https:// complet, il compte donc.

La demande contientScoreRésultat
Le lien du dossier0Reçue
Le lien du dossier et deux autres liens dans details+2Reçue
Les trois mêmes liens, renvoyés dans les 24 heures avec les mêmes champs+2 et +3Spam, à 5

La troisième ligne, c'est une vraie personne qui a cru que le premier envoi avait échoué. C'est pourquoi le formulaire doit avoir un seul champ lien, pas trois, et pourquoi l'état de succès doit être sans ambiguïté. Vérifiez le filtre Spam chaque semaine ; marquer une demande comme non-spam déclenche alors son e-mail et son webhook.

Fixer une échéance à chaque demande

Le message de succès promet un devis sous deux jours ouvrés. Ce Cloudflare Worker transforme cette promesse en une date visible par l'équipe. Il vérifie le webhook, calcule l'échéance à partir de created_at et publie la demande dans un canal de devis avec le lien des fichiers :

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 });
  },
};
  • Les jours ouvrés sautent le samedi et le dimanche en UTC. Ajoutez vos jours fériés si vos devis en tiennent compte.
  • Un files_url manquant produit un rappel de demander les fichiers dans la première réponse, plutôt qu'une ligne vide.
  • Répondre 502 quand Slack échoue fait réessayer Ikiform pour la même livraison : une demande n'est donc pas perdue.

Ajoutez l'URL du Worker sous Webhooks, copiez le secret whsec_ dans IKIFORM_WEBHOOK_SECRET et stockez l'URL Slack comme secret. Le guide Slack explique comment créer l'incoming webhook.

Vérifiez que tout fonctionne

  1. Envoyez avec le lien d'un dossier Google Drive ou Dropbox. Ouvrez le lien de l'e-mail de notification dans une fenêtre privée pour confirmer qu'il est consultable.
  2. Envoyez avec un lien http:. L'envoi est refusé avec 422 et le message nomme files_url.
  3. Cherchez type="file" dans vos templates et supprimez chaque occurrence des formulaires de devis qui envoient à Ikiform.
  4. Vérifiez le canal des devis. Le message affiche l'échéance à deux jours ouvrés et le lien des fichiers.
  5. Appuyez sur Reply dans l'e-mail de notification. La réponse part à l'adresse indiquée dans le formulaire.

Pièges

  • Les liens privés. L'échec le plus courant est un lien que seul son propriétaire peut ouvrir. Expliquez comment le partager dans le texte d'aide, et demandez l'accès dans la première réponse plutôt que de l'attendre.
  • Les clients qui ont des fichiers mais pas de dossier. Dites-leur de répondre à votre premier e-mail avec des pièces jointes. L'adresse de réponse place leurs fichiers dans un fil d'e-mails normal avec votre équipe.
  • Les périmètres longs. Les e-mails de notification affichent les valeurs jusqu'à 500 caractères. Le texte complet de details est dans le tableau de bord et le webhook.
  • Pas d'accusé de réception par e-mail. Ikiform n'envoie pas d'e-mail à la personne qui remplit le formulaire. Le message sur la page sert d'accusé de réception : rendez donc le délai concret.

Questions

Une étape vous bloque, ou vous voulez un guide pour votre cas ? Écrivez à hello@ikiform.com.