Formulário de feedback para um site ou app6 min de leitura
Colete o feedback dos beta testers build a build
Um formulário de feedback de beta com um link pessoal por tester e build, duas escalas de nota e um resumo semanal que mostra se cada build melhorou.
Dê a cada tester um link pessoal que leva um código opaco do tester e o número do build, para que o formulário saiba quem é e qual build sem perguntar. Pergunte para que a pessoa usou o build, duas notas de 1 a 5 para estabilidade e utilidade, e o que a travou. Depois compare builds, não respostas individuais, para ver se cada release mexeu nos números.
O que muda no feedback de beta
O feedback público vem de desconhecidos, uma vez. O feedback de beta vem do mesmo pequeno grupo de pessoas, de novo e de novo, sobre um software que muda toda semana. Uma resposta isolada importa menos que a tendência: o build 1.4.0 pareceu mais estável que o 1.3.0 para as mesmas pessoas? Isso exige duas coisas que um formulário de feedback normal não tem: quem respondeu e em qual build estava.
Pedir aos testers que digitem o e-mail e o número da versão falha na prática. Eles esquecem a versão, digitam errado ou escrevem "a mais recente". Então as duas coisas vão no link que você envia, e a página as preenche.
- Um build novo é liberado para o grupo de beta.
- Um script gera um link por tester com o código dele e o número do build, e você os envia por e-mail.
- O tester abre o link. A página preenche os campos ocultos de tester e build e mostra sobre qual build está perguntando.
- Um script de resumo lê todas as respostas pela API e tira a média das notas por build.
- Os bloqueios das notas mais baixas viram a lista de correções do próximo build.
Os campos
Prévia
Roda o validador do Ikiform no seu navegador. Nada é enviado.
tester e build são inputs ocultos preenchidos a partir do link. Os padrões deles rejeitam qualquer coisa que não veio de um convite real.| Campo | Por quê |
|---|---|
tester | Um código aleatório de 10 caracteres. Permite acompanhar uma pessoa ao longo dos builds sem colocar o e-mail dela numa URL |
build | Liga cada nota a um release. O padrão só aceita versões como 1.4.0 |
tried | O que a pessoa realmente fez. Notas sem isso são difíceis de interpretar |
stability, usefulness | Dois campos rating, de 1 a 5. Separados, porque um build estável da coisa errada continua sendo a coisa errada |
would_miss | O quanto a pessoa ficaria decepcionada sem ele. Uma parcela crescente de "Muito" é o sinal mais forte de que o beta está funcionando |
blockers | Opcional, e é daqui que sai a lista de correções |
Gere um link por tester
Mantenha uma lista simples de e-mails dos testers em testers.txt. Este script dá a cada um um código estável na primeira vez que o vê, guarda o mapeamento em testers.json e escreve um link de convite por tester para o build que você indicar. Comece 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}`);Envie o CSV pela mala direta da sua ferramenta de e-mail, ou cole os links à mão para um grupo pequeno. Mantenha testers.json privado: é o único lugar onde um código leva de volta a uma pessoa.
A página de feedback
Coloque isto numa página em /beta/feedback no seu site. Ela lê o código e o build do link, se recusa a mostrar o formulário sem eles e envia do jeito tradicional. Defina Redirect after submit para uma página de agradecimento. Funciona em qualquer host estático ou criador de sites que permita um 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>Compare builds
O painel mostra respostas individuais. Para comparar builds, leia todas com o SDK e agrupe por build. Rode isto com uma chave secreta em 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)}%`,
})),
);As notas chegam como números, então as médias não exigem parsing. Conte os testers ao lado de cada média: um build com três respostas não pode ser comparado de forma justa com um que tem trinta.
Confira se funciona
- Rode
node links.mjs 1.4.0e abra um dos links. O formulário mostra "Feedback do build 1.4.0". - Abra a página sem a query string. Só a mensagem de convite aparece.
- Envie uma resposta, depois mude
buildparalatestnas ferramentas de desenvolvedor do navegador e envie de novo. O Ikiform responde422com "Use a version like 1.4.0". - Rode
summary.mjs. A tabela mostra o build 1.4.0 com um tester e as suas duas notas.
Pegadinhas
- Grupos de beta costumam testar de um mesmo escritório, que compartilha um IP. O limite Standard os conta juntos, então escolha Relaxed, 20 por minuto por visitante, para este formulário.
- Betas mobile no TestFlight já permitem que os testers mandem feedback com captura de tela para o App Store Connect. Use isso para bugs de tela e este formulário para as perguntas semanais.
- Faça as mesmas perguntas toda semana. Mudar a redação quebra a comparação entre builds.
- Os testers respondem menos conforme o beta avança. Mantenha o formulário em poucos minutos, e agradeça às pessoas pelo nome nas notas de release.
- O Ikiform não junta respostas repetidas. Se um tester responder duas vezes para um build, fique com a mais recente no seu resumo.
Solução de problemas
| Problema | O que fazer |
|---|---|
422 com "Open the link from your invite email" | O valor de tester não bate com o padrão, geralmente porque o link foi cortado num cliente de e-mail. Reenvie o link. |
429 rate_limited | Um visitante enviou mais do que o limite de taxa do formulário permite. O Standard permite 5 por minuto por visitante. Espere o Retry-After, ou escolha Relaxed ou Custom para formulários que enviam a partir de um único IP compartilhado. |
403 origin_not_allowed, ou todo envio cai no spam | O domínio da página não está em Allowed domains do formulário. Adicione-o, mais localhost para testes locais. Subdomínios de um domínio listado são permitidos. |
Perguntas
Dê a cada tester um código aleatório e coloque-o no link pessoal dele. A página o copia para um campo oculto, e só o seu arquivo de mapeamento privado liga o código a um e-mail.
Coloque também o número do build no link, valide com um padrão e agrupe as respostas por build. O submissions.iterate do SDK lê todas as respostas para um resumo.
Para que a pessoa usou o build, quão estável e quão útil ele pareceu numa escala de 1 a 5, o quanto ela ficaria decepcionada sem ele e o que a travou. Mantenha as mesmas perguntas toda semana.
Mantenha um formulário de relato de bug separado para tudo o que precisa ser reproduzido. O formulário semanal é sobre a impressão geral do build; misturar os dois deixa ambos mais difíceis de ler.
Travou em algum passo ou quer um guia para o seu caso? Envie um e-mail para hello@ikiform.com.