自転車GPSをつないで、グラベルレース中にピザを注文するよう設定した私
(steele.blue)- NebraskaのGravel Worlds Long Voyageで、補給地点のピザが売り切れる問題を避けるため、自転車GPSの位置情報でCasey'sのピザを事前注文する自動化を作成
- 仕組みは、AWS LocationのジオフェンスがGPSトラッカーの離脱を検知し、Lambdaが次の停車地点のETAに合わせてオンライン注文を実行する方式
- Casey'sには公開注文APIがないため、PlaywrightでReactベースのWebサイトをスクリーンスクレイピングし、注文結果はiPhoneとApple Watchのプッシュ通知で受け取るよう構成
- 実際のレースでは注文成功通知が来たものの、店舗には注文記録がなく、クラウドブラウザ自動化のfalse positiveが明らかに
- その後、ブラウザ動作の映像をS3に残すよう変更するとテスト注文は成功したが、Lambda環境ではローカルテストだけで安定性を確信するのは難しい
レース中にピザを確保しようとした理由
- Midwestの収穫期に、NebraskaのGravel Worlds Long Voyage自転車レースに参加
- 前年は速いライダーたちが先に到着して補給地点のCasey'sのピザをすべて持っていき、到着したときにはピザが残っていなかった
- 今年の目標は、停車時間に合わせて焼きたてのピザを事前注文することだった
- 既存のサーバーレス自転車GPSトラッカーの上に、特定のジオフェンスを離れたら注文スクリプトを実行する仕組みを追加しようとした
GPSとLambdaで注文をトリガーした方法
- 全体設計は、AWS LocationのジオフェンスがGPSトラッカーを監視する構成
- トラッカーがジオフェンスを離れるとLambda関数をトリガー
- Lambdaが次の停車地点までのETAを計算
- 計算した時刻に合わせてCasey'sのピザを注文
- Casey'sにはオンライン注文用の公開APIがないため、Webサイトのスクリーンスクレイピングを選択
- Casey'sのWebサイトはクライアント側でレンダリングされる複雑なReactアプリだった
- 一般的なスクレイパーの代わりにPlaywrightを使用
- PlaywrightをLambdaで実行する過程は、別記事にまとめられるほど厄介だった
- 注文状態を確認するため、成功または失敗時にスマートフォンとウォッチへプッシュ通知を送るよう設定
- iOSデバイスでWeb Pushを動かす設定も別記事の題材になるほどだった
成功通知とは違っていた現場の結果
- 注文トリガー用のジオフェンスはレースの180マイル地点付近に設定
- ピザは200マイル地点で受け取る計画だった
- ジオフェンスを離れると、ウォッチにピザ注文成功のプッシュ通知が届いた
- 停車地点に到着したとき、カウンターに注文はなく、店舗にも注文記録は残っていなかった
- アカウントを確認した結果、実際の注文も作成されておらず、成功通知だけが発生したfalse positiveだった
- 現場にはあらかじめ作られていたピース売りのピザが数枚あり、それを購入した
- その後、300マイルのレースを終えるまで、Lambda関数で何がうまくいかなかったのかを考え続けることになった
ログではなく動画キャプチャが手がかりを残した
- レース後にログを確認したが、失敗原因を示す情報はなかった
- ログ上では静かに成功したように見え、デバッグの手がかりが不足していた
- 数日後、Lambdaを修正してブラウザ動作を動画としてキャプチャし、S3バケットにアップロードするようにした
- 修正後の動作でテストすると注文は実際に成功し、Hawaiian pizzaを問題なく受け取れた
- 正確な原因は確定していない
- Lambdaがembedded Playwrightブラウザで最後の
form.submit()が実行された直後に処理を終了した可能性がある - オンライン注文サイトがブラウザの成功レスポンス受信を確認できず、注文を完全に処理しなかった可能性がある
- 動画処理とアップロードにかかった追加時間が、ブラウザのクリーンアップに十分な時間を与えた可能性がある
- Lambdaがembedded Playwrightブラウザで最後の
次にもう一度作るなら変えたい点
- Reactクライアントアプリをクラウドブラウザで安定してスクリーンスクレイピングすることは可能だが、非常に厄介
- もう一度作るなら、Casey'sのネイティブアプリをリバースエンジニアリングして内部APIを直接トリガーする方法を検討できる
- 地理空間の動作をシミュレーションできる良いワークフローが必要
- 最初は家の近くにジオフェンスを作ってテストした
- 夜11時に実際に外へ歩いて出てテストする方法はすぐに負担になった
- 実環境テストを減らしてはいけない
- レース前は主にローカルワークステーションで関数を実行してテストしていた
- ローカルでの成功がLambda環境でも正しく動くという誤った確信を与えた
- Casey'sのピザがなくなるのが心配なら、先行グループとの間を30分以上空けて、店舗で新しいピース売りピザを作る時間を与える方法もある
- コードはGitHubで公開されている: https://github.com/mattdsteele/spot-tracker-tracker/…
1件のコメント
Hacker News のコメント
Colin は配達しながらピザも作れる: https://youtu.be/YjyJRTM0knE?si=fes2lbRntUlciPSH
完璧に見えた計画の致命的な欠陥は、トラックが道路の段差を越えるとピザが飛び回ってトッピングを全部失ってしまうことだった: https://gizmodo.com/zume-softbank-ai-pizza-delivery-stellar-...
動画は今年 YouTube で見た中で一番大笑いした。
いまだに判断できなくて、なぜかそれで見るのがつらくなってきた。もちろん何かが大きくまずくなる動画は公開していないだろうけど。
この人が家から倉庫までトンネルを掘る動画を2時間半見てしまったけど、本当に面白いチャンネルだ。
すごくいい。pizzatool を21世紀風に解釈した感じ。
https://donhopkins.medium.com/the-story-of-sun-microsystems-...
ちなみに Tiburon の Waypoint Pizza というピザ店は、うまく頼めば San Francisco Bay の水上にも配達してくれる。Three Bridge Fiasco みたいな、あまり真剣ではない変わったヨットレースのときにはかなり役に立つ。
Dean Karnazes はテクノロジーなしで、ウルトラランニングの大会で似たようなことをしていた。
ピザをブリトーみたいに巻いて持って走ったらしい: https://gffmag.com/the-raw-endurance-of-ultramarathon-man-de...
React のウェブサイトなら、直接使えるAPIがある可能性が高いということ。
トークンを得るにはログインが必要かもしれないが、そのほうがずっと堅牢だ。
ずっと安くてずっと堅牢なのに、何か見落としているのかな?
この記事は本当にとても楽しめた。
面白い技術的問題、ピザ、「s-tier」が何を意味するのか調べさせられた点、前提だけでも笑えるのにそこへさらに加わるユーモア、最後の mea culpa とバグ原因の推測まで、良い要素が多かった。その仮説ももっともらしく見えるが、確実ではない。
現代技術の悪いところを全部集めたように感じる。
正直かなりクール。Deliveroo みたいなサービスでも似たようなことができるのか気になる。
特定の日付 X に条件が合えば、たとえば残業中に家からだいたい Z の距離まで来た時点で、あらかじめ決めておいた注文 Y を入れる、といった形でできそう。
食品の注文と決済まで、IFTTT 的なハックに簡単に組み込めるようにしない理由があるだろうか?
Casey's pizza を食べて育った思い出が良い。
中西部に戻るたびに買って食べるけど、正確に何とは言いにくいが独特の魅力がある。
ああ、結局動かなかったんですね。
200マイル地点でそれを知るのはかなりつらかっただろう。
ソフトウェア、自転車、ピザなんて、人生で好きなものばかり。
このプロジェクトと記事は本当に楽しく読めたし、似たようなアイデアも思い浮かばせてくれた。
自分ならたぶんハンズフリーで電話するか、友人に電話を頼んでメッセージでトリガーしたと思う。
それにずっと「配達」と呼んでいるけど、実際にはピックアップじゃないの?