Formulario de feedback para un sitio web o una app6 min de lectura
Recoge el feedback de los beta testers build a build
Un formulario de feedback para betas con un enlace personal por tester y build, dos escalas de valoración y un resumen semanal que muestra si cada build mejoró.
Da a cada tester un enlace personal con un código de tester opaco y el número de build, para que el formulario sepa quién responde y sobre qué build sin preguntarlo. Pregunta para qué usaron la build, dos valoraciones de 1 a 5 de estabilidad y utilidad, y qué les frenó. Después compara builds, no respuestas sueltas, para ver si cada versión movió los números.
Qué cambia en el feedback de una beta
El feedback público viene de desconocidos, una sola vez. El feedback de una beta viene del mismo grupo pequeño de personas, una y otra vez, sobre un software que cambia cada semana. Una respuesta suelta importa menos que la tendencia: ¿la build 1.4.0 les pareció más estable que la 1.3.0 a las mismas personas? Para eso hacen falta dos cosas que un formulario de feedback normal no tiene: quién respondió y en qué build estaba.
Pedir a los testers que escriban su email y su número de versión falla en la práctica. Olvidan la versión, la escriben mal o ponen "la última". Así que ambos van en el enlace que envías, y la página los rellena.
- Sale una build nueva para el grupo de la beta.
- Un script crea un enlace por tester con su código y el número de build, y se los envías por email.
- El tester abre el enlace. La página rellena los campos ocultos de tester y build y muestra por qué build pregunta.
- Un script de resumen lee todas las respuestas a través de la API y promedia las puntuaciones por build.
- Los bloqueos de las puntuaciones más bajas se convierten en la lista de arreglos de la siguiente build.
Los campos
Vista previa
Ejecuta el validador de Ikiform en tu navegador. No se envía nada.
tester y build son inputs ocultos que se rellenan desde el enlace. Sus patrones rechazan todo lo que no venga de una invitación real.| Campo | Por qué |
|---|---|
tester | Un código aleatorio de 10 caracteres. Te permite seguir a una persona entre builds sin poner su email en una URL |
build | Vincula cada puntuación a una versión. El patrón solo acepta versiones como 1.4.0 |
tried | Lo que hicieron realmente. Sin esto, las puntuaciones son difíciles de interpretar |
stability, usefulness | Dos campos rating, de 1 a 5. Separados, porque una build estable de algo equivocado sigue siendo algo equivocado |
would_miss | Lo decepcionados que estarían sin él. Una proporción creciente de "Muy" es la señal más clara de que la beta funciona |
blockers | Opcional, y de donde sale la lista de arreglos |
Crea un enlace por tester
Guarda una lista simple de emails de testers en testers.txt. Este script asigna a cada uno un código estable la primera vez que lo ve, guarda la correspondencia en testers.json y escribe un enlace de invitación por tester para la build que indiques. Empieza testers.json como {}.
import { randomBytes } from "node:crypto";
import { readFileSync, writeFileSync } from "node:fs";
const BUILD = process.argv[2];
if (!/^\d+\.\d+\.\d+$/.test(BUILD ?? "")) throw new Error("Usage: node links.mjs 1.4.0");
const known = JSON.parse(readFileSync("testers.json", "utf8"));
const emails = readFileSync("testers.txt", "utf8").split(/\r?\n/).map((line) => line.trim().toLowerCase()).filter(Boolean);
for (const email of emails) {
known[email] ??= randomBytes(5).toString("hex");
}
writeFileSync("testers.json", JSON.stringify(known, null, 2));
const rows = emails.map((email) => {
const link = new URL("https://example.com/beta/feedback");
link.searchParams.set("t", known[email]);
link.searchParams.set("build", BUILD);
return `${email},${link}`;
});
writeFileSync(`invites-${BUILD}.csv`, ["email,link", ...rows].join("\n"));
console.log(`${rows.length} links for build ${BUILD}`);Envía el CSV con la combinación de correspondencia de tu herramienta de email, o pega los enlaces a mano si el grupo es pequeño. Mantén testers.json en privado: es el único sitio donde un código se relaciona con una persona.
La página de feedback
Ponlo en una página en /beta/feedback de tu sitio. Lee el código y la build del enlace, no muestra el formulario sin ellos y envía de la forma normal. Configura Redirect after submit con una página de agradecimiento. Funciona en cualquier hosting estático o creador de sitios que permita un script.
<p id="beta-missing" hidden>This page needs the link from your invite email.</p>
<form id="beta" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post" hidden>
<h2>Feedback for build <span id="beta-build"></span></h2>
<input type="hidden" name="tester" />
<input type="hidden" name="build" />
<label for="tried">What did you use this build for?</label>
<textarea id="tried" name="tried" rows="4" required minlength="15"></textarea>
<fieldset>
<legend>How stable did it feel?</legend>
<label><input type="radio" name="stability" value="1" required /> 1, it crashed a lot</label>
<label><input type="radio" name="stability" value="2" /> 2</label>
<label><input type="radio" name="stability" value="3" /> 3</label>
<label><input type="radio" name="stability" value="4" /> 4</label>
<label><input type="radio" name="stability" value="5" /> 5, no problems</label>
</fieldset>
<fieldset>
<legend>How useful was it?</legend>
<label><input type="radio" name="usefulness" value="1" required /> 1, not at all</label>
<label><input type="radio" name="usefulness" value="2" /> 2</label>
<label><input type="radio" name="usefulness" value="3" /> 3</label>
<label><input type="radio" name="usefulness" value="4" /> 4</label>
<label><input type="radio" name="usefulness" value="5" /> 5, I rely on it</label>
</fieldset>
<fieldset>
<legend>If you could no longer use it, how would you feel?</legend>
<label><input type="radio" name="would_miss" value="very" required /> Very disappointed</label>
<label><input type="radio" name="would_miss" value="somewhat" /> Somewhat disappointed</label>
<label><input type="radio" name="would_miss" value="not" /> Not disappointed</label>
</fieldset>
<label for="blockers">Anything that stopped you?</label>
<textarea id="blockers" name="blockers" rows="3"></textarea>
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button>Send this week's feedback</button>
</form>
<script>
const params = new URLSearchParams(location.search);
const tester = params.get("t") ?? "";
const build = params.get("build") ?? "";
const form = document.getElementById("beta");
if (/^[a-z0-9]{10}$/.test(tester) && /^\d+\.\d+\.\d+$/.test(build)) {
form.elements.tester.value = tester;
form.elements.build.value = build;
document.getElementById("beta-build").textContent = build;
form.hidden = false;
} else {
document.getElementById("beta-missing").hidden = false;
}
</script>Compara builds
El panel muestra las respuestas individuales. Para comparar builds, léelas todas con el SDK y agrúpalas por build. Ejecútalo con una clave secreta en IKIFORM_SECRET_KEY:
import { createClient } from "@ikiform/sdk";
const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY });
const builds = new Map();
for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx", status: "received" })) {
const { build, tester, stability, usefulness, would_miss } = submission.fields;
const row = builds.get(build) ?? { testers: new Set(), stability: 0, usefulness: 0, very: 0, answers: 0 };
row.testers.add(tester);
row.stability += stability;
row.usefulness += usefulness;
row.very += would_miss === "very" ? 1 : 0;
row.answers += 1;
builds.set(build, row);
}
console.table(
[...builds].map(([build, row]) => ({
build,
testers: row.testers.size,
stability: (row.stability / row.answers).toFixed(1),
usefulness: (row.usefulness / row.answers).toFixed(1),
"very disappointed": `${Math.round((row.very / row.answers) * 100)}%`,
})),
);Las valoraciones llegan como números, así que las medias no necesitan parseo. Cuenta los testers junto a cada media: una build con tres respuestas no se puede comparar de forma justa con una que tiene treinta.
Comprueba que funciona
- Ejecuta
node links.mjs 1.4.0y abre uno de los enlaces. El formulario muestra "Feedback for build 1.4.0". - Abre la página sin la query string. Solo se muestra el mensaje de invitación.
- Envía una respuesta, luego cambia
buildalatesten las herramientas de desarrollo del navegador y vuelve a enviar. Ikiform responde422con "Use a version like 1.4.0". - Ejecuta
summary.mjs. La tabla muestra la build 1.4.0 con un tester y tus dos puntuaciones.
Errores comunes
- Los grupos de beta suelen probar desde una misma oficina, que comparte IP. El límite Standard los cuenta juntos, así que elige Relaxed, 20 por minuto por visitante, para este formulario.
- Las betas móviles en TestFlight ya permiten a los testers enviar feedback con capturas a App Store Connect. Usa eso para los bugs de pantalla y este formulario para las preguntas semanales.
- Haz las mismas preguntas cada semana. Cambiar la redacción rompe la comparación entre builds.
- Los testers responden menos a medida que avanza la beta. Mantén el formulario en un par de minutos y agradece a la gente por su nombre en las notas de la versión.
- Ikiform no fusiona respuestas repetidas. Si un tester responde dos veces para una build, quédate con la última en tu resumen.
Solución de problemas
| Problema | Qué hacer |
|---|---|
422 con "Open the link from your invite email" | El valor de tester no coincide con el patrón, normalmente porque el cliente de email cortó el enlace. Vuelve a enviar el enlace. |
429 rate_limited | Un visitante envió más de lo que permite el límite de frecuencia del formulario. Standard permite 5 por minuto por visitante. Espera lo que indique Retry-After, o elige Relaxed o Custom para formularios que envían desde una IP compartida. |
403 origin_not_allowed, o todos los envíos acaban en spam | El dominio de la página no está en Allowed domains del formulario. Añádelo, y localhost para las pruebas locales. Los subdominios de un dominio de la lista están permitidos. |
Preguntas
Da a cada tester un código aleatorio y ponlo en su enlace personal. La página lo copia en un campo oculto, y solo tu archivo privado de correspondencias relaciona el código con un email.
Pon también el número de build en el enlace, valídalo con un patrón y agrupa las respuestas por build. submissions.iterate del SDK lee todas las respuestas para un resumen.
Para qué usaron la build, qué tan estable y útil les pareció en una escala de 1 a 5, lo decepcionados que estarían sin ella y qué les frenó. Mantén las mismas preguntas cada semana.
Ten un formulario de bugs aparte para todo lo que haya que reproducir. El formulario semanal es para cómo se siente la build en general; mezclar ambos hace que los dos sean más difíciles de leer.
¿Te atascaste en un paso o quieres una guía para tu caso? Escribe a hello@ikiform.com.