Every couple of months, team foursquare takes a break from relentlessly shipping new features and spends a couple weeks in an engineering “fix-it." During this time, all new development stops, and instead we try to pay down our technical debt by refactoring and polishing our code, fixing pet bugs that have been bothering us, improving our test coverage, and adding logging and metrics everywhere (we're a little addicted to data).
At the end of the fix-it, when all the points have been tallied and the winners announced (yes, this is foursquare, so we make a game of it), we hold an internal Hack Day where engineers, designers and PMs from across the company get together and hack on whatever they want. It's a time to prototype out a feature that you've always wanted, to build something that no one has thought of, to mess around in a part of the code that you normally don't get to work with, or to give some application to a new library that you've been meaning to try out.
Our most recent Hack Day also happened to coincide with our last day at our old office at 36 Cooper Square in Manhattan's East Village. Hack presentations happened the next Monday at our shiny new office in SoHo. It was a nice way to say goodbye to the old office and mark the transition to our new digs.
In the next few posts we're going to highlight some interesting projects that came out of Hack Day. Our first project comes courtesy of Akshay, our platform evangelist and all-around API expert. His hack is somewhat unique in that it was built purely on top of our public API. As he explains:
Some of my favorite foursquare moments are discovering that a far flung friend is visiting or a “local" friend from across town is literally next door. Right now these discoveries are totally serendipitous, so I wanted to build a system that would alert me when a friends are much closer than normal. I decided to call it Squaredar.
Unlike most foursquare hack day participants, I'm not fluent in Scala, so Squaredar doesn't use any internal-only data or code. Instead, Squaredar just uses our public API. This is possible because our API is incredibly powerful; it's the same API the official foursquare mobile apps use.
After a person authorizes Squaredar, the app receives a real-time notification every time the user checks in. Squaredar automatically acknowledges this message and pushes the check-in object onto an AppEngine TaskQueue. This is to ensure the request from foursquare's servers doesn't time out. A separate handler picks up the task and calls /checkins/recent with the user's location. The call returns a list of recent check-ins by friends, with an additional “distance" parameter, indicating how far each friend is from the location specified in the request.
I keep a FriendDistance object for each (user, friend) pair in my database. After receiving the current list of distances, I fetch all pairs for the user and update a field tracking the friend's average distance. I also update two fields for remembering their last seen distance and time. Once I've done this, I kick off a new task to handle notifications.
The notification task re-fetches the FriendDistance objects and checks the following:
- Friend's last seen distance is at least 100 times smaller than the average distance
- Last seen distance is > 0 (no point notifying you every time you check in with a friend)
- Friend's last seen time is at least 6 hours ago
- Last time Squaredar sent an alert about this friend was over a week ago.
If any of the FriendDistance objects meet all of these criteria, Squaredar sends an e-mail to the user listing the friends who are closer than normal.
Squaredar works pretty well, but it wouldn't be a hack if there wasn't a long list of improvements I'd like to make. For example, I'd like to switch from an average distance to a moving average distance over the last X sightings, so a trip to China doesn't skew the average distance forever. I'd also like to remember if the user has checked in at the same place as the friend recently, so you don't get notified about co-workers who stepped for lunch or someone you've already caught up with. But, I'm happy with what I built over the weekend, and I can't wait for our next Hack Day!
P.S. Love hacking? We're hiring!
-Akshay Patil (@ak)