Es verano en San Francisco, y cada semana la autora olvidaba participar en la lotería del Stern Grove Music Festival. La solución, por supuesto, no fue poner un recordatorio en el calendario — sino construir un script en Python que corre semanalmente vía GitHub Actions, scrapea el sitio del festival con Playwright, y se registra automáticamente en la lotería.
Lo interesante es cómo lo construyó. Describió lo que quería a un agente de codificación (con experiencia previa automatizando reservas de canchas de tenis y visualizaciones de datos), y Entire registró cada prompt, tool call y output, generando un registro completo y auditable de cómo surgió todo el proyecto.
“Lo que cualquier desarrollador razonable haría en lugar de poner un simple recordatorio: construir un bot que lo haga por ti.”
Comenzó con un solo mensaje
Todo el proyecto comenzó con un único mensaje al agente de codificación (usó Claude Code, pero cualquier agente funciona). Le entregó las reglas del juego:
La lotería de Stern Grove abre seis semanas antes de cada concierto a las 10:00 AM y permanece abierta durante una semana completa…
También le pasó el HTML exacto del botón de inscripción. Stern Grove maneja sus entradas a través de Tixologi, así que el agente necesitaba saber con qué estaba lidiando.
Luego le indicó las variables secretas que tendría disponible su GitHub Action:
- Nombre
- Ciudad
- Una API key de Resend (para notificaciones)
- Dirección de email “from”
- Código postal
Todo esto vive como secretos encriptados en GitHub Actions — nunca se suben al repositorio — y el agente entendió esa restricción desde el principio.
La arquitectura propuesta
Antes de escribir una sola línea de implementación, el agente exploró el spec, hizo una pregunta aclaratoria y propuso un diseño limpio:
lottery.py— punto de entrada, ejecutado por un cron schedule de GitHub Actionsbrowser.py— toda la lógica de Playwright: web scraping y automatización del navegadorstate.py— carga y guardaentered_lotteries.jsonpara evitar dobles inscripcionesnotify.py— emails de éxito y fallo vía Resend
La persistencia de estado fue la jugada maestra. En lugar de montar una base de datos para un trabajo que corre una vez por semana, las loterías ingresadas se rastrean en un archivo JSON que se sube de vuelta al repositorio después de cada ejecución.
Inspeccionar antes de automatizar
Antes de tocar cualquier lógica del navegador, el agente hizo una inspección en vivo de la página real de Stern Grove — específicamente window.tixologiWidget.concerts — para aprender la forma real de los datos en lugar de suponer.
Esa inspección documentó los nombres de campos precisos, el formato de fecha ISO 8601 y la estructura de IDs de eventos. Un solo console.log capturado ahorró mucho debugging después:
// Lo que la página realmente expone
window.tixologyWidget.concerts
// → [{ eventId, name, startDate: "2025-07-13T19:00:00Z", ... }]
Basar la implementación en datos reales observados en lugar de suposiciones es un diferenciador clave entre el código que funciona en la primera ejecución real y el que falla silenciosamente en producción.
Subir estado al repositorio
state.py no solo lee el JSON — después de una inscripción exitosa, hace commit y push de la actualización usando un Personal Access Token (PAT) de GitHub, para que la siguiente ejecución sepa qué ya se hizo:
def commit_state(token: str) -> None:
subprocess.run(["git", "add", "entered_lotteries.json"], check=True)
subprocess.run(["git", "commit", "-m", "Update entered lotteries"], check=True)
subprocess.run(["git", "push"], check=True)
El ciclo de revisión atrapó un bug real
Cuando el agente agregó notify.py, un agente revisor identificó inmediatamente dos problemas en el diff:
- Estaba usando
print()en lugar del módulologging. - Había duplicado la inicialización de la API key de Resend.
El agente corrigió ambos antes de pasar a la siguiente tarea. Ese ciclo tarea → revisión funcionó exactamente como debería — atrapando el tipo de descuido que normalmente solo aparece semanas después.
import logging
logger = logging.getLogger(__name__)
resend.api_key = os.environ["RESEND_API_KEY"] # inicializado una vez
def notify_success(show: str) -> None:
logger.info("Entered lottery for %s", show)
resend.Emails.send({ ... })
No funcionó al primer intento
La primera ejecución real falló. Dos problemas de entorno:
1. Deriva de versión de Ubuntu. Tuvo que fijar el runner a Ubuntu 22.04 para compatibilidad con Playwright. ubuntu-latest se había convertido silenciosamente en Ubuntu 24.04, y el paquete libasound2 fue renombrado en el proceso.
2. Dependencias de Chromium. Terminó instalando las dependencias de Chromium manualmente con los nombres correctos de paquetes de Ubuntu 24.04 en lugar de confiar en el instalador empaquetado de Playwright.
La solución pasó de esto:
# antes
- run: playwright install --with-deps chromium
a instalaciones explícitas con apt más un paso Playwright más ligero:
# después
- run: |
sudo apt-get update
sudo apt-get install -y libasound2t64 libnss3 libnspr4
- run: playwright install chromium
Stack final
El stack quedó muy bien armado:
- Playwright para la automatización del navegador
- GitHub Actions para el cron semanal y gestión de secretos
- Resend para notificaciones de éxito/fallo
- Un agente de codificación (Claude Code) para construirlo, con un ciclo de revisión que atrapó bugs reales
- Entire capturando cada prompt, tool call y output, vinculado a los commits
La próxima vez que necesites automatizar un proceso repetitivo, recuerda: no necesitas un calendario, necesitas un bot. Y con herramientas como Playwright, GitHub Actions y agentes de IA, puedes tenerlo funcionando en cuestión de horas.
¿Quieres automatizar procesos en tu negocio? Prueba las herramientas de automatización que mencionamos y acelera tus flujos de trabajo.