- Para evitar el problema de que se acabara la pizza en los puntos de abastecimiento de la Gravel Worlds Long Voyage de Nebraska, creé una automatización que pedía con anticipación pizza de Casey's usando la ubicación GPS de la bicicleta
- La arquitectura usa geocercas de AWS Location para detectar cuándo el rastreador GPS sale de una zona, y Lambda ejecuta el pedido en línea según el ETA al siguiente punto de parada
- Como Casey's no tiene una API pública de pedidos, hice screen scraping del sitio web basado en React con Playwright, y configuré el resultado del pedido para recibirlo como notificaciones push en iPhone y Apple Watch
- En la carrera real llegó una notificación de pedido exitoso, pero la tienda no tenía registro del pedido, lo que reveló un falso positivo de la automatización del navegador en la nube
- Después cambié el sistema para guardar en S3 un video del comportamiento del navegador; con eso los pedidos de prueba funcionaron, pero en un entorno Lambda es difícil confiar en la estabilidad basándose solo en pruebas locales
Por qué quería asegurar pizza durante la carrera
- Participé en la carrera de ciclismo Gravel Worlds Long Voyage de Nebraska durante la temporada de cosecha en el Midwest
- El año anterior, los ciclistas más rápidos habían llegado primero y se llevaron toda la pizza de Casey's del punto de abastecimiento; cuando llegué, ya no quedaba pizza
- El objetivo de este año era pedir con anticipación pizza recién hecha para que estuviera lista durante mi parada
- Quería agregar, sobre mi rastreador GPS serverless de bicicleta existente, un mecanismo que ejecutara un script de pedido al salir de una geocerca específica
Cómo activé el pedido con GPS y Lambda
- El diseño general usa geocercas de AWS Location para monitorear el rastreador GPS
- Cuando el rastreador sale de la geocerca, se dispara una función Lambda
- Lambda calcula el ETA hasta el siguiente punto de parada
- Según el tiempo calculado, pide pizza de Casey's
- Casey's no tiene una API pública para pedidos en línea, así que opté por hacer screen scraping del sitio web
- El sitio de Casey's era una aplicación React compleja renderizada del lado del cliente
- En lugar de un scraper común, usé Playwright
- Ejecutar Playwright en Lambda fue lo suficientemente complicado como para merecer un artículo aparte
- Para verificar el estado del pedido, configuré el envío de notificaciones push al teléfono y al reloj en caso de éxito o falla
- Hacer funcionar Web Push en dispositivos iOS también daba para otro artículo
El resultado en el lugar no coincidió con la notificación de éxito
- La geocerca para disparar el pedido se configuró alrededor de la milla 180 de la carrera
- La idea era recoger la pizza en la milla 200
- Al salir de la geocerca, llegó al reloj una notificación push indicando que el pedido de pizza había sido exitoso
- Cuando llegué al punto de parada, no había ningún pedido en el mostrador ni registro del pedido en la tienda
- Al revisar la cuenta, el pedido real tampoco se había creado: solo se había producido un falso positivo de éxito
- En el lugar había algunas rebanadas de pizza ya preparadas, así que compré eso
- Después, hasta terminar la carrera de 300 millas, seguí pensando en qué había salido mal con la función Lambda
La captura en video dejó pistas en lugar de los logs
- Después de la carrera revisé los logs, pero no había información que mostrara la causa de la falla
- Según los logs, todo parecía haber tenido éxito silenciosamente, así que faltaban pistas para depurar
- Unos días después modifiqué Lambda para capturar en video el comportamiento del navegador y subirlo a un bucket de S3
- Al probar con el comportamiento modificado, el pedido sí funcionó y pude recoger una Hawaiian pizza sin problemas
- La causa exacta no se pudo confirmar
- Es posible que Lambda haya terminado el procesamiento apenas se ejecutó el último
form.submit()en el navegador Playwright embebido - Es posible que el sitio de pedidos en línea no haya podido confirmar la recepción de la respuesta exitosa del navegador y por eso no haya procesado completamente el pedido
- El tiempo adicional requerido para procesar y subir el video quizá le dio al navegador tiempo suficiente para cerrarse correctamente
- Es posible que Lambda haya terminado el procesamiento apenas se ejecutó el último
Qué cambiaría si lo volviera a hacer
- Hacer screen scraping de una app cliente en React con un navegador en la nube de forma confiable es posible, pero muy complicado
- Si lo volviera a hacer, consideraría hacer ingeniería inversa de la app nativa de Casey's y disparar directamente su API interna
- Hace falta un buen flujo de trabajo para simular comportamiento geoespacial
- Al principio hice pruebas creando una geocerca alrededor de mi casa
- Salir caminando a las 11 de la noche para probarlo en condiciones reales se vuelve pesado rápidamente
- No hay que reducir las pruebas en el entorno real
- Antes de la carrera, la mayoría de las pruebas consistieron en ejecutar la función desde mi estación de trabajo local
- El éxito local dio una falsa confianza de que también funcionaría correctamente en el entorno Lambda
- Si te preocupa que se acabe la pizza de Casey's, otra opción es sacar más de 30 minutos de ventaja al grupo delantero para darle tiempo a la tienda de preparar nuevas rebanadas
- El código está publicado en GitHub: https://github.com/mattdsteele/spot-tracker-tracker/…
1 comentarios
Opiniones de Hacker News
Colin puede entregar y también prepararte la pizza: https://youtu.be/YjyJRTM0knE?si=fes2lbRntUlciPSH
La falla fatal de un plan que parecía impecable era que, cuando el camión pasaba por baches en la calle, las pizzas salían volando y perdían todos los toppings: https://gizmodo.com/zume-softbank-ai-pizza-delivery-stellar-...
El video fue lo que más me hizo reír en YouTube este año.
Todavía no logro decidirlo, y curiosamente eso hace que me cueste verlo. Claro, supongo que no publicaría un video en el que algo salga muy mal.
Vi durante dos horas y media videos de este tipo cavando un túnel desde su casa hasta el cobertizo; es un canal realmente entretenido.
Muy bueno. Se siente como una interpretación del siglo XXI de pizzatool.
https://donhopkins.medium.com/the-story-of-sun-microsystems-...
Como dato, la pizzería Waypoint Pizza, en Tiburon, si se lo pides con amabilidad, también entrega sobre el agua en la bahía de San Francisco. Es bastante útil en carreras de yates poco serias y raras como la Three Bridge Fiasco.
Dean Karnazes hizo algo parecido en una carrera de ultrarunning, sin tecnología.
Dicen que corría llevando una pizza enrollada como burrito: https://gffmag.com/the-raw-endurance-of-ultramarathon-man-de...
Si es un sitio web en React, probablemente significa que hay una API que se puede usar directamente.
Tal vez haga falta iniciar sesión para obtener un token, pero eso sería mucho más robusto.
Es mucho más barato y mucho más robusto; ¿habrá algo que se me escapa?
Disfruté muchísimo este artículo.
Tenía muchos elementos buenos: un problema técnico interesante, pizza, que me hizo buscar qué significa “s-tier”, una premisa que ya de por sí da risa y además más humor encima, el mea culpa del final y hasta una conjetura sobre la causa del bug. Esa teoría también parece plausible, aunque no es segura.
Me dio la impresión de reunir todo lo malo de la tecnología moderna.
Sinceramente, está bastante genial. Me pregunto si se podría hacer algo parecido con servicios como Deliveroo.
Parece posible hacer que, si se cumplen ciertas condiciones en una fecha X, por ejemplo cuando estás trabajando hasta tarde y te falta aproximadamente una distancia Z para llegar a casa, se haga un pedido Y predefinido.
¿Por qué no facilitar que pedir comida y pagar se integren en hacks estilo IFTTT?
Tengo buenos recuerdos de crecer comiendo pizza de Casey's.
Cada vez que vuelvo al Medio Oeste compro una; no sabría decir exactamente qué es, pero tiene un encanto propio.
Ah, al final no funcionó.
Enterarse en la milla 200 debe haber sido bastante duro.
Software, bicicletas y pizza: cosas que me gustan de la vida.
Disfruté mucho este proyecto y el texto, y también me hizo pensar en ideas parecidas.
Yo probablemente habría hecho una llamada con manos libres, o le habría pedido a un amigo que llamara y lo activado con un mensaje.
Y siguen llamándolo “entrega”, pero en realidad ¿no es retiro en tienda?