Creating an RSS feed for your Twitter home page

Updated to use v1.1 of the Twitter API on 2-Mar-2013. See comments below for notes on updating.
I used to read my twitter feed (the tweets you see on your Twitter home page) in an RSS reader, but when Twitter stopped providing that feed I was unable to do so. There are still some feeds supported until March 2013 but they show just your own tweets, tweets from a particular user or for a particular hash tag. e.g.

https://api.twitter.com/1/statuses/user_timeline.rss?screen_name=username

To get RSS reading back again I decided to create my own feed and you can do the same. I made heavy use of Adam Green’s code from 140dev.com and he in turn uses Matt Harris’ OAuth library from https://github.com/themattharris/tmhOAuth.

You will need web hosting that supports PHP and you can down load the files I used here (twitter-v1.1.zip updated 2-Mar-2013) and extract them to your computer.

You will also need to get some access keys from Twitter so go to https://dev.twitter.com/apps (you will need to log in with your Twitter name and password).

Click on the create a new application button then provide a name, description and a URL for the application (the URL is just where people can find out about your code – in my case it’s the blog page you’re reading).

The Callback URL is not required in this case. But if you want you can give the URL where your feed is going to be for example http://www.mywebsite.com/twitter/rss.php

Accept the terms and complete the captcha and you will be taken to the settings pages for your application.

Go to the settings tab and select Read only as the application type and update the settings.

Go back to the details tab and click the “create my access token” button at the bottom.

You will now have a page with a number of codes, you will need to copy the values for

  • Consumer key
  • Consumer secret
  • Access token
  • Access token secret

Now go to the files you downloaded, find the keys folder and in that folder is a file called personal_keys.php. Open it and edit it replacing the dummy values with the ones you copied above.

Also replace the entries in the personal_keys.php file for the domain where you will be hosting the feed. (Thanks to Terry for pointing out my earlier errors.)

Now simply upload the entire folder to your web site and test the feed by entering the appropriate URL into a browser e.g.

http://www.mysite.com/twitter.rss.php

Note, the feed is not secure and anyone with the URL can read the feed. It would be possible to have a password protected feed if you wanted to do some extra work but as tweets are public anyway I decided it wasn’t necessary for my purposes.

If you wanted something other than the home timeline you can change the URL you use to request data in the rss.php file.

$code = $tmhOAuth->request(
        	'GET', 
			$tmhOAuth->url('1/statuses/home_timeline'), 
			array(
          		'include_entities' => true,
    			'count' => 50,
        	)
        );

See https://dev.twitter.com/docs/api/1.1 for other options.

71 thoughts on “Creating an RSS feed for your Twitter home page

  1. Firstly, many thanks for posting this.

    I did however have a problem setting it up. I solved it by changing the Oauth object as follows:
    // create the OAuth object
    $tmhOAuth = new tmhOAuth(array(
    'consumer_key' => $my_consumer_key,
    'consumer_secret' => $my_consumer_secret,
    'user_token' => $my_access_token,
    'user_secret' => $my_access_token_secret,
    'curl_ssl_verifypeer' => false
    ));

    The user_token and user_secret weren’t being set correctly.

    I also noticed that “Fogcat” was hardcoded so that it appeared in the rss feed, regardless of the actual user. While this didn’t seem to cause a problem I removed it by replacing both occurences with:

    Thanks again and I hope the above will help others who may hit the same problem.

  2. Thanks for posting this Geoff. Very useful information. I have a number of users who have emailed about the loss of the RSS feeds from the URL’s that my application generates for them as March rolls around. I will point them over to your post. I seem to recall that Twitter had a restriction against re-syndication of the new API that I came across somewhere in their documentation or blog posts. Do you happen to know if this approach falls within their current terms?

  3. To be honest I have no idea about how it interacts with their current terms. I only did it so I could continue to read my Twitter stream in my RSS reader of which I’m likely to be the only subscriber. So I regarded as for personal use only.

    I don’t really see how it’s any different from embedding tweets in a web page, but I might have to have a read of the terms.

  4. I found this at https://dev.twitter.com/terms/api-terms

    4. You will not attempt or encourage others to:

    • sell, rent, lease, sublicense, redistribute, or syndicate access to the Twitter API or Twitter Content to any third party without prior written approval from Twitter.
    • If you provide an API that returns Twitter data, you may only return IDs (including tweet IDs and user IDs).
    • You may export or extract non-programmatic, GUI-driven Twitter Content as a PDF or spreadsheet by using “save as” or similar functionality. Exporting Twitter Content to a datastore as a service or other cloud based service, however, is not permitted.

    So as I’m not providing an API (you can’t call RSS an API) I think it’s fine.

  5. Well an RSS feed is just an XML file and it’s designed for use by a feed reader rather than a human. Normally a browser will make a successful attempt and converting an XML RSS feed into something readable. What are you using to look at the feed?

  6. Doesn’t the code in the zip file use the API version that they are going to shut down? Shouldn’t it use version 1.1? Or what am I missing?

  7. I’ve updated the files to make sure they use the v1.1 API and I’ve included the latest copy of the OAuth library that was available at the time of the update.

    If you’ve already used the files you should upload all the files in the new zip except personal_keys.php. Replacing any existing ones.

    You also no longer need to include your twitter name in the personal keys file.

  8. Is it possible to retrieve another user’s public tweets using this script? I’ve tried replacing home_timeline with user_timeline?user_id=12345&count=5 but only my own timeline shows up.

    Thanks.

    • Ah! Figured it out just after I posted that last comment. It should be like:

      $code = $tmhOAuth->request(
      'GET',
      $tmhOAuth->url('1.1/statuses/user_timeline.json'),
      array(
      'include_entities' => true,
      'count' => 5,
      'user_id' =>12345,
      )
      );

      To get the tweets of another user ID.

  9. Hi, great article. I have been trying to get this to work for search hashtags without success. Could someone be so kind as to let me know what the code should change to for a search hashtag feed? Thanks.

  10. Hello me again,

    The code is still working fine and my RSS feed poster is posting the results to a sub-forum of mine. What I wanted to ask is there a limit or some sort of block stopping my RSS feed poster from posting tweets every 60 minutes?

    I have setup the poster so that it should post a new tweet every 60 minutes but it seems to only pick one out every.. week?

    Many thanks

    • I’m not sure I understand what you mean by “RSS feed poster”. Is this a variant of the code that makes a new tweet for you?

    • hash_hmac seems to be used by the tmhOAuth package and should be part of PHP versions 5.1.2 and above).

      http://php.net/manual/en/function.hash-hmac.php

      I don’t know anything about the Google App Engine but it looks like their version of PHP doesn’t support it for some reason. What version of PHP does the GAE provide?

      If it’s lower this page says it provides a version of hash_hmac for PHP 4

      http://www.ulrichmierendorff.com/software/aws_hmac_signer.html

      • Ahh just checked your link and it seems Quercus is a Java implementation of PHP so it probably doesn’t support all PHP functions. You could try implementing your own version of the function – maybe the code I linked to will help.

        • Hi Admin

          Thank you very much for your response.

          Yes you’re right. Quercus, a Java implementation of PHP is not supporting the function hash_hmac.

          I’m not good at PHP, so couldn’t fix it despite of your suggestions.

          Ok No problem, the code is working fine when hosted on a different php hosting service.

          And many thanks to you for this very useful post.

          Cheers
          Bob

          • You could try adding the php files in this zip file to the same directory as the rss.php file and add the line

            include("php4_hmac.php");

            after the requires at the top of rss.php.

            I’ve not tested it – so no promises.

  11. Has anyone used the above code to get “list” statuses? I can get the home timeline to work ok, but can’t get lists to work. I keep getting this error: “You must specify either a list ID or a slug and owner,” even though I provide the requested info. Here’s a snippet of what I modified in the RSS file:

    $code = $tmhOAuth->request(
    'GET',
    //$tmhOAuth->url('1.1/statuses/home_timeline'),
    $tmhOAuth->url('1.1/lists/statuses.json?slug=mylistslugname&owner_screen_name=myscreenname'),

    ….I’ve obviously replaced “mylistslugname” and “myscreenname” with the appropriate values, but it still doesn’t work. Also, I’ve tried passing the “list_id” name/value, but that still gives me the same error message. Wondering if it’s my code, or if lists are just borked right now. Thanks.

  12. Have you tried

    $code = $tmhOAuth->request(
    'GET',
    $tmhOAuth->url('1.1/lists/statuses'),
    array(
    'slug' => 'mylistslugname',
    'owner_screen_name'='myscreenname',
    )
    );

    • That worked! Thanks so much Geoff…your tutorial and extra help are much appreciated (esp. since there isn’t any documentation on a lot of this stuff). Well, nothing that an avg Joe like myself can decipher anyways. Cheers!

  13. It seems that twitter have disconnected the RSS today. I have uploaded the code and configured as suggested and it all works fine. Thank you very much Geoff.

    Any idea how to configure it just to get my own posts and not everyone that I follow?

  14. Hi. Thanks for share all this! If you don’t mind, I will link this post from my blog in a new article trying to explain how to create your own Twitter’s feed NOW (in spanish). But, its your code, so I want people know that it is your work and I’m only the messenger. Mine it is not a plain translation, but still depends on your development. Is this OK?

    BTW, I used it to get my favorites… In that case, “$tmhOAuth->url(‘1/statuses/home_timeline’),” must be “$tmhOAuth->url(‘1.1/favorites/list’),”

    🙂

  15. Hello,

    I am very green to coding. Dumb question, but, is this available in a quartz composer overlay (via RSS feed). Or is that impossible to get a twitter RSS feed through QC with API v1.1????

    • Sorry, I’d never heard of Quartz Composer until I just Googled it. It’s some sort of music program for Macs? So no I don’t think it would work with that.

  16. Geoff, would you mind contacting me at my email address in this post? I am developing an open source version of the old Twitter user timeline, favorites, mentions, and search feeds that I would like to place on GitHub. I’d like to include some of your code and wanted to see if you are interested in collaborating on the project and what type of licensing you have applied to the home timeline code that you developed here.

    Thanks much,
    Chris

  17. Pingback: Crear RSS de Twitter para Api 1.1 | Salinasjavi's Blog

  18. Hello! Thanks for your app. I tweaked it a bit so that if you add the parameter ?name=sometwitterusername
    it will show that user’s stream instead of yours.
    Maybe you want to integrate it in the original since it doesn’t change the original behavior and just adds new features.

    Instead of

    $userInfoObj = json_decode($tmhOAuth->response['response']);
    //tmhUtilities::pr($userInfoObj);

    // extract certain info about the user
    $twitterName = $userInfoObj->screen_name;
    $fullName = $userInfoObj->name;
    $twitterAvatarUrl = $userInfoObj->profile_image_url;
    $feedTitle = $twitterName . ' Twitter ' . $twitterName . 'Timeline';

    // request the home time line - the last 50 item
    $code = $tmhOAuth->request(
    'GET',
    $tmhOAuth->url('1.1/statuses/home_timeline'),
    array(
    'include_entities' => true,
    'count' => 50,
    )
    );

    The code now contains

    if ($_GET["name"]) {
    $code = $tmhOAuth->request(
    'GET',
    $tmhOAuth->url('/1.1/users/show.json'),
    array(
    'screen_name' => $_GET["name"],
    )
    );
    if ($code 200) {
    tmhUtilities::pr($tmhOAuth->response['response']);
    die("users_show connection failure");
    }
    $userInfoObj = json_decode($tmhOAuth->response['response']);
    //tmhUtilities::pr($userInfoObj);

    // extract certain info about the user
    $twitterName = $userInfoObj->screen_name;
    $fullName = $userInfoObj->name;
    $twitterAvatarUrl = $userInfoObj->profile_image_url;
    $feedTitle = $twitterName . ' Twitter ' . $twitterName . 'Timeline';

    $code = $tmhOAuth->request(
    'GET',
    $tmhOAuth->url('/1.1/statuses/user_timeline.json'),
    array(
    'screen_name' => $_GET["name"],
    'include_entities' => false,
    'skip_status' => true,
    )
    );
    } else {
    $userInfoObj = json_decode($tmhOAuth->response['response']);
    //tmhUtilities::pr($userInfoObj);

    // extract certain info about the user
    $twitterName = $userInfoObj->screen_name;
    $fullName = $userInfoObj->name;
    $twitterAvatarUrl = $userInfoObj->profile_image_url;
    $feedTitle = $twitterName . ' Twitter ' . $twitterName . 'Timeline';

    // request the home time line - the last 50 item
    $code = $tmhOAuth->request(
    'GET',
    $tmhOAuth->url('1.1/statuses/home_timeline'),
    array(
    'include_entities' => true,
    'count' => 50,
    )
    );
    }

      • Hello, I tried the code given by Nicola,
        and I do not get it to work. I get a:

        Response: Internal Server Error (500)

        I just deleted the ‘old’ piece of code and copy pasted the new code.
        really don’t know where to look or what to do since I am not a programmer, sorry for that.

        I got the rss.php and searchrss.php working.

        So I hope you could help,

        thanks

        • There is an error in the code (probably caused by wordpress when it was copied and pasted.

          Where it says

          if ($code 200) {
          tmhUtilities::pr($tmhOAuth->response['response']);
          die("users_show connection failure");
          }

          it should say

          if ($code <> 200) {
          tmhUtilities::pr($tmhOAuth->response['response']);
          die("users_show connection failure");
          }

  19. If the twitter API is providing geolocation then,
    Is there a way to get geolocations from a tweet? is there a geoloction tag?
    And when using searchrss.php is it possible to use geolocation (gps coordinates) instead of a place name to get tweets from a area?

    Thanks in advance

  20. As others have said, thank you for putting in the work to make this happen! I just wanted to say that I did have some problem with the short tags in the rss.php file. I would imagine that some users might not have a host that would support short tags so it might be desirable to change that aspect of the code if you happen to do a revision at some point. Just a thought!

  21. Hi, I followed your instructions exactly in uploading the files, and getting authentication keys. I then updated the personal_keys.php file but I’m getting the following error – “verify_credentials connection failure”

    I’m certain that the key, secret, token and token_secret are entered correctly but I’m unsure about the $my_domain value – I’ve tried the URL of the feed as well as the URL of my website.

    Any help?

    • Make sure there are no spurious spaces in the strings you’ve assigned the keys and that you’ve uploaded your edited keys file to the right place.

      For the domain I just use the full URL of my site (with the http:// in front). Sorry, been busy the last few days, I’ll have a look after the weekend.

  22. Hi
    Thanks for this, but I’m getting the following error:

    This page contains the following errors:
    error on line 3 at column 25: Unescaped ‘<' not allowed in attributes values

    Any ideas?

  23. Pingback: Show posts from Google+, Facebook and Twitter in your WordPress blog | WebdesignZ

  24. Pingback: Moving at the Speed of Creativity | Playing with FeedWordPress: Planning for the Classroom Newspaper of Now

  25. Pingback: Playing with FeedWordPress: Planning for the Classroom Newspaper of Now – American Fido

  26. Pingback: Playing with FeedWordPress: Planning for the Classroom Newspaper of Now – Web Guy Help

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.