Formulario de captación de leads

Formulario de captación de leads6 min de lectura

Crea un formulario de consulta de proyecto para una agencia o un freelance

Un formulario de inicio de proyecto para estudios y freelances que clasifica las consultas en calientes, templadas y sin encaje por presupuesto y plazos antes de que nadie lea el briefing.

Preet SutharFundador, Ikiform

Pide los servicios como checkboxes, el presupuesto y la fecha de inicio como opciones fijas, y una descripción lo bastante larga para valorar el encaje. Envía cada consulta por webhook a un pequeño relay que la clasifica en los carriles caliente, templado o sin encaje según presupuesto y plazos. Luego responde el carril caliente el mismo día, y declina con educación el carril sin encaje en un día, porque ambas respuestas construyen tu reputación.

Qué tiene de distinto una consulta de proyecto

Una solicitud de presupuesto pide precio para un trabajo conocido. Una consulta de proyecto hace una pregunta más grande: ¿encajamos? A menudo el visitante aún está dando forma al proyecto, y tú decides si le dedicas una llamada de descubrimiento. Para un estudio o un freelance, lo escaso no son los leads, son las horas de los socios leyendo briefings que nunca iban a salir adelante.

Así que este formulario recoge la estructura suficiente para clasificar antes de leer. Bastan tres respuestas: qué necesitan, cuánto pueden gastar más o menos y cuándo. Todo lo que querrías comentar va en una descripción larga que solo se lee entera cuando las respuestas estructuradas dicen que vale la pena.

Cómo clasifica un relay las consultas de proyecto en carrilesconsultaservicios,presupuesto,iniciorelayverifica,puntúa¿presupuestoeinicio?carrilcaliente30k $+,empieza prontocarriltempladoresponder endos díascarril sinencajerechazoeducadowebhookaltobajo o más tardeCómo clasifica un relay las consultas de proyecto en carrilesconsultaservicios,presupuesto, iniciorelayverifica, puntúa¿presupuestoe inicio?carril caliente30k $+, empieza prontocarriltempladoresponder endos díascarril sinencajerechazoeducadowebhookaltobajo o más tarde
  1. La consulta llega como un webhook firmado con servicios, presupuesto y fecha de inicio.
  2. El relay verifica la firma y puntúa el presupuesto y los plazos.
  3. Comprueba la puntuación.
  4. Un presupuesto de 30.000 $ o más que empieza en menos de tres meses va al carril caliente.
  5. Un presupuesto menor o un inicio más tardío va al carril templado.
  6. Menos de 10.000 $ para algo que no sea una web va al carril sin encaje, para un rechazo rápido y amable.
Los carriles son canales de chat. No se rechaza a nadie automáticamente: una persona sigue respondiendo en cada carril, en otro orden.

Los campos

Para un formulario más ligero con un solo tema, parte de la plantilla de formulario de contacto. Este añade las tres preguntas de clasificación. Marca varios servicios en la vista previa para ver cómo se guardan como lista.

Vista previa

Ejecuta el validador de Ikiform en tu navegador. No se envía nada.

¿Qué necesitas?
¿Cuándo debería empezar?

Objetivos, público y cómo sería el éxito.

services es un multi_select, guardado como un array como ["brand", "website"]. website es un campo url, así que example.com se guarda como https://example.com/.
CampoPor qué tiene esta forma
servicesCasillas, porque los proyectos reales combinan servicios. Llega como array en el webhook
budgetObligatorio aquí, a diferencia de un formulario de presupuesto. Tus rangos deberían empezar donde empieza tu encargo mínimo
startSolo explorando por ahora es una respuesta honesta, y útil: va al carril templado
descriptionAl menos 40 caracteres, como mucho 4.000. Lo bastante largo para valorar el encaje, lo bastante corto para que la gente lo termine

El formulario

Las casillas comparten un mismo name. El navegador envía services=brand&services=website, e Ikiform junta las repeticiones en una lista. Terminar el nombre en [] también funciona, si tus herramientas lo esperan.

start-a-project.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">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />
  <label for="website">Your current website</label>
  <input id="website" name="website" inputmode="url" placeholder="example.com" />

  <fieldset>
    <legend>What do you need?</legend>
    <label><input type="checkbox" name="services" value="brand" /> Brand identity</label>
    <label><input type="checkbox" name="services" value="website" /> Website</label>
    <label><input type="checkbox" name="services" value="app" /> Web or mobile app</label>
    <label><input type="checkbox" name="services" value="seo" /> Search and content</label>
  </fieldset>

  <label for="budget">Budget</label>
  <select id="budget" name="budget" required>
    <option value="under_10k">Under $10,000</option>
    <option value="10k_30k">$10,000 to $30,000</option>
    <option value="30k_75k">$30,000 to $75,000</option>
    <option value="over_75k">Over $75,000</option>
  </select>

  <fieldset>
    <legend>When should it start?</legend>
    <label><input type="radio" name="start" value="this_month" required /> This month</label>
    <label><input type="radio" name="start" value="next_quarter" /> In the next three months</label>
    <label><input type="radio" name="start" value="exploring" /> Exploring for now</label>
  </fieldset>

  <label for="description">Tell us about the project</label>
  <textarea id="description" name="description" rows="6" minlength="40" maxlength="4000" required></textarea>

  <input type="hidden" name="_redirect" value="https://studio.example/inquiry/thanks" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send inquiry</button>
</form>

Clasifica las consultas con un webhook

Este servidor Express recibe cada consulta, la verifica, elige un carril y publica un resumen corto en el canal de Slack de ese carril. Lee el cuerpo sin procesar con express.raw, porque la firma cubre los bytes exactos que envió Ikiform, y pasa req.headers de Node a verifyWebhook tal cual.

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

const BUDGET: Record<string, number> = { under_10k: 0, "10k_30k": 1, "30k_75k": 2, over_75k: 3 };
const START: Record<string, number> = { this_month: 2, next_quarter: 1, exploring: 0 };
const CHANNEL = {
  hot: process.env.SLACK_HOT_LEADS!,
  warm: process.env.SLACK_LEADS!,
  "no-fit": process.env.SLACK_NO_FIT!,
};

function lane(fields: Record<string, unknown>): keyof typeof CHANNEL {
  const budget = BUDGET[String(fields.budget)] ?? 0;
  const start = START[String(fields.start)] ?? 0;
  const services = Array.isArray(fields.services) ? fields.services : [];
  if (budget === 0 && !services.includes("website")) return "no-fit";
  if (budget >= 2 && start >= 1) return "hot";
  return "warm";
}

const app = express();

app.post("/webhooks/inquiries", express.raw({ type: "application/json" }), async (req, res) => {
  let event;
  try {
    event = await verifyWebhook({
      payload: req.body.toString("utf8"),
      headers: req.headers,
      secret: process.env.IKIFORM_WEBHOOK_SECRET!,
    });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return res.status(400).send(error.reason);
    throw error;
  }
  if (event.type !== "submission.created") return res.sendStatus(204);

  const fields = event.data.fields;
  const which = lane(fields);
  const summary = String(fields.description ?? "").slice(0, 280);
  const response = await fetch(CHANNEL[which], {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
      text: `[${which}] ${fields.name}: ${(fields.services as string[]).join(", ")}, ${fields.budget}, ${fields.start}\n> ${summary}\nmailto:${fields.email}`,
    }),
  });
  res.sendStatus(response.ok ? 204 : 502);
});

app.listen(3000);
  • Cambia lane() para que encaje con tu forma de vender. Los umbrales de arriba son un ejemplo, no un consejo.
  • El resumen son los primeros 280 caracteres de la descripción. El texto completo está en el panel y en event.data.fields.
  • Un 502 cuando falla Slack hace que Ikiform reintente la misma entrega durante unos 3 días, así que una consulta no se pierde por una caída del chat.

Añade la URL https: pública del servidor en Webhooks. Si prefieres no mantener un servidor, la misma ramificación funciona como paso de router en Zapier, Make o n8n.

Cuando tus propios servicios suenan a spam

La puntuación de spam incluye frases conocidas de venta, como seo services, backlinks y rank your website, y cada una suma 2. Si vendes trabajo de posicionamiento, un cliente real puede escribir exactamente eso. Los enlaces también suman: website se guarda como enlace, y tres o más enlaces suman 2.

Una consulta real que contienePuntuaciónResultado
"We need SEO services" y una web+2Recibido
Lo mismo, más dos enlaces a competidores en la descripción+2 y +2Recibido, una señal por debajo del umbral
Todo lo anterior, enviado dos veces en 24 horas+2, +2 y +3Spam, por encima de 5

Una opción de búsqueda y contenido en services permite a los clientes decir lo que necesitan sin escribir la frase. Revisa igualmente el filtro Spam cada semana; perder una consulta de 50.000 $ cuesta más que leer diez envíos de spam.

Comprueba que funciona

  1. Envía con dos servicios marcados. El envío guarda services como una lista de dos elementos.
  2. Envía con Más de 75.000 $ y Este mes. El resumen llega al canal caliente.
  3. Envía con Menos de 10.000 $ y solo Identidad de marca. Llega al canal sin encaje.
  4. Pega una descripción de 3.000 caracteres. El email de notificación corta el valor en 500 caracteres; el panel lo muestra entero.
  5. Para tu servidor y envía. La entrega muestra intentos fallidos en Webhooks, y luego tiene éxito cuando lo vuelves a arrancar y eliges Retry.

Errores comunes

  • Ninguna casilla marcada. Un grupo de casillas vacío no envía nada, así que el required de HTML no puede exigirlo. Ikiform rechaza el envío con Choose at least one option; muestra ese error en la página con la versión fetch de la guía de captación de leads.
  • Renombrar opciones. Cambia las etiquetas libremente. Cambia los valores solo a la vez que el relay, o las consultas caerán en el carril equivocado.
  • Briefs largos en el email. Los emails de notificación muestran hasta 20 campos y 500 caracteres por valor. La descripción se corta ahí. Los miembros del espacio de trabajo reciben en el email un enlace al envío completo.
  • El rechazo. Ikiform no envía nada a la persona que rellenó el formulario, así que un lead sin encaje no sabe nada a menos que alguien responda. Un rechazo de dos líneas con una recomendación deja la puerta abierta.

Preguntas

¿Te atascaste en un paso o quieres una guía para tu caso? Escribe a hello@ikiform.com.