npx bitelio init
Configura los emails transaccionales desde tu repositorio con un comando — qué lee, qué escribe y qué se niega a hacer
Un comando, en la raíz de tu aplicación:
npx bitelio@latest initEl @latest importa si tu proyecto ya depende del SDK bitelio. npx prefiere una copia ya
instalada antes que descargarla, y las versiones anteriores a la 0.2.0 no traían el comando — un
npx bitelio init a secas ahí falla con el could not determine executable to run de npm, que no
explica nada. Nombrar la versión salta la copia local.
Te identifica, te da un proyecto y una clave, lee tu repositorio, propone los emails transaccionales que tu aplicación debería enviar, y abre un pull request con el código para enviarlos.
Dos cosas antes que nada.
La clave que te da es de test. Una clave de test hace todo lo que hace una real y se detiene antes del proveedor: cada envío queda registrado, ninguno se entrega. Eso es lo que permite que tu primer envío funcione en la misma sesión en vez de esperar al DNS — y es también la única forma en que esto puede morderte. Una clave de test en la configuración de producción es una aplicación que despliega, funciona, reporta éxito en cada envío y no entrega nada. Crea una clave real en Ajustes → Claves API cuando vayas a enviar de verdad.
Los proyectos nuevos esperan unas horas antes de poder enviar correo real. Los envíos de prueba están exentos, así que nada de esto se bloquea, pero un envío real desde un proyecto creado hace minutos se rechaza. El CLI te dice a qué hora se desbloquea.
Qué lee
Solo ficheros que una regla pueda justificar, y te enseña todos antes de que nada salga de tu máquina:
| Busca | Para saber |
|---|---|
package.json | tu framework, si usas Stripe, y tu comando de tests |
app/ o pages/ | qué router, que decide dónde va el código generado |
stripe.webhooks.constructEvent | tu handler de Stripe — suscripción, pago fallido, cancelación |
| una verificación de Svix | tu handler de alta — registro, verificación de email |
schema.prisma o un esquema de Drizzle | cómo se llama tu modelo de usuario |
| el árbol de ficheros, solo rutas | dónde está todo lo demás, sin leerlo |
Los handlers se encuentran por la llamada que los convierte en handlers, no por su ruta, así que da igual dónde los tengas archivados.
No se abre ningún fichero .env, se llame como se llame — ni siquiera para inspeccionarlo. Todo
lo demás pasa antes por un filtro de secretos: lo que tenga forma de clave se sustituye por
<redacted>, y la pantalla te dice cuántos se sustituyeron en cada fichero. Es una heurística y no
una garantía, y por eso puedes leer cada fichero exactamente como se enviará, y descartar el que
quieras.
Para ver todo eso y nada más, sin cuenta y sin red:
npx bitelio@latest init --dry-runQué escribe
Una rama propia, desde HEAD. Si tienes cambios sin commitear se detiene antes de hacer nada, así
que lo que produzca lo tiras con un solo comando:
git branch -D bitelio-initEjecuta tu comando de tests antes y después del parche. Una comprobación que ya fallaba sigue fallando, y el pull request lo dice en vez de culpar al cambio. Una comprobación que pasaba y ahora falla significa que el parche se deshace y te deja exactamente donde estabas. Si tu repositorio no tiene comando de tests no ejecuta nada — y lo dice bien claro en el pull request, porque verificado y sin verificar merecen confianzas distintas.
Ninguna clave va en el pull request. Solo el nombre de la variable y un marcador; la clave se imprimió una vez en tu terminal.
Si el CLI de GitHub no está instalado o no tiene sesión, la rama se queda y recibes la URL de comparación.
Cuándo se detiene
init construye tu ciclo de vida a partir de tu integración con Stripe — eso es lo que le dice
qué eventos tiene tu aplicación de verdad. Sin una dependencia stripe se detiene antes de subir
nada y lo explica, porque inventar un ciclo de vida que el código no tiene produce un pull request
que nadie puede probar.
El framework da igual. Next.js, Express, Fastify, Remix, NestJS, Hono o un servicio Node a
secas: el handler se encuentra por la llamada que lo convierte en handler,
stripe.webhooks.constructEvent, no por dónde lo hayas archivado. Reconocer tu framework solo sirve
para colocar los ficheros NUEVOS de forma idiomática — con Next distingue app/ de pages/; en el
resto sigue cómo esté organizado tu proyecto, y la pantalla de consentimiento te avisa cuando va por
convención y no por certeza.
En un monorepo te dice desde qué workspace ejecutarlo en vez de elegir uno.
Ejecutarlo desatendido
La pantalla de consentimiento necesita a una persona, así que init no sube nada desde CI.
--dry-run funciona en cualquier sitio. Para una ejecución con script en una máquina con terminal,
--project <id> elige el proyecto y --yes toma el valor por defecto donde lo hay; con varios
proyectos en la cuenta y ninguna de las dos, se niega en vez de escribir en el equivocado.
Tres ejecuciones por cuenta y día.