Foursquare API Automated Check ins

Automated Check-ins to steal Mayorships

I moved from Berlin to Dubai a little over a year ago. There can be little doubt that it is certainly one of the most impressive and awe-inspiring cities in the world. A city with incredible architecture wherever you look, from the world’s tallest building, to the world’s largest shopping mall, and more.

In comparison with Europe and North America the usage of Foursquare in the Middle East is much lower. This means that obtaining the mayorship of a popular venue or famous landmark is much easier than elsewhere.
Easier still if we can automate it…

By using the Foursquare API we can put together a little app to automatically check in a user at roughly the same time each day.

The key trick here is making the check-ins seem like a genuine user check-in, rather than an automated bot.
To do this we have to think of some ways to get around the footprints that an automated process would generate, such as the routine action of running the code on a cron job.

To get around this I decided to run the code each time the website loads a page, running the check-ins in specified time. This has the effect of randomising the check-in time depending on when a page of the website is requested by a visitor.

Step 1: Create a (new) Foursquare Account

If you already have a Foursquare account you can choose to use that, or create a new account specifically for this.
I chose to create a new account to prevent my real account getting banned, though that’s probably likely now I write this post.

Step 2: Identify the targets and times

First we need to identify the locations in which we want to obtain the mayorships.
A couple of things to bear in mind are:

  • The places must be within travelling distance of each other (round trip) in 24 hours.
  • The number of venues must be few enough in number that they could all be visited in a 24 hour round trip.

For me the list of venues was as follows:
All times GMT

  • 01:00 – Dubai International Airport (on 4sq)
  • 07:00(1) – Dubai Mall (on 4sq)
  • 07:00(2) – The Dubai Fountain (on 4sq)
  • 07:00(3) – Burj Khalifa (on 4sq)
  • 09:00 – Palm Jumeirah (on 4sq)
  • 10:00 – Atlantis the Palm (on 4sq)
  • 12:00(1) – Dubai Marina (on 4sq)
  • 12:00(2) – Dubai Marina Walk (on 4sq)
  • 17:00 – Mall of the Emirates (on 4sq)
  • 18:00- Mindshare (on 4sq)
  • 20:00 – Business Central Towers (on 4sq)
  • 22:00 – Burj al Arab (on 4sq)

Step 3: Create a Foursquare App

I won’t repeat myself here, so check out my previous post: how to create a Foursquare App.
Be sure to keep note of the “Client ID” and “Secret ID”

Also, a very important step here is to make sure you authorise your new app with the account you intend to use for the check-ins.

Take note of the Access token that you generate when authenticating the user in your app.
This access token is the cornerstone to making the app work!

Step 4: Create a MySQL Database

Set up a MySQL database on your hosting.
A simple Database, it needs only one table with two columns: “ID” and “stamp”
We will use this to record the time of the last successful check-in and prevent multiple check-ins from occurring each time the code runs in the specified time-frame.

Step 5: Code the app

Firstly let’s work out the API call to make a check in at a location.
In this example we will use “Burj al Arab”

First we need a couple of pieces of information:

  • 4sq venue ID for the location
  • Approximate Longitude and Latitude of the venue

The Venue ID we can get from the webpage of the venue on Foursquare.
In this case the URL for the Burj al Arab is: https://foursquare.com/v/burj-al-arab-%D8%A8%D8%B1%D8%AC-%D8%A7%D9%84%D8%B9%D8%B1%D8%A8/4bebf8d661aca593759c8500
Simple.

Burj al Arab Coordinates

Burj al Arab Coordinates

To get the approximate Longitude and Latitude, we can simply look up the building on Wikipedia: http://en.wikipedia.org/wiki/Burj_Al_Arab
On the right hand column, you will see the coordinates.
We only need to be approximate with these, so giving the Longitude and Latitude to 4-5 decimal places is fine.
In this case: “25.141975, 55.186147″

To further make the check ins look more natural, one could very simply throw in a random number generator here and randomly generate the last couple of decimal places in the Longitude/Latitude, as each figures is 10x less important than the previous, the final few numbers are not important.

Now we have the 3 key items required to process a check in via an API call:

  • User Authentication token
  • Venue ID
  • Longitude/Latitude Coordinates

Let’s put this together into an API call:

 
	//Burj al Arab
 
	//Set the Venue name, just because...
	$venue = "Burj al Arab";
 
	//Assign the Venue ID to a string $vid
		$vid = "4bebf8d661aca593759c8500";
 
	//Assign the Long/Lat coordinates to a string $llid
		$llid = "25.141975, 55.186147";
 
	//Build the API Call
	//llacc is the Long/Lat accuracy, here we say within 200meters... Pretty sure this does fuck all.
	//v is the API version, use the number 20130327, or whatever the newest version is.
$url = 'https://api.foursquare.com/v2/checkins/add';
$data = array('venueId' => $vid , 'll' => $llid , 'llAcc' => '200', 'oauth_token' => '**********ACCESS TOKEN FROM API AUTHENTICATION*********', 'v' => '20130327');
 
//Here we process the API call. Pretty sure some magic happens here:
 
// use key 'http' even if you send the request to https://...
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data),
    ),
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$obj = json_decode($result, true);
 
//Api call made, result processed.
 
//All thing being equal, check in should be processed.
//Output a string to happily assert this:
echo "Checked in at Burj al Arab";

There we are.

Now this is all well and good, but every time this code runs, you will be checked in at the venue.
At the time of writing, this blog received 1,585 page requests yesterday. This would mean we check in to the same location 1,585 times/day.

Clearly we need to limit the check ins to once per day, with some room for variance in the check in time.
For this we will check the current time and use this to regulate when to process the check in.

We will then use the MySQL to check how long ago the last successful check in was made, and if it was>22 hours ago, process the check in

First thing’s first, Connect to the SQL Database right at the top of the code for this app:

mysql_connect("localhost", "*****Username*****", "*****Password*****") or die(mysql_error());
mysql_select_db("*****MySQL Database*****") or die(mysql_error());
$result = mysql_query("SELECT * FROM `*****Table*****`") or die(mysql_error());

You should probably remember to close the SQL connection at the end of the file. PHP5 takes care of it for you, but it’s bad form.

Next up we need to get the current time.
We need this in two formats:

  • Unix timestamp
  • Current Hour

Get these and assign them to variables, thusly:

$times = time();
$time = date(H);

Now let’s use the single example of Burj al Arab and say we want to check in at 22:00GMT each day.
We need to do the following steps:

Check if the hour is 22.
If it is, check if the last check in was over 22 hours ago.
If it is, process the check in.

If not, do not process the check in.

Using the assigned time variables above:

if ($time >= 22){
	//Burj al Arab
	$venue = "Burj al Arab";
			$vid = "4bebf8d661aca593759c8500";
		$llid = "25.141975, 55.186147";
 
 
// Query the SQL database for the ID we choose for this venue.
//In this case I assigned the ID 2 to this venue
$result = mysql_query("SELECT * FROM `check` WHERE ID='2'");
while($row = mysql_fetch_array($result))
  {
 
//Pull out the "stamp" column of the MySQL row with the ID 2
//Assign this to a variable so we can run a check against it to see if it was last updated >22 hours ago
  $checknow = $row['stamp'];
  }
 
//Take the current UNIX timestamp and deduct 79200 seconds (22 hours) to give the figure the last check in must be less than in order to process the check in
  $datetochek = $times - 79200;
 
//Check the current time-22hours against the last check in
//If the last check in IS more than 22 hours ago, process the check in!
 
if ($checknow < $datetochek){
$url = 'https://api.foursquare.com/v2/checkins/add';
$data = array('venueId' => $vid , 'll' => $llid , 'llAcc' => '200', 'oauth_token' => '**********ACCESS TOKEN FROM API AUTHENTICATION*********', 'v' => '20130327');
 
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data),
    ),
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$obj = json_decode($result, true);
 
 
//Update the MySQL table to update the "stamp" column of the SQL row with the ID 2 with the current time.
// This ensures the next check in won’t be until at least 22 hours form now.
 
mysql_query("UPDATE `check` SET stamp='$times' WHERE ID='2'") 
or die(mysql_error()); 
 
//Output a little signal to show the check in was processed
echo "Checked in at Burj al Arab";
}

Now all we have to do is set up the chosen venues in reverse chronological order with “if elseif” statements:

if ($time >= 22){
//Burj al Arab check in
}
elseif($time >= 20){
//Business Central Towers check in
}

You can even stagger multiple locations to go off in sequence at the same hour.

For example Dubai Mall, Dubai Fountains, and Burj Khalifa are all at the same location.
It makes sense that one might check into them at the same time (sort of).

We simply have to add a further logic check to see if the previous location has been checked into, if so move on to the next.

if($time >=12){
//Dubai Mall ID=12
 
$result = mysql_query("SELECT * FROM `check` WHERE ID='12'");
		while($row = mysql_fetch_array($result))
  {
  $checknow = $row['stamp'];
  }
  $datetochek = $times - 79200;
if ($checknow < $datetochek){
//Process Dubai Mall check in
}
else{
//Burj Khalifa ID=13
$result = mysql_query("SELECT * FROM `check` WHERE ID='13'");
		while($row = mysql_fetch_array($result))
  {
  $checknow = $row['stamp'];
  }
  $datetochek = $times - 79200;
if ($checknow < $datetochek){
//Process Burj Khalifa check in
}
}
}

In this case, the first time the code fires after 12:00 GMT the check in for Dubai Mall will be processed.
The next time the code fires, the check in for Burj Khalifa will be processed.

Depending on the volume of page requests, there may be a few seconds/minutes/hours between the two requests.

Finally it’s a good idea to add a little output at the bottom of the code to ensure it has executed correctly.

For me the final code looked something like this:

mysql_connect("localhost", "*****Username*****", "*****Password*****") or die(mysql_error());
mysql_select_db("*****MySQL Database*****") or die(mysql_error());
$result = mysql_query("SELECT * FROM `*****Table*****`") or die(mysql_error());
 
$times = time();
$time = date(H);
 
if ($time >= 22){
//Burj al Arab check in
echo "^^";
}
elseif($time >= 20){
//Business Central Towers check in
echo "^^";
}
elseif($time >=12){
//Dubai Mall ID=12
 
$result = mysql_query("SELECT * FROM `check` WHERE ID='12'");
		while($row = mysql_fetch_array($result))
  {
  $checknow = $row['stamp'];
  }
  $datetochek = $times - 79200;
if ($checknow < $datetochek){
//Process Dubai Mall check in
echo "^^";
}
else{
//Burj Khalifa ID=13
$result = mysql_query("SELECT * FROM `check` WHERE ID='13'");
		while($row = mysql_fetch_array($result))
  {
  $checknow = $row['stamp'];
  }
  $datetochek = $times - 79200;
if ($checknow < $datetochek){
//Process Burj Khalifa check in
echo "^^";
}
}
}
echo ":)";

I embedded this into the sidebar of my blog, right at the end of the small map form my check in app.

Any time the code runs, you will see a “:)” in the sidebar.

Any time the code runs and happens to trigger a check in, you will see “^^:)” in the sidebar.

Apologies for ousting: @BachirZ as mayor of Mindshare. I stopped checking in there and @fitzyRichard has the mayorship back.

But he uses an app to automate his check ins.

And that’s cheating if you ask me ;)