Author David O
Posted July 7, 2013 10:13 am
Skill Level
Duration

Twitter API 1.1 Get Tweets

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 http://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.

twitter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?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;
      }
   }
?>
ShowTweets.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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

Did you like this post? Leave feedback or ask questions in the comment section below. Also don't forget to share this post with your friends by using the social icons to the right.

Comments

Alyssa November 22, 2013 2:50 pm

I am still having some trouble being able to display more than one tweet at time. I changed the ?count=10 since I would like to grab the 10 most recent tweets but I can still only see one tweet. You said we have to loop through the array for each tweet? I would greatly appreciate it if you could provide a code example that corresponds with your implementation. Thank you!

David O November 22, 2013 5:32 pm

Hello, I will update the tutorial for multiple tweets later. But for now, in the function fetchNewTweet make sure you return $tweet and not $tweet[0]. Then after you setup $Twitter, $Twitter->tweet will be an array of the last n tweets you specified in the URL. So you can do a simple foreach($Twitter->tweet as $tweet) { } loop, and then the variable $tweet will be a single tweet you can reference.

Natali October 16, 2013 3:21 am

iv'e tried to use to code above but im getting this error:
Fatal error: Call to undefined function curl_init() in /srv/disk8/1528553/www/natalipolishuk.co.nf/Twitter.php on line 50

why is that ?

David O October 16, 2013 7:55 am

Make sure that you have PHP Curl enabled. You will have to modify the php.ini file and enable the extension.

Shaukat Hayder September 20, 2013 9:26 am

How can I 3-4 last tweets with the program posted in here?

David O September 20, 2013 10:26 am

On line 42 of the twitter.php file, you will want to change the url parameter ?count=1 to the number of tweets you wish to fetch. I believe there is a limit of 50 or so. You will then have to loop through the returned array for each tweet.

EQPaisley September 18, 2013 1:51 pm

Hi there. Is there a way to POST tweets via PHP? Also, is there a way to use ONE set of tokens/access keys and POST or RETWEET from multiple accounts?

David O September 19, 2013 5:53 am

Posting Tweets are possible, but the method above is for only gathering tweets, the authorization method is completely different. Have a look at "Application-user authentication" and POST "statuses/update" on the Twitter Developer website.

Alex September 12, 2013 6:46 pm

Hi.

I fount your post because I'm looking for the Bearer Token. The truth is I have no idea of php nor web development, although I can read the code and get the idea (I know a little of c and java).

My dump request is if there is a way to use your twitter.php in order to get the Bearer Token and prompt it to me or something like that. I understand at the end of the class you return it, but I don't know how to see it from anywhere else. (Don't know where to include it and then prompt/print/send it). Could you give some directions?

I'm sorry the very novice question.

Thanks.

David O September 12, 2013 8:20 pm

In the function "fetchNewTweet()" before the return of tweet[0], just do "echo $bearerToken;". This should print the token to the webpage just so you can get it.

Alex September 13, 2013 10:00 am

Thanks. I got it. I have my bearer Token.

Write a Comment

October 30, 2014 11:09 am
Notify me when someone replies.