Formulaire de feedback pour un site ou une application6 min de lecture
Recueillir le feedback des bêta-testeurs build après build
Un formulaire de feedback bêta avec un lien personnel par testeur et par build, deux échelles de notation et un résumé hebdomadaire qui montre si chaque build s'est amélioré.
Donnez à chaque testeur un lien personnel qui porte un code testeur opaque et le numéro de build, pour que le formulaire sache qui répond et sur quel build sans le demander. Demandez à quoi ils ont utilisé le build, deux notes de 1 à 5 pour la stabilité et l'utilité, et ce qui les a bloqués. Comparez ensuite les builds, pas les réponses individuelles, pour voir si chaque version a fait bouger les chiffres.
Ce qui change avec le feedback bêta
Le feedback public vient d'inconnus, une seule fois. Le feedback bêta vient du même petit groupe de personnes, encore et encore, sur un logiciel qui change chaque semaine. Une réponse isolée compte moins que la tendance : le build 1.4.0 a-t-il paru plus stable que le 1.3.0 aux mêmes personnes ? Il faut pour cela deux choses qu'un formulaire de feedback normal n'a pas : qui a répondu, et sur quel build.
Demander aux testeurs de taper leur e-mail et leur numéro de version échoue en pratique. Ils oublient la version, la tapent mal ou écrivent « la dernière ». Les deux vont donc dans le lien que vous envoyez, et la page les remplit.
- Un nouveau build est distribué au groupe bêta.
- Un script génère un lien par testeur avec son code et le numéro de build, et vous les envoyez par e-mail.
- Le testeur ouvre le lien. La page remplit les champs masqués du testeur et du build et affiche le build concerné.
- Un script de synthèse lit chaque réponse via l'API et fait la moyenne des notes par build.
- Les blocages des notes les plus basses deviennent la liste des corrections du build suivant.
Les champs
Aperçu
Exécute le validateur d'Ikiform dans votre navigateur. Rien n'est envoyé.
tester et build sont des inputs masqués remplis depuis le lien. Leurs motifs rejettent tout ce qui ne vient pas d'une vraie invitation.| Champ | Pourquoi |
|---|---|
tester | Un code aléatoire de 10 caractères. Permet de suivre une personne d'un build à l'autre sans mettre son e-mail dans une URL |
build | Relie chaque note à une version. Le motif n'accepte que des versions comme 1.4.0 |
tried | Ce qu'ils ont réellement fait. Sans cela, les notes sont difficiles à interpréter |
stability, usefulness | Deux champs rating, de 1 à 5. Séparés, car un build stable de la mauvaise chose reste la mauvaise chose |
would_miss | À quel point ils seraient déçus sans. Une part croissante de « Très » est le signe le plus fort que la bêta fonctionne |
blockers | Facultatif, et c'est de là que vient la liste des corrections |
Créer un lien par testeur
Gardez une simple liste d'e-mails de testeurs dans testers.txt. Ce script attribue à chacun un code stable la première fois qu'il le voit, enregistre la correspondance dans testers.json et écrit un lien d'invitation par testeur pour le build indiqué. Commencez testers.json avec {}.
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}`);Envoyez le CSV via le publipostage de votre outil d'e-mailing, ou collez les liens à la main pour un petit groupe. Gardez testers.json privé : c'est le seul endroit où un code renvoie à une personne.
La page de feedback
Placez ceci sur une page /beta/feedback de votre site. Elle lit le code et le build depuis le lien, refuse d'afficher le formulaire sans eux et envoie de façon classique. Réglez Redirect after submit sur une page de remerciement. Cela fonctionne sur n'importe quel hébergeur statique ou créateur de sites qui autorise 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>Comparer les builds
Le tableau de bord affiche les réponses une par une. Pour comparer les builds, lisez-les toutes avec le SDK et regroupez par build. Lancez ceci avec une clé secrète dans 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)}%`,
})),
);Les notes arrivent sous forme de nombres, donc les moyennes ne demandent aucun parsing. Affichez le nombre de testeurs à côté de chaque moyenne : un build avec trois réponses ne se compare pas honnêtement à un build qui en a trente.
Vérifiez que tout fonctionne
- Lancez
node links.mjs 1.4.0et ouvrez l'un des liens. Le formulaire affiche "Feedback for build 1.4.0". - Ouvrez la page sans les paramètres d'URL. Seul le message d'invitation s'affiche.
- Envoyez une réponse, puis changez
buildenlatestdans les outils de développement du navigateur et envoyez à nouveau. Ikiform répond422avec "Use a version like 1.4.0". - Lancez
summary.mjs. Le tableau affiche le build 1.4.0 avec un testeur et vos deux notes.
Pièges
- Les groupes bêta testent souvent depuis un même bureau, qui partage une IP. La limite Standard les compte ensemble : choisissez donc Relaxed, 20 par minute et par visiteur, pour ce formulaire.
- Les bêtas mobiles sur TestFlight permettent déjà aux testeurs d'envoyer un feedback avec capture d'écran à App Store Connect. Utilisez-le pour les bugs d'écran et ce formulaire pour les questions hebdomadaires.
- Posez les mêmes questions chaque semaine. Changer la formulation casse la comparaison entre les builds.
- Les testeurs répondent de moins en moins au fil de la bêta. Gardez le formulaire à quelques minutes, et remerciez les gens par leur nom dans les notes de version.
- Ikiform ne fusionne pas les réponses répétées. Si un testeur répond deux fois pour un même build, gardez la plus récente dans votre synthèse.
Dépannage
| Problème | Que faire |
|---|---|
422 avec "Open the link from your invite email" | La valeur tester ne correspond pas au motif, généralement parce que le lien a été coupé dans un client e-mail. Renvoyez le lien. |
429 rate_limited | Un visiteur a envoyé plus que ce que permet la limite de débit du formulaire. Standard autorise 5 envois par minute et par visiteur. Attendez la durée de Retry-After, ou choisissez Relaxed ou Custom pour les formulaires qui envoient depuis une seule IP partagée. |
403 origin_not_allowed, ou tous les envois finissent en spam | Le domaine de la page n'est pas dans les Allowed domains du formulaire. Ajoutez-le, plus localhost pour les tests en local. Les sous-domaines d'un domaine listé sont autorisés. |
Questions
Donnez à chaque testeur un code aléatoire et mettez-le dans son lien personnel. La page le copie dans un champ masqué, et seul votre fichier de correspondance privé relie le code à un e-mail.
Mettez aussi le numéro de build dans le lien, validez-le avec un motif et regroupez les réponses par build. La méthode submissions.iterate du SDK lit chaque réponse pour une synthèse.
À quoi ils ont utilisé le build, à quel point il leur a paru stable et utile sur une échelle de 1 à 5, à quel point ils seraient déçus sans, et ce qui les a bloqués. Gardez les mêmes questions chaque semaine.
Gardez un formulaire de signalement de bug à part pour tout ce qui doit être reproduit. Le formulaire hebdomadaire porte sur le ressenti global du build ; mélanger les deux rend chacun plus difficile à lire.
Une étape vous bloque, ou vous voulez un guide pour votre cas ? Écrivez à hello@ikiform.com.