Lista de espera para un nuevo SaaS9 min de lectura
Cómo crear una página de lista de espera para una app móvil antes de lanzarla en la App Store
Una lista de espera previa al lanzamiento para una app de iOS o Android que pregunta qué teléfono se usa, lleva a los testers de iPhone a TestFlight y llena una prueba cerrada de Play.
Pon un formulario de lista de espera en la landing page de tu app que pregunte qué teléfono usa la persona y si quiere probar antes. Mete a los testers de iPhone en un grupo de TestFlight con un webhook y la API de App Store Connect, y carga a los testers de Android en una prueba cerrada de Google Play desde una exportación. El día del lanzamiento, envía a cada grupo por email el enlace a su tienda.
Antes de que una app esté en una tienda, no hay botón de instalar al que enviar a la gente. Una lista de espera en tu propia landing page mantiene su interés hasta que lo haya, y cumple una segunda función que las tiendas no cubren: encuentra los testers que necesitas antes del lanzamiento.
Qué cambia en una app móvil
- Dos tiendas, dos listas. El email de lanzamiento enlaza a la App Store o a Google Play, y las invitaciones de prueba pasan por TestFlight o por una prueba cerrada de Play. Necesitas saber la plataforma de cada persona para enviar la correcta.
- Los testers tienen que coincidir con la cuenta de la tienda. TestFlight envía una invitación por email a cualquier dirección. Una prueba cerrada de Play solo deja entrar a las cuentas de Google de su lista, así que un tester de Android que se registra con una dirección del trabajo no puede instalar la build.
- Google Play puede exigir testers antes del lanzamiento. Las cuentas de desarrollador personales creadas después del 13 de noviembre de 2023 deben hacer una prueba cerrada con al menos 12 testers que sigan inscritos 14 días seguidos antes de poder publicar en producción. Una lista de espera es de donde salen esos 12.
- Las tiendas tienen sus propias herramientas previas al lanzamiento. Vale la pena usarlas junto a una lista de espera, no en su lugar. Mira la comparación de abajo.
| Item | Pedidos anticipados de la App Store o prerregistro de Play | Tu propia lista de espera |
|---|---|---|
| Necesita ficha en la tienda | Sí, aprobada y lista | No. Funciona desde el primer día de la landing page |
| Qué obtienes | Un recuento, y una notificación de la tienda o una descarga automática al publicar | El email, la plataforma y las respuestas de cada persona |
| Puede invitar testers | No | Sí, por email a TestFlight o a una prueba cerrada de Play |
| Límites | El prerregistro de Play sigue desactivado en las cuentas personales nuevas hasta que se cumple el requisito de pruebas | El email de lanzamiento lo envías tú |
Campos para una lista de espera de una app
Pregunta primero por la plataforma, porque cambia lo que significa el campo de email. El modelo de teléfono es opcional y te dice en qué dispositivos probar. La casilla de la beta separa a quienes quieren probar de quienes quieren el email de lanzamiento.
Vista previa
Ejecuta el validador de Ikiform en tu navegador. No se envía nada.
platform es obligatorio, así que cada registro cae en una lista con la que puedes actuar. Pega la definición en la pestaña Fields del formulario.El formulario
El formulario funciona como HTML sencillo en cualquier landing page. El script hace dos cosas pequeñas: preselecciona la plataforma según el navegador del visitante y muestra la indicación sobre la cuenta de Google solo a los usuarios de Android.
<form id="app-waitlist" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<fieldset>
<legend>Which phone do you use?</legend>
<label><input type="radio" name="platform" value="iphone" required> iPhone</label>
<label><input type="radio" name="platform" value="android"> Android</label>
</fieldset>
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" inputmode="email" required>
<p id="email-hint" hidden>Use the Google account you sign in to Google Play with.</p>
<label for="first_name">First name</label>
<input id="first_name" name="first_name" autocomplete="given-name" maxlength="60">
<label for="device">Phone model</label>
<input id="device" name="device" maxlength="80" placeholder="iPhone 15, Pixel 8">
<label><input type="checkbox" name="beta" value="true"> Invite me to test the app before launch</label>
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
<button>Join the waitlist</button>
</form>
<script>
const form = document.getElementById("app-waitlist");
const agent = navigator.userAgent;
const guess = /iPhone|iPad/.test(agent) ? "iphone" : /Android/.test(agent) ? "android" : null;
if (guess) form.querySelector(`[name="platform"][value="${guess}"]`).checked = true;
const hint = () => {
document.getElementById("email-hint").hidden = form.platform.value !== "android";
};
form.addEventListener("change", hint);
hint();
</script>- La suposición solo preselecciona un radio. La gente puede cambiarlo, y sin el script no hay nada seleccionado, así que
requiredles obliga a elegir. inputmode="email"yautocomplete="email"importan aquí más que en ningún otro sitio: la mayoría de los visitantes de la landing page de una app están en un teléfono.- Configura Redirect after submit con una página de agradecimiento que explique qué pasa después en cada plataforma. Para una versión del formulario con un framework, consulta la guía principal y añade estos campos.
Lleva a los testers a cada tienda
- Un usuario de iPhone que marca la casilla de la beta dispara un webhook firmado.
- Tu relay lo verifica y llama a la API de App Store Connect para añadir la dirección a un grupo de TestFlight.
- Apple envía por email la invitación de TestFlight cuando el grupo tiene una build disponible.
- Los testers de Android se recogen igual, y luego se exportan como CSV y se filtran por plataforma.
- Pegas las cuentas de Google en la lista de emails de la prueba cerrada en Play Console.
- Les envías el enlace de inscripción de la prueba desde tu herramienta de email.
iPhone: añade testers a TestFlight
En App Store Connect, crea un grupo de pruebas externas y una clave de API en Users and Access › Integrations, con el rol App Manager o Admin. Luego añade un relay que escuche el webhook submission.created de Ikiform. Este es un route handler de Next.js y usa jose para firmar el token de Apple; funciona en cualquier servidor que tenga fetch.
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { importPKCS8, SignJWT } from "jose";
async function appStoreToken() {
const key = await importPKCS8(process.env.ASC_PRIVATE_KEY!, "ES256");
return new SignJWT({})
.setProtectedHeader({ alg: "ES256", kid: process.env.ASC_KEY_ID!, typ: "JWT" })
.setIssuer(process.env.ASC_ISSUER_ID!)
.setAudience("appstoreconnect-v1")
.setIssuedAt()
.setExpirationTime("15m")
.sign(key);
}
export async function POST(request: Request) {
const payload = await request.text();
try {
const event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.IKIFORM_WEBHOOK_SECRET! });
if (event.type !== "submission.created") return new Response(null, { status: 204 });
const { email, first_name, platform, beta } = event.data.fields;
if (platform !== "iphone" || beta !== true) return new Response(null, { status: 204 });
const response = await fetch("https://api.appstoreconnect.apple.com/v1/betaTesters", {
method: "POST",
headers: { authorization: `Bearer ${await appStoreToken()}`, "content-type": "application/json" },
body: JSON.stringify({
data: {
type: "betaTesters",
attributes: { email: String(email), firstName: first_name ? String(first_name) : undefined },
relationships: { betaGroups: { data: [{ type: "betaGroups", id: process.env.ASC_BETA_GROUP_ID! }] } },
},
}),
});
if (response.ok || response.status === 409) return new Response(null, { status: 204 });
return new Response(`App Store Connect answered ${response.status}`, { status: 502 });
} catch (error) {
if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
throw error;
}
}ASC_PRIVATE_KEYes el contenido del archivo.p8que te da Apple, saltos de línea incluidos.ASC_KEY_IDyASC_ISSUER_IDestán en la misma página.- Los tokens de Apple pueden durar como máximo 20 minutos, así que el relay firma uno nuevo por cada entrega.
- Un
409significa que Apple rechazó el cambio por un conflicto, a menudo porque la dirección ya es tester. El relay lo da por hecho, así que si un tester nunca recibe la invitación, revisa el grupo en App Store Connect. Cualquier otro fallo responde502, así que Ikiform reintenta la entrega. - TestFlight permite hasta 10.000 testers externos por app. La primera build que das a un grupo externo pasa por Beta App Review, y cada build caduca a los 90 días.
Añade la URL del relay en Webhooks en Ikiform y copia el secreto whsec_ en IKIFORM_WEBHOOK_SECRET. Un espacio de trabajo puede tener 3 endpoints, así que esto puede funcionar junto a un relay que alimenta tu herramienta de email.
Android: llena una prueba cerrada
La API de publicación de Google Play gestiona los testers de las pruebas cerradas mediante Google Groups, no con direcciones sueltas, así que esta parte es una exportación semanal. Exporta la lista con Export CSV, fíltrala en una hoja de cálculo por platform = android y beta = true, y añade los emails a la lista de emails de la prueba cerrada en Test and release › Testing › Closed testing › Manage track › Testers en Play Console. Luego envía a esas personas el enlace de inscripción de la prueba desde tu herramienta de email.
Si estás cumpliendo el requisito de 12 testers, invita a más de 12. Quienes se dan de baja o nunca se inscriben no cuentan, y los 14 días necesitan 12 testers inscritos todo el tiempo.
El día del lanzamiento
Exporta toda la lista y divídela por platform. Envía a cada mitad un email con un solo enlace a la tienda. Quien eligió iPhone no necesita el enlace de Play, y un único email con dos insignias pierde toques en una pantalla pequeña. Si recogiste device, compara tus informes de fallos con los modelos que indicó la gente antes de enviar.
Comprueba que funciona
- En Allowed domains del formulario, añade el dominio de tu sitio, y
localhostmientras desarrollas. Déjalo vacío para aceptar envíos desde cualquier sitio. - Abre la página en un teléfono. La plataforma correcta está preseleccionada, y en Android aparece la indicación sobre la cuenta de Google.
- Envía como tester de iPhone. El envío muestra
platformcomoiphoneybetacomotrue. - Abre el endpoint del relay en Webhooks. La entrega muestra
succeededy la dirección aparece en tu grupo de TestFlight. - Envía como tester de Android, exporta el CSV y confirma que la fila aparece al filtrar con
platformenandroid. - Envía con el honeypot relleno,
_gotcha=bot. Sigue recibiendo una respuesta de éxito, pero el envío se guarda como spam y no manda email ni webhook.
Problemas habituales
| Problema | Qué hacer |
|---|---|
Las entregas del relay fallan con 502 y Apple respondió 401 | El token es incorrecto: revisa el id de la clave, el id del emisor y que la clave privada conservó sus saltos de línea en la variable de entorno. |
| Se añadió un tester pero no recibió el email de TestFlight | El grupo aún no tiene build, o la primera build sigue en Beta App Review. Las invitaciones salen cuando hay una build disponible para el grupo. |
| Un tester de Android no puede abrir el enlace de inscripción | La dirección de la lista no es la cuenta de Google con la que inició sesión en el teléfono. Pídele que se vuelva a registrar con esa cuenta. |
422 validation_failed | El envío no coincide con la definición de campos del formulario. error.fields indica cada campo y el motivo. Haz coincidir el name del input con el id del campo. |
| El envío está en el panel pero no llegó ningún email ni webhook | Se guardó como spam. El spam no envía nada. Ábrelo con el filtro Spam para ver los motivos y márcalo como no spam para que se envíen su email y sus webhooks. |
Preguntas
Hacen cosas distintas. Los pedidos anticipados y el prerregistro de Play necesitan una ficha aprobada en la tienda y te dan un recuento, no contactos. Una lista de espera funciona desde el primer día, te da el email y la plataforma de cada persona y te permite invitar testers.
Pídelos en tu lista de espera. Una casilla de beta y una pregunta sobre la plataforma te muestran quién tiene un teléfono Android y quiere probar. Pon sus cuentas de Google en la lista de emails de la prueba cerrada y envíales el enlace de inscripción.
No directamente. Ikiform envía un webhook firmado por cada registro, y un relay corto que despliegas tú añade la dirección a un grupo de TestFlight mediante la API de App Store Connect, como se muestra arriba.
No. Ikiform te envía emails a ti y a tu equipo, no a quien envía el formulario, así que no hay respuesta automática ni email de confirmación. Envía un webhook a tu herramienta de email y manda la confirmación desde allí.
No, no hay plan gratuito. Probar es gratis: puedes enviar 50 envíos de prueba al mes desde localhost antes de pagar. Para pasar a producción, Pro empieza en 6 $/mes por 500 envíos, o puedes pagar una sola vez 10.000 envíos por 49 $ o 50.000 envíos por 149 $, con créditos que nunca caducan.
¿Te atascaste en un paso o quieres una guía para tu caso? Escribe a hello@ikiform.com.