Twitter API 1.1 Get Tweets

GeekThis remains completely ad-free with zero trackers for your convenience and privacy. If you would like to support the site, please consider giving a small contribution at Buy Me a Coffee.

Twitter for a while have been pushing users to move to version 1.1 of their API. And now they are forcing you to since 1.0 has been taken down. For a lot of users this doesn’t matter since they use WordPress plugins or others of the sort. I liked using jsonp to pull tweets and not worry about it.

I put a little bit of time creating a simple PHP Twitter Library to pull your most recent tweet or tweets. This only works for Public Users and uses the Application Authorization method described below.

Setting Up Application Keys

  1. Navigate to dev.twitter.com and sign in using your Twitter Credentials.
  2. Once logged in, go to “My Applications” on the upper right side.
  3. Create a new Application. It doesn’t matter what you name it or what you use for the description. You will most likely be the only person able to view this.
  4. Take note of the “Consumer Key” and the “Consumer Secret”. Do not share these, they are similar to passwords. You will need these soon for the PHP Program.

The PHP Program

If you don’t care how this works, copy and paste the following code, and change the consumerKey and consumerSec variables to fit your applications. Save it as a PHP file, and include it in the files you need.

<?php
	class Twitter {
		private $consumerKey = "AAAAaaaaAAAAaaaaAAAA";
		private $consumerSec = "zzzzZZZZzzzzZZZZzzzzZZZZzzzzZZZZzzzzZZZZ";
		public $tweet = false;
		function __construct($username,$filename) {
			$data = @file_get_contents($filename);
			if($data === false) {
				$tweet = $this->fetchNewTweet($username);
				$this->updateSaveFile($filename,$tweet);
				$this->tweet = $tweet;
			}else{
				$data = json_decode($data);
				if($data->{"last_update"}+3600 < time()) {
					$tweet = $this->fetchNewTweet($username);
					$this->updateSaveFile($filename,$tweet);
					$this->tweet = $tweet;
				}else{
					$this->tweet = $data->{"tweet"};
				}
			}
		}
		function updateSaveFile($filename,$tweet) {
			$f = fopen($filename,'w');
			if($f == false) {
				return false;
			}
			$data = array(
				'last_update' => time(),
				'tweet' => $tweet
			);
			fwrite($f,json_encode($data));
			fclose($f);
			return true;
		}
		function fetchNewTweet($username) {
			$consumerEncoded = base64_encode($this->consumerKey.':'.$this->consumerSec);
			$bearerToken = $this->request("https://api.twitter.com/oauth2/token",'Basic',$consumerEncoded,true);
			if($bearerToken == false) {
				return false;
			}
			$tweet = $this->request("https://api.twitter.com/1.1/statuses/user_timeline.json?count=1&screen_name=".$username,'Bearer',$bearerToken);
			$tweet = json_decode($tweet);
			if($tweet == false || $tweet == null) {
				return false;
			}
			return $tweet[0];
		}
		function request($url,$authType,$authValue,$bearer=false) {
			$ch = curl_init();
			if($bearer == true) {
				curl_setopt($ch,CURLOPT_POST,1);
				curl_setopt($ch,CURLOPT_POSTFIELDS,"grant_type=client_credentials");
			}
			curl_setopt($ch,CURLOPT_URL,$url);
			curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
			curl_setopt($ch,CURLOPT_CONNECTTIMEOUT, 5);
			curl_setopt($ch,CURLOPT_USERAGENT, "Tweet Fetcher PHP 0.0.1");
			curl_setopt($ch,CURLOPT_FOLLOWLOCATION, 1);
			curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
			curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);
			curl_setopt($ch,CURLOPT_HTTPHEADER,array('Authorization: '.$authType.' '.$authValue,'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'));
			$result = curl_exec($ch);
			curl_close($ch);

			if($bearer == true) {
				$json = json_decode($result);
				if(isset($json->{'access_token'})) {
					return $json->{'access_token'};
				}
				return false;
			}
			return $result;
		}
	}
?>
<?php
	include('Twitter.php');
	$twitterUsername = "username";
	$twitterCacheFile = "../.cacheFile";
	$Twitter = new Twitter($twitterUsername,$twitterCacheFile);
	if($Twitter->tweet != false) {
?>
	<p><?php echo $Twitter->tweet->text; ?></p>
	<a href="https://www.twitter.com/<?php echo $Twitter->tweet->user->{"screen_name"}; ?>" target="_blank">@Username</a>
	<a href="https://www.twitter.com/<?php echo $Twitter->tweet->user->{"screen_name"}; ?>/status/<?php echo $Twitter->tweet->{"id_str"}; ?>" target="_blank"><?php echo date('F j, Y \a\t g:i a',strtotime($Twitter->tweet->{"created_at"})); ?></a>
<?php
	}else{
?>
	<p>Error loading tweets</p>
<?php
	}
?>

What The Code Does

  1. Checks / Creates a Cache File of the tweet. This helps prevent being rate limited and speeds up requests.
  2. If the cache is old (1 hour), it checks for a new tweet. First it requests a bearer token from “https://api.twitter.com/oauth2/token" by using Basic Authorization.
  3. Using the Bearer Token, we then request the API 1.1 User_Timeline at “https://api.twitter.com/1.1/statuses/user_timeline.json". The Bearer token is included again in the HTTP Authorization Header.
  4. The cache file is then updated with the new tweet, and the library returns the JSON data to be used for displaying the tweet or other information.

Code Breakdown

function __construct();

When the Library is created, we first check the file. If the file doesn’t exist we create a new file and start the fetching of the tweet process. If the file does exist we check the last time we updated it. If it is over 1 hour (3600 seconds) we start the fetching process. If the cache is still fresh (under 1 hour), we simply return the tweet we have stored. Not only is the tweet stored, but the full JSON data is, so in the future we can easily update displayed information.

function fetchNewTweet();

Starting with this code, we have to create a base64 encoded string to request the Bearer Token. This is done by simply concatenating the string with a colon divider. This is then used for the HTTP Header Authorization Basic. The returned value once we call the oauth/token URL, is the bearer token. This will be the method of future requests. The Bearer Token won’t change for applications unless requested. So in theory you could cache this, but I found it safer to request it using my consumer strings.

We now call for the API Request we want. This can be anything but I requested 1 tweet from the user_timeline. You would normally use oauth client tokens, but since this is a public user, it is much easier to just use the application keys. The request again uses a HTTP Authorization header, but instead of “Basic” method we use “Bearer” and the token we previously acquired. Returned will be the tweet, or other data requested.

We return the data back to the construct function where we then update the saved cache file. You could store this information to a database for cache, but this was coded for a small site that was mostly HTML. Creating a database only for tweets seemed overkill.

function updateSaveFile();

We pass the filename and tweet to the save function. We create a new array with the returned data, under tweet, and the last_update to the current time. So in the future we can check if this request is old or not. Using json_encode, we save the file as a json string.

The last function just handles the HTTP Requests using CURL. We pass a specific parameter to set up the HTTP header, url, and if we need to add special request rules.

To learn more about the Twitter API, the best spot to look at is the official http://dev.twitter.com documents. To be more specific, these following API’s that were covered in this tutorial.

Application Auth - https://dev.twitter.com/docs/auth/application-only-auth

User Timeline - https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline

Display Requirements - https://dev.twitter.com/terms/display-requirements

Related Posts

YouTube Data API Recent Uploads

Fetch recently uploaded videos to YouTube by using the YouTube Data API.