Using the Twitter Search API

30 January 2009| 47 Comments| Print

Twitters new search feature is great for finding interesting people and topics to follow. So i wrote a script to get search results from twitter and display them on your site. This could be integrated into an existing application or used standalone to follow a particular topic or keyword on twitter,  Check the Demo.

twitter-search

The script uses PHP and CURL to get the twitter search results to display them on the page. for the demo i’ve set an if statement to display results for ‘papermashup.com’ if no get variable is present.

Here’s the code that allows us to enter our search term, on submit it posts a get variable to the URL which PHP then processes with CURL.

<div id="search">
<form action="" method="get">
  <label>
  Search twitter
  <input type="text" name="q" id="searchbox" />
  <input type="submit" name="submit" id="submit" value="Search" />
  </label>
</form>
</div>

So we use PHP, CURL, and the SimpleXMLElement() class in PHP5 to parse the XML file. Once we have the xml data, regular expression is used to find the links in the xml content element, which is then saved in $description.

The Code:


// Date function (this could be included in a seperate script to keep it clean)
function date_diff($d1, $d2){
	$d1 = (is_string($d1) ? strtotime($d1) : $d1);
	$d2 = (is_string($d2) ? strtotime($d2) : $d2);

	$diff_secs = abs($d1 - $d2);
	$base_year = min(date("Y", $d1), date("Y", $d2));

	$diff = mktime(0, 0, $diff_secs, 1, 1, $base_year);
	$diffArray = array(
		"years" => date("Y", $diff) - $base_year,
		"months_total" => (date("Y", $diff) - $base_year) * 12 + date("n", $diff) - 1,
		"months" => date("n", $diff) - 1,
		"days_total" => floor($diff_secs / (3600 * 24)),
		"days" => date("j", $diff) - 1,
		"hours_total" => floor($diff_secs / 3600),
		"hours" => date("G", $diff),
		"minutes_total" => floor($diff_secs / 60),
		"minutes" => (int) date("i", $diff),
		"seconds_total" => $diff_secs,
		"seconds" => (int) date("s", $diff)
	);
	if($diffArray['days'] > 0){
		if($diffArray['days'] == 1){
			$days = '1 day';
		}else{
			$days = $diffArray['days'] . ' days';
		}
		return $days . ' and ' . $diffArray['hours'] . ' hours ago';
	}else if($diffArray['hours'] > 0){
		if($diffArray['hours'] == 1){
			$hours = '1 hour';
		}else{
			$hours = $diffArray['hours'] . ' hours';
		}
		return $hours . ' and ' . $diffArray['minutes'] . ' minutes ago';
	}else if($diffArray['minutes'] > 0){
		if($diffArray['minutes'] == 1){
			$minutes = '1 minute';
		}else{
			$minutes = $diffArray['minutes'] . ' minutes';
		}
		return $minutes . ' and ' . $diffArray['seconds'] . ' seconds ago';
	}else{
		return 'Less than a minute ago';
	}
}

// Work out the Date plus 8 hours
// get the current timestamp into an array
$timestamp = time();
$date_time_array = getdate($timestamp);

$hours = $date_time_array['hours'];
$minutes = $date_time_array['minutes'];
$seconds = $date_time_array['seconds'];
$month = $date_time_array['mon'];
$day = $date_time_array['mday'];
$year = $date_time_array['year'];

// use mktime to recreate the unix timestamp
// adding 19 hours to $hours
$timestamp = mktime($hours + 0,$minutes,$seconds,$month,$day,$year);
$theDate = strftime('%Y-%m-%d %H:%M:%S',$timestamp);	

// END DATE FUNCTION

//Search API Script

$q=$_GET['q'];

if($_GET['q']==''){

$q = 'papermashup.com';}

$search = "http://search.twitter.com/search.atom?q=".$q."";

$tw = curl_init();

curl_setopt($tw, CURLOPT_URL, $search);
curl_setopt($tw, CURLOPT_RETURNTRANSFER, TRUE);
$twi = curl_exec($tw);
$search_res = new SimpleXMLElement($twi);

echo "<h3>Twitter search results for '".$q."'</h3>";

## Echo the Search Data

foreach ($search_res->entry as $twit1) {

$description = $twit1->content;

$description = preg_replace("#(^|[\n ])@([^ \"\t\n\r<]*)#ise", "'\\1<a href=\"http://www.twitter.com/\\2\" >@\\2</a>'", $description);
$description = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t<]*)#ise", "'\\1<a href=\"\\2\" >\\2</a>'", $description);
$description = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r<]*)#ise", "'\\1<a href=\"http://\\2\" >\\2</a>'", $description);

$retweet = strip_tags($description);

$date =  strtotime($twit1->updated);
$dayMonth = date('d M', $date);
$year = date('y', $date);
$message = $row['content'];
$datediff = date_diff($theDate, $date);

echo "<div class='user'><a href=\"",$twit1->author->uri,"\" target=\"_blank\"><img border=\"0\" width=\"48\" class=\"twitter_thumb\" src=\"",$twit1->link[1]->attributes()->href,"\" title=\"", $twit1->author->name, "\" /></a>\n";
echo "<div class='text'>".$description."<div class='description'>From: ", $twit1->author->name," <a href='http://twitter.com/home?status=RT: ".$retweet."' target='_blank'>Retweet!</a></div><strong>".$datediff."</strong></div><div class='clear'></div></div>";

}

curl_close($tw);


UPDATE 25/03/09: i’ve added a re-tweet button which simply opens twitter putting the update in your status window.

UPDATE 26/04/09: As requested by @vincent below. I’ve added a time function which works out how long ago a tweet was posted

demodownload

47 Comments

  • Simon Lewis

    Great tutorial this is exactly what i was looking for an app im building thanks Ashley

  • Ashley (author)

    Hey Simon,

    Glad you found it useful, thanks for dropping by!

  • Enlaces del 31-01-09 | evelio.info

    [...] Using the Twitter Search API | Ashley Ford – PaperMashup.com [...]

  • Mootools Ajax Example | Ashley Ford - PaperMashup.com

    [...] Here’s a quick example of an ajax request with Mootools. the code below is from sandmoose.com. However I have modified it to get the data using the twitter search api. [...]

  • nick

    Hey,

    Is it possible to add a retweet button to each of the results?

  • Ashley (author)

    @nick I’ve updated the script and added a retweet button, you could extend this and mash it with my ‘using the twitter api’ post to make it automatic but as a simple example you click the re-tweet button and it adds the status in the twitter form.

    Hope that helps

  • nick

    Awesome. I have almost 0 php skills and this was the only thing missing.

    Thanks!

  • nick

    Isn’t it standard practice to include the original tweeter when retweeting?

    Also then there is a ‘ it cuts off the rest of the message.

  • Ashley (author)

    @nick yeah it is, i added the retweet as an example you are more than welcome to extend the script for your own use.

  • vincent

    it cool,is it possibel to show the tweet time in the tweeet

  • Ashley (author)

    @vincent I’ve updated the demo and download to include the time as well as a function to work out the time since a tweet was posted.

  • Vincent

    Appreciate your doing this,worthing learning. I try to integrate google translate API or other translate jQuery into this.so I can translate the search result to any language.

  • Rod

    Looks great at first glance, but for some reason I can’t get the demo to work with hash tags… #anything returns no results… intentional? it’s a pretty crucial omission for me

  • Rod

    Hashes weren’t working – also spaces were yielding incorrect results. On twitter if you search two keywords it finds results with BOTH, with yours it would find results with EITHER. To fix both of these you need to redefine the URL encoding after pulling down the info with GET – eg;

    $q = str_replace(” “, “%20″, $q); // put the space code back
    $q = str_replace(“#”, “%23″, $q); // put the hash code back

    Should fix it up.

  • Ashley (author)

    @Rod you’ll need to urlencode() the search query thats passed to the xml file, it’s something i missed out in the example code. Hope that helps.

  • Andrew

    Hi,

    Thanks for a great script… any ideas how I can limit the amount of items that are displayed? Also a good idea is to include the username in the retweet after the RT: @ – I did manage to do this but it includes the users name in brackets which is not needed.

    Cheers,

    Andy

  • Ashley (author)

    @andrew you can limit the items by simply adding an if statement

    $num=0;
    if($num < 5){

    // wrap the if statement just inside the foreach statement

    $num++;
    }

    let me know if you have any problems

  • Perry

    Have you heard of an IP address being blocked by Twitter for using this script or a derivative of it?

    I had modified your script and had been using it successfully on a website, but now, it won’t provide results.

    How can I tell if I’m being blocked?

  • Perry

    In addition to my last comment, I now see where your demo exhibits the same behaviour as does mine where no results from a search are displayed.

    Any comments?

  • Ashley (author)

    @perry no i can’t say i have with the search api…

  • Gregg

    Thanks so much for this code!! The date function is really great. I’m a real novice here–any chance you could help me modify the date function above to work with the friends-timeline API rather than the search API? What would I change to make it work?

  • saif

    Dear
    nice tutorial.but help me…..how can i get the id of particular content?
    I have tried by ‘ $twit1->id’. result is not only id but with ‘tag:search.twitter.com……..’
    i need id to hyperlink with it to go to the specific update.

    hope u will understand my problem.
    is there any list, what ‘$search_res = new SimpleXMLElement($twi);’ return?……..means content,updated & what others?

    Awaiting for yr reply

  • Ashley (author)

    @gregg you might be best looking at this tutorial http://papermashup.com/using-the-twitter-api/ and just add the date function to this code. let me know if you have any problem doing it and i can give you a hand

  • Ashley (author)

    @saif firstly to see what data you can get from the xml file its best just to view it (in firefox not safari. Firefox removes xml style so you can see the xml nodes) if you just want to link to the specific status this line is in the xml file:
    you can simply target the attribute href by using the following line: link[0]->attributes()->href; ?> let me know if that makes sense.

  • Jeppe D

    Hi,

    Nice example.

    But when I use it the date is wrong. A tweet from yesterday evening seems to be 5 days and 19 hours old.
    Are there any problems because of timezones?

  • Ashley (author)

    @jeppe my server is in Los Angeles and i’m in London UK, so to compensate for the time difference there’s this line of code.

    $timestamp = mktime($hours + 0,$minutes,$seconds,$month,$day,$year);

    you need to change the 0 above to however many hours time difference there is between you and your server.

    Hope that helps,

  • prabal

    Thanks for a great script… really nice script by using jQuery.
    i have work on number of web service API but this one is best for me.

  • Yannik

    Fatal error: Call to undefined function curl_init() in /mnt/web6/21/82/51616782/htdocs/twitter.php on line 146

    what is curl, and what to do, that it works?

  • Ashley (author)

    @yannik CURL is a module installed only with PHP5 and up it sounds like your server is below PHP5 or the CURL module isn’t turned on, you can check this by looking at your php info file: http://docs.simplemachines.org/index.php?topic=479 hope that helps.

  • Miami Mike

    Here is a similar script that uses server side caching and time delays so that Twitter won’t block your access due to overuse: http://spaceninja.com/2009/07/twitter-php-caching/

  • Dallas Web Design

    Does nayone use the twitter badge on the site. Most people dont even know about it but its pretty cool . Just copy and paste tweek the css to the way you want it to look and all your tweets go right on your page. Cool to use for blog web design or something.

  • dmkinteractive

    Hi there, this script is brilliant! I just have one question, is there any way to get multiple searches and include them all in the same output ordered by time?

  • Ashley (author)

    @dmkinteractive you would have to write a script to loop through the search terms and do a curl request. i’d also recommend caching popular search results to limit the amount of times you ping twitter. Hope that helps ;)

  • Rick

    Hello, great script. How would I go about making the links in each individual tweet have a target of “blank” so that it would pop up in another window? Thanks.

    Rick

  • Ashley (author)

    @rick You could use jquery to add the attribute target with a value of _blank to each of the links.

  • Teh

    Hello,

    Thanks for your script.
    I was testing it with this date “Tue Mar 21 21:00:54 +0000 2006″.
    It returns a wrong count. I guess you are not handling anything more than a year.

  • lapz

    Hi, thanks for this great script.
    I was wondering if there was a simple way to sort the posts from the oldest to the newest ?

    @Teh, sometimes Twitter search results only display recent tweets. It comes back afterwards.

  • raghu

    Hi, thanq for your valuable script. Here the results has to open in new page. thats y u gave as blank

    “.$description.”From: “, $twit1->author->name,”

    plz rectify this…

  • Andivista Info und Technikblog » Blog Archive » Twitter API

    [...] Using the Twitter Search API [...]

  • Friday Fix Nov 30 - Dec 4

    [...] Using the Twitter Search API [...]

  • designfollow

    great.

    thank you.

  • jake

    not working.

    Fatal error: Uncaught exception ‘Exception’ with message ‘String could not be parsed as XML’ in /home/penpal/public_html/index.php:151 Stack trace: #0 /home/penpal/public_html/index.php(151): SimpleXMLElement->__construct(”) #1 {main} thrown in /home/penpal/public_html/index.php on line 151

  • Ashley (author)

    @jake can you provide a little more information, what did you modify in the script?

  • Marcel

    Hi Ashley,

    Would you be willing to give me some tips on how to change this code in order to search for a term in the tweets of a group of users in a particular Twitter list?

    Many thanks in advance.

    Best regards,
    Marcel

  • Matt

    Hey Ashley!
    Thanks for this great great tutorial and demo, I’m right now playing with it.
    I’m stuck trying to add a jquery auto refresh to add the new tweets every x seconds, can you help me?
    Best regardst

  • e-sushi

    Tnx for sharing… a great resource to start from (if you’re lazy like me – lol)

  • Jose Augusto

    Does not work with two words queries like “domain name”.
    You better url encode the query ($q)

Leave a comment...

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled site. To get your own globally-recognized-avatar, register at Gravatar.