Bug or Feature? The Instagram vs Foursquare case
TL;DR: the Instagram Foursquare integration has a bug which allows users to checkin remotely and still get points, badges and mayorships when posting pictures.
Long version:
Roughly over one year ago at CAST 2011, I presented a lightning talk entitled “Bug or Feature: The importance of being context driven”, which explored some common bug or feature scenarios we often see here in Brazil.
My intention was to raise the awareness of our fellow testing colleagues that even though we have the power to file bug reports, we should consider the context we find ourselves (and the bugs!) in before doing so.
So, last week, I decided to post some pictures from my trip to the Yahoo! Headquarters in Sunnyvale on Instagram, adding them to my photo map and to their related Foursquare venues.
My use case was simple:
As a Instagram user
I want to be able to upload my pictures to a Foursquare venue
So that other Foursquare users can see them when they explore the venue.
Everything was cool until I received a push notification from Foursquare about a comment left by GC on my checkin at the Y! Design Studio. He was complaining that I had stolen his mayorship and wasn’t even at the Yahoo! HQ (it was Sunday and I was at the San Jose airport).
But hold on a second, I was just uploading pictures! I didn’t want to check into the venue on Foursquare.
I said it was probably a Foursquare bug because we shouldn’t be able to receive points, badges or even mayorships when uploading pictures on Instagram.
Elias jumped into my conversation with GC and brought up the “Bug or feature?” question, saying I should open a feature request.
GC said it was a bug since I was able to take the Y! Design Studio mayorship from him.
Considering that “a bug is something that bugs someone who matters”, GC and I were in sync and I decided to investigate this odd behavior.
Before we jump into conclusions, let’s dive into the Foursquare and Instagram APIs.
Instagram upload endpoint
This is a private endpoint, so I had to sniff the SSL traffic to understand how it works.
In order to reproduce the scenario, I added some pictures to the Yahoo! Brazil office.
Here is the request body (after removing my private access tokens and formatting it to improve readability):
{
"fb_access_token": "FACEBOOK_TOKEN",
"foursquare_access_token": "FOURSQUARE_TOKEN",
"flickr_access_token_key": "FLICKR_TOKEN",
"location": "{\"name\":\"Yahoo!\",\"lng\":-46.684924849648894,\"lat\":-23.595049881369359,\"foursquare_v2_id\":\"4b1e479af964a520591824e3\",\"address\":\"R. Fidêncio Ramos 195\",\"external_source\":\"foursquare\"}",
"caption": "A whole new level of @bigodines keyboards",
"geotag_enabled": true,
"filter_type": 0,
"share_to_flickr": true,
"source_type": 0,
"media_id": "330338251555385834_1222987",
"flickr_access_token_secret": "FLICKR_SECRET",
"media_latitude": -23.594667434692383,
"media_longitude": -46.68516540527344,
"share_to_facebook": true,
"fb_has_publish_actions": true,
"share_to_foursquare": true,
"device_timestamp": 1353599409
}
The response contains a Location object:
"location": {
"external_source": "foursquare",
"name": "Yahoo!",
"foursquare_v2_id": "4b1e479af964a520591824e3",
"address": "",
"lat": -23.595049881,
"pk": 333588,
"lng": -46.68492485,
"external_id": 391328
}
The coordinates on this object differ from the ones in the EXIF data (media_latitude and media_longitude) parameters, so let’s take a look at the Foursquare venue API:
Hitting the Venue endpoint returns this object, along with a lot of information:
venue: {
id: "4b1e479af964a520591824e3"
name: "Yahoo!"
contact: { }
location: {
address: "R. Fidêncio Ramos 195"
crossStreet: "12º Andar"
lat: -23.59504988136936
lng: -46.684924849648894
radius50: 43
radius90: 417
postalCode: "04551-010"
city: "São Paulo"
state: "São Paulo"
country: "Brazil"
cc: "BR"
}
Now we have the following coordinates to work with:
Sent Instagram LAT: -23.595049881369359
Sent Instagram LNG: -46.684924849648894Received Instagram LAT: -23.595049881
Received Instagram LNG: -46.68492485Media LAT: -23.594667434692383
Media LNG: -46.685165405273438Foursquare LAT: -23.59504988136936
Foursquare LNG: -46.684924849648894
It seems to me that Instagram is querying the Foursquare API for the venue’s coordinates, rounding them up (notice the slight difference) and sending them back to Foursquare to checkin AND add a picture to the checkin.
Let’s dig a little deeper and take a look at the Foursquare checkin and photo upload endpoints and see if that hypothesis is true.
Foursquare checkin endpoint
Documentation URL: https://developer.foursquare.com/docs/checkins/add
Description: “Allows you to check in to a place.”
Notes: You can’t add photos using this endpoint.
According to this post from June 2011, Foursquare pushed a change to its API which added the optional “ll” parameter to indicate the user’s real location.
Foursquare photo upload endpoint
Documentation URL: https://developer.foursquare.com/docs/photos/add
Description: “Allows users to add a new photo to a checkin, tip, venue, or page update in general. All fields are optional, but exactly one of the id fields (checkinId, tipId, venueId, pageId) must be passed in.”
Notes: Does not mention if it automatically checks in when called.
Interesting.
So, it seems that when we select to share to Foursquare (share_to_foursquare=true), it also uses the latitude (lat) and longitude (lng) parameters to checkin to Foursquare on the Instagram backend, since no checkin activity was logged on the client side.
Also, as we can see on the photo upload endpoint, Instagram could be using just the venueId to upload the picture without providing a checkinId (which proves that Instagram is checking in before uploading the picture).
Do you want further evidence? Try adding a picture to a venue through Foursquare (Explore > Search for a venue > Select a Venue > Photos > Camera Icon). You will notice that the picture will be added and you won’t checkin to the venue.
What do you think? Bug or feature?
Thanks Elias and GC for the inspiration for this post :)
Instragram has that FEATURE for those who still have to use their iPhone 3G… sometimes it is the only way to check in a venue. ;-P