- Um zu vermeiden, dass an den Verpflegungsstationen beim Gravel Worlds Long Voyage in Nebraska die Pizza ausgeht, baute ich eine Automatisierung, die anhand der GPS-Position meines Fahrrads vorab Pizza bei Casey's bestellt
- Die Struktur: AWS Location-Geofencing erkennt, wenn sich der GPS-Tracker entfernt, und Lambda führt passend zur ETA des nächsten Stopps die Online-Bestellung aus
- Da Casey's keine öffentliche Bestell-API hat, nutzte ich Playwright zum Screen-Scraping der React-basierten Website; das Bestellergebnis wurde per Push-Benachrichtigung auf iPhone und Apple Watch zugestellt
- Im echten Rennen kam zwar eine Erfolgsbenachrichtigung für die Bestellung an, im Laden gab es jedoch keinen Bestelleintrag — ein false positive der Browser-Automatisierung in der Cloud
- Danach stellte ich es so um, dass ein Video der Browser-Aktionen in S3 gespeichert wird; Testbestellungen klappten dann, aber in der Lambda-Umgebung ist Zuverlässigkeit allein aus lokalen Tests schwer abzuleiten
Warum ich während des Rennens Pizza sichern wollte
- Ich nahm während der Erntesaison im Mittleren Westen am Fahrradrennen Gravel Worlds Long Voyage in Nebraska teil
- Im Vorjahr waren die schnellen Fahrer zuerst angekommen und hatten die gesamte Casey's-Pizza an der Verpflegungsstation mitgenommen; als ich ankam, war keine Pizza mehr übrig
- Das Ziel in diesem Jahr war, rechtzeitig zum Stopp frische Pizza im Voraus zu bestellen
- Auf meinen bestehenden serverlosen Fahrrad-GPS-Tracker wollte ich eine Logik aufsetzen, die beim Verlassen eines bestimmten Geofence ein Bestellskript ausführt
So wurde die Bestellung mit GPS und Lambda ausgelöst
- Das Gesamtdesign bestand aus Geofences in AWS Location, die den GPS-Tracker überwachen
- Wenn der Tracker den Geofence verlässt, wird eine Lambda-Funktion ausgelöst
- Lambda berechnet die ETA bis zur nächsten Verpflegungsstation
- Passend zu dieser berechneten Zeit wird Casey's-Pizza bestellt
- Da Casey's keine öffentliche API für Online-Bestellungen hat, fiel die Wahl auf Screen-Scraping der Website
- Die Casey's-Website war eine komplexe, clientseitig gerenderte React-App
- Statt eines gewöhnlichen Scrapers wurde Playwright verwendet
- Playwright in Lambda auszuführen war so knifflig, dass es dazu einen eigenen Beitrag geben könnte
- Um den Bestellstatus zu prüfen, wurde eingerichtet, bei Erfolg oder Fehler Push-Benachrichtigungen an Telefon und Uhr zu senden
- Auch die Einrichtung von Web Push auf iOS-Geräten wäre Stoff für einen eigenen Beitrag gewesen
Vor-Ort-Ergebnis anders als die Erfolgsbenachrichtigung
- Der Geofence zum Auslösen der Bestellung wurde in der Nähe von Meile 180 des Rennens gesetzt
- Die Pizza sollte bei Meile 200 abgeholt werden
- Sobald ich den Geofence verlassen hatte, kam auf der Uhr eine Push-Benachrichtigung über eine erfolgreiche Pizzabestellung an
- Als ich an der Verpflegungsstation ankam, gab es am Tresen keine Bestellung, und auch im Laden war kein Bestellverlauf vorhanden
- Ein Blick ins Konto zeigte ebenfalls keine tatsächlich erzeugte Bestellung — es war also nur ein false positive mit Erfolgsbenachrichtigung
- Vor Ort gab es ein paar vorbereitete Pizzastücke, die ich stattdessen kaufte
- Danach dachte ich bis zum Ende des 300-Meilen-Rennens weiter darüber nach, was in der Lambda-Funktion schiefgelaufen war
Videoaufzeichnung statt Logs lieferte Hinweise
- Nach dem Rennen sah ich die Logs durch, fand dort aber keine Informationen zur Fehlerursache
- Den Logs zufolge hatte alles still und leise erfolgreich ausgesehen, daher gab es kaum Ansatzpunkte fürs Debugging
- Einige Tage später änderte ich Lambda so, dass die Browser-Aktionen als Video aufgezeichnet und in einen S3-Bucket hochgeladen werden
- Beim Test mit der angepassten Version funktionierte die Bestellung tatsächlich, und eine Hawaiian pizza konnte regulär abgeholt werden
- Die genaue Ursache ist nicht geklärt
- Möglicherweise beendete Lambda die Verarbeitung, sobald im eingebetteten Playwright-Browser das letzte
form.submit()ausgeführt wurde - Möglicherweise konnte die Online-Bestellseite nicht bestätigen, dass der Browser die Erfolgsmeldung empfangen hatte, sodass die Bestellung nicht vollständig verarbeitet wurde
- Die zusätzliche Zeit für Videoverarbeitung und Upload könnte dem Browser genug Zeit zum Aufräumen gegeben haben
- Möglicherweise beendete Lambda die Verarbeitung, sobald im eingebetteten Playwright-Browser das letzte
Was ich beim nächsten Mal ändern würde
- Eine React-Client-App per Cloud-Browser zuverlässig zu screen-scrapen ist möglich, aber sehr knifflig
- Wenn ich es noch einmal bauen würde, käme in Frage, die native Casey's-App zu reverse engineeren und direkt ihre interne API auszulösen
- Es braucht einen guten Workflow, um georäumliche Abläufe zu simulieren
- Zuerst testete ich mit einem Geofence in der Nähe meines Hauses
- Um 23 Uhr tatsächlich nach draußen zu gehen und zu testen, wurde schnell lästig
- Tests in der realen Umgebung dürfen nicht vernachlässigt werden
- Vor dem Rennen testete ich die Funktion meist lokal auf meiner Workstation
- Das vermittelte die falsche Sicherheit, dass lokaler Erfolg auch in der Lambda-Umgebung korrekt funktioniert
- Wenn man befürchtet, dass Casey's-Pizza ausverkauft ist, kann man auch versuchen, mehr als 30 Minuten Abstand zur Spitzengruppe zu haben, damit der Laden Zeit hat, neue Stücke vorzubereiten
- Der Code ist auf GitHub veröffentlicht: https://github.com/mattdsteele/spot-tracker-tracker/…
1 Kommentare
Hacker-News-Kommentare
Colin kann während der Lieferung auch Pizza machen: https://youtu.be/YjyJRTM0knE?si=fes2lbRntUlciPSH
Der fatale Fehler des scheinbar wasserdichten Plans war, dass die Pizza herumflog und alle Beläge verlor, wenn der Truck über Bodenwellen fuhr: https://gizmodo.com/zume-softbank-ai-pizza-delivery-stellar-...
Das Video hat mich dieses Jahr auf YouTube am meisten zum Lachen gebracht.
Ich kann das immer noch nicht einschätzen, und seltsamerweise macht es das schwerer anzusehen. Natürlich würde er wohl kein Video veröffentlichen, in dem etwas richtig schiefgeht.
Ich habe zweieinhalb Stunden lang zugesehen, wie dieser Typ einen Tunnel von seinem Haus bis zum Schuppen gräbt; ein wirklich unterhaltsamer Kanal.
Sehr gut. Fühlt sich an wie eine Interpretation von pizzatool fürs 21. Jahrhundert.
https://donhopkins.medium.com/the-story-of-sun-microsystems-...
Nebenbei: Die Pizzeria Waypoint Pizza in Tiburon liefert, wenn man nett fragt, auch aufs Wasser der San Francisco Bay. Das ist ziemlich praktisch bei weniger ernst gemeinten, skurrilen Yachtregatten wie dem Three Bridge Fiasco.
Dean Karnazes hat bei einem Ultralauf etwas Ähnliches ohne Technik gemacht.
Er soll die Pizza wie einen Burrito zusammengerollt getragen haben: https://gffmag.com/the-raw-endurance-of-ultramarathon-man-de...
Wenn es eine React-Website ist, heißt das wahrscheinlich, dass es eine API gibt, die man direkt nutzen kann.
Zum Abrufen des Tokens muss man sich vielleicht einloggen, aber das wäre deutlich robuster.
Das ist viel günstiger und viel robuster; übersehe ich da etwas?
Ich hatte wirklich viel Spaß an diesem Beitrag.
Ein interessantes technisches Problem, Pizza, der Umstand, dass ich nachschlagen musste, was „s-tier“ bedeutet, die schon für sich lustige Prämisse plus zusätzlicher Humor, und am Ende noch das Mea culpa samt Vermutung zur Bug-Ursache — da war viel Gutes dabei. Die Theorie wirkt auch plausibel, aber sicher ist sie nicht.
Es fühlte sich an wie eine Sammlung von allem, was an moderner Technik schlecht ist.
Ehrlich gesagt ziemlich cool. Ich frage mich, ob man etwas Ähnliches auch mit Diensten wie Deliveroo machen könnte.
An einem bestimmten Datum X, wenn die Bedingungen passen, etwa wenn man Überstunden macht und noch ungefähr Z Entfernung von zu Hause entfernt ist, automatisch eine vorher festgelegte Bestellung Y aufgeben — das scheint machbar.
Warum sollte man es nicht leicht machen, Essensbestellungen und Bezahlung in IFTTT-artige Hacks zu integrieren?
Ich habe gute Erinnerungen daran, mit Casey's Pizza aufzuwachsen.
Immer wenn ich in den Mittleren Westen zurückkomme, esse ich sie; ich kann nicht genau sagen, was es ist, aber sie hat einen eigenen Charme.
Ah, am Ende hat es also nicht funktioniert.
Das bei Meile 200 herauszufinden, muss ziemlich hart gewesen sein.
Software, Fahrräder und Pizza — das sind Dinge, die ich im Leben mag.
Dieses Projekt und den Artikel fand ich wirklich unterhaltsam, und sie haben mich auch auf ähnliche Ideen gebracht.
Ich hätte wahrscheinlich einfach freihändig angerufen oder einen Freund gebeten anzurufen und das per Nachricht ausgelöst.
Außerdem wird es ständig „Lieferung“ genannt, aber eigentlich ist es doch Abholung, oder?