The ultimate guide to creating your own personalized twitterfeed clone! Kidding… Actualy this is just a mockup, a simple prototype, which is way too fresh for any actual use. We’ll take this forward step by step. I’m not going to give out all my sources but I’ll guide you through authentication, rss lookup, parsing, thanking for retweets, and shooting random stuff at people that mention your robot.
Here’s a brief list of features we will implement:
- Runs in console, no HTTP access
- Authentication via OAuth, tweeting via OAuth
- RSS lookup, parsing, forming tweets in bound of 140 characters including a postfix (hashtag or RT)
- Tweeting ‘thank you for retweeting’ to users that retweet the robot
- Following people that retweet the robot
- Acting strange on users that mention the robot
All this is going to be setup on a linux box running crond and acting every 15 minutes or so. Are you ready? Let’s do it!
Registering an App at Twitter OAuth Clients
This is mandatory if we’re using OAuth (don’t go with basic authentication because Twitter will be closing that down sooner or later, plus we’re making a personalized robot, so the ‘from’ string in the tweets is a must). Browse to the Twitter OAuth Clients page (assuming you’re logged into Twitter) and register a new application. Make sure you pick Read and Write access as our robot will use POST calls to update its status. Also note that we’re preventing all HTTP access to the robot control, thus we’ll be using PIN based OAuth, so make sure you pick Client application and not web.
Now, don’t lose your Consumer key and Consumer secret – we’ll be using those in our app for identity. Don’t give them out to anybody you don’t trust unless you’d like people tweeting “from YourApp”. Note that you can ask Twitter to reset the values for you in case somebody got unwanted access to them. The request and access URLs are not important, they’re the same for everyone.
Setting up the Environment
What environment? Umm, we’ll be using Magpie RSS to parse RSS feeds, Curl to access the Twitter API and the Twitter OAuth Class by Abraham Williams (we used this a bunch of times in my earlier postings) which is dependent on the Curl functions. Make sure you install everything right – the magpie functions work, curl functions are available and the Twitter OAuth class is defined.
What you also need is a bit.ly login and API key, go get yours somewhere here. Feel free to use a different URL shortener if you feel like, but we’ll stick to bit.ly.
Authentication: Storing the Access Tokens
We’ll divide our application in two parts, one will be running every 15 minutes, the second one will run once for authentication. Create a new PHP file, call it oauth.php or whatever and also make sure you got your consumer key and secret next to you and visible by oauth.php. It’s up to you where to keep them, I like storing them in a config.php which I include/require in auth.php and robot.php.
If you haven’t read my previous articles about Automated Serverside Tweeting Using OAuth and PIN-based OAuth Using PHP then make sure you do, because I wouldn’t like to go through the same code again. What’s important here is that oauth.php will run on its own and will accept parameters via command line. Like this:
# php oauth.php register Request tokens aquired, proceed to this link: https://twitter.com/oauth/authorize?oauth_token=whatever # php oauth.php validate 123456 Access tokens stored, identified as @twittername
So after you’ve validated your OAuth session, access tokens are stored somewhere on disk, I just call my files access_token and access_token_secret. If the files are present, then your robot will be able to tweet, otherwise ask for registration. I hope everything’s clear enough here. The main point of this file is to get your access tokens written to disk.
Feeding Twitter from RSS
We need to distinguish different actions which the robot is supposed to do, through an action parameter passed by the command line. I leave it up to you, but make sure your control flows similar to this:
$action = $argv[1]; if ($action == "feed") { $feed_name = $argv[2]; // Read the feeds, tweet the feeds } elseif ($action == "rthx") { // Read the names, tweet the names! } elseif ($action == "reply") { // Read the names, umm.. Say something! }
So the robot control will look something like this:
# php robot.php feed wordpress Feeding my public timeline with wordpress articles # php robot.php rthx Thanking peeps for the retweets and following them all # php robot.php reply Writing strange stuff to peeps that mentioned me
Good, now let’s assume we’re in the feed action. Define an associative array of feeds:
$feeds = array( "wordpress" => array("url" => "http://wordpress.org/development/feed/", "postfix" => "#wordpress"), "mashable" => array("url" => "http://feeds2.feedburner.com/Mashable", "postfix" => "via (@mashable)"), );
Two is enough for starting. We’ll make our robot tweet #wordpress tweets and read out mashable’s website and tweet headlines via @mashable. Make sure that you’ve already written a check for access_token and access_token_secret and gave out an error message if they didn’t exist or were expired. We cannot tweet without those, remember? I’m assuming you’ve stored them into $access_token and $access_token_secret respectively and initialized the $oauth object:
$oauth = new TwitterOAuth($oauth_consumer_key, $oauth_consumer_secret, $access_token, $access_token_secret);
The second parameter (“wordpress” in the control above example) would be stored into a $feed_name variable. From there on we’ll go with code:
// Store the feed settings into $feed $feed = $feeds[$feed_name]; // Fetch the feed and store the prefix $rss = fetch_rss($feed["url"]); $postfix = $feed["postfix"]; // Loop through the feed items foreach ($rss->items as $item) { // All simple enough here $title = trim($item["title"]); $url = $item["link"]; // Let's make sure our feeds are in English, allow spaces and punctuation if (ereg('^[[:alnum:][:blank:][:punct:]]+$', $title)) { // Escape the URL for bit.ly shortening and then shorten the link // This is the place where you have to use your bit.ly login // And the API key $url_escaped = urlencode($url); $bitly_url = "http://api.bit.ly/shorten?version=2.0.1"; $bitly_url .= "&longUrl=$url_escaped"; $bitly_url .= "&login=$bitly_login&apiKey=$bitly_key"; $shortened_url = json_decode(file_get_contents($bitly_url)); // If everything went okay, go on if ($shortened_url->errorCode == 0) { // Retrieve the shortened url from the json object foreach ($shortened_url->results as $key => $value) $shorturl = $value->shortUrl; // Form a new message from the short URL and the postfix $message = " $shorturl $postfix"; $length = strlen($message); // We should trim down the title if it's too long // So that our tweets are 120 characters or less if (strlen($title) > 120-$length) $shorttitle = substr($title, 0, 117-$length) . "..."; else $shorttitle = $title; // Add the title to the message $message = $shorttitle.$message; // Post the message to Twitter $oauth->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $message), 'POST'); // Wait a couple of mintes before the next tweet // Don't try and flood Twitter, remember, you have // Only 150 API calls per hour, use them wisely. sleep(rand(60,120)); } } }
Read carefully through the comments, you should be able to understand what we’re doing here. This is the RSS part, (almost) all clean and shiny. Proceed to the retweets part.
Automatically Thank Your Retweeters and… Follow them!
Be very very careful here as we don’t want to thank the retweeters too much. You’ll need to think of a mechanism to store the id of the latest retweet that you already thanked and use it in the since_id parameter when calling the Twitter API. I’ll leave this part up to you, but in general the code should look something like this:
// Read the since_id from a file $since_id = @file_get_contents("retweets_since_id"); if ($since_id > 0) { } else { $since_id = 1; } // Send the Twitter API request for the latest 50 mentions // That were posted after the since_id parameter we read earlier $mentions = $oauth->OAuthRequest("http://twitter.com/statuses/mentions.xml" , array("count" => 50, "since_id" => $since_id), "GET"); // Make the XML an object $mentions = simplexml_load_string($mentions); // Setup an array which will contain users to retweet and follow $users_to_rthx = array(); // Read the last tweet's id and store it into the retweets_since_id file $last_id = ($mentions->status[0]->id > $since_id) ? $mentions->status[0]->id : $since_id; file_put_contents("retweets_since_id", (string)$last_id); // Loop through the tweets foreach ($mentions->status as $status) { // Let's see if somebody retweeted you. // Err, remember to replace @yourname if (strpos(strtolower($status->text), "rt @yourname") || strpos(strtolower($status->text), "via @yourname")) { // Add the guy to the retweeters array $users_to_rthx[] = $status->user->screen_name; } } // Remove duplicates (we don't thank somebody twice in a tweet) $users_to_rthx = array_unique($users_to_rthx); // Setup the tweet prefix and initialize the mentions variable // The tweet_prefix is just in case ;) $tweet_prefix = "Thanks for the retweets! "; $tweet_mentions = ""; $tweet_prefix = ""; // Loop through the retweeters popping variables out of the array while ($mention_this_guy = array_pop($users_to_rthx)) { // If the popped guy fits into our brand new tweet, add him if (strlen($tweet_prefix . $tweet_mentions . $tweet_postfix . "@".$mention_this_guy) < 140) { $tweet_mentions .= "@".$mention_this_guy . " "; // Send the friendhips create (follow) request to the API echo "Following: " . $mention_this_guy; $oauth->oAuthRequest("https://twitter.com/friendships/create/" . $mention_this_guy . ".xml", array(), "POST"); } // If he doesn't push him back into the variable, tweet and reset // The $tweet_mentions variable for the other retweeters else { array_push($users_to_rthx, $mention_this_guy); // Format the message and output to screen (for debugging) $message = $tweet_prefix . trim($tweet_mentions) . $tweet_postfix; echo "Tweeting: " . $message . " (" . strlen($message) . ") n"; // Send the status update request to the Twitter API $oauth->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $message), 'POST'); // Wait a few seconds before the next round sleep(rand(5,30)); // Reset $tweet_mentions = ""; } } // If we've got something left in the mentions, we need to tweet that if (strlen($tweet_mentions) > 0) { $message = $tweet_prefix . trim($tweet_mentions) . $tweet_postfix; echo "Tweeting: " . $message . " (" . strlen($message) . ") n"; $oauth->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $message), 'POST'); sleep(rand(5,30)); $tweet_mentions = ""; }
The comments explain it all.
Did Somebody Say Anything? Random Replies
This is the fun part. Whenever somebody mentions your name (and it is not a retweet), we send them a strange message mentioning their name. The code looks exactly like the retweeters thank code above, except that we don’t search for “rt @yourname” and “via @yourname”, instead we work with ones that don’t contain “rt” and “via” at all.
Don’t forget to store the replies_since_id too as we don’t want to message users multiple times (infinite number of times actually) because they’ll block the frustrating robot. Here’s the while loop that actually tweets. In this part the names are stored in the $users_to_reply array and goes like this:
// The loop while ($mention_this_guy = array_pop($users_to_reply)) { // Some random quotes ;) You can add your own $random_quotes = array( "Wha?", "Interesting ...", "Affirmative sir!", "Hmm, makes me think ..", "So you really think I'm not human? Well.. Umm.. *sigh*" ); // Format the message and tweet a random quote $message = "@".$mention_this_guy . " " . $random_quotes[array_rand($random_quotes)]; echo "Tweeting: " . $message . " (" . strlen($message) . ") n"; $oauth->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $message), 'POST'); // Wait a little sleep(rand(5,30)); }
That’s about it. The last part is adding the whole stuff to crontab for automated work. Open up /etc/crontab and add a few lines:
# Feed mashable and wordpress tweets once every 15-16 minutes */15 * * * * php /home/youruser/twibots/robot.php feed wordpress */16 * * * * php /home/youruser/twibots/robot.php feed mashable # Thank and follow the retweeters once every half an hour */30 * * * * php /home/youruser/twibots/robot.php rthx # Reply to people hourly 01 * * * * php /home/youruser/twibots/robot.php reply
Restart your cron daemon and voila! I’m used to having full control over my virtual private server so if you use simple shared hosting you should access the crontab (also called cron jobs) via your CPanel. Don’t forget to actually write the php command because .php files aren’t actually executable by linux. Also note that my files are stored in a non-accessible by apache part of the hard drive, so omit putting them into public_html, www or whatever. If you do though, make sure you define a “deny from all” rule in .htaccess. We don’t want other people messing with our newly born robot. Robots, robots, robots… What should we call them? Twibots? ;)
Upd. Continued: Automated Twitter Bot in PHP: Remote Control and Twitter Robot in PHP: Twibots Draft
[…] This post was mentioned on Twitter by kovshenin, Cecil J. Chen and Michael Davis. Michael Davis said: Create Your Own Automated Twitter Robot in PHP http://bit.ly/21d2A […]
Great job, Very detailed and very precise. Excellent. :)
I am really having a hard time getting my twitter bot to work, I can’t get passed the PIN verification stage. Part of the problem I am having is that while I am an OKAY coder, following your broken pieces of code (broken as split up) and not fully understanding where to put them I may have put something in the wrong spot, or possibly never included something I was supposed to.
I am sure that the script will work after I get it authorized and such. Possibly you can take a look at my code and tell me what is wrong? Please email me and I will zip it to you… it follows your basic templates so it shouldn’t be hard to spot the error.
Ooor if you just want to send me a sample of a working code (with oauth, libs, and even your static files to put tokens and keys in) just without the tokens and keys and such, so I can replace all that with my stuff, and then replace the main script with mine. I just know I am missing something.
However you want to do it is fine.. just shoot me an email.. its the same email in the mail field but t/e/a/m/c/o/l/t/r/a@gmail.com (without the slashes) is my email address if you for some reason can’t see it.
Hi Travis, I'll be glad to help you sort things out, shooting you an e-mail.
[…] Create Your Own Automated Twitter Robot in PHP By Konstantin Kovshenin, October 9th, 2009 Site: Kovshenin […]
[…] Create Your Own Automated Twitter Robot in PHP By Konstantin Kovshenin, October 9th, 2009 Site: Kovshenin […]
[…] Create Your Own Automated Twitter Robot in PHP By Konstantin Kovshenin, October 9th, 2009 Site: Kovshenin […]
Hey,
can u send me the whole code (to mail2niju,gmail).?
Not really Niju, it's still not as good as I'd like it to be but I'm working on it. Sign up to the blog feed, I'll post it all out eventually ;)
Do you have this script available by any chance. Are you able to share the full code? Will really appreciate it.
You're actually the second one to ask me this week. I'll do a little clean up and post it very soon, promise ;)
Thanks for the DEMO….
Can U plz explain … is it possible to update reply without display the page https://twitter.com/oauth/authenticate….
Well you can use basic authentication which would require your username and password, but OAuth was implemented to replace that.
thanks again
hey great stuff there i only wanted to draw you attention to the retweeters script line number 62 i
am having problems pushing items in the array…
<pre>
<?php
$items=('twenty','beach','advark');
$msg='';
while($item=array_pop($items))
{
$msg.=$items;
if(strlen($msg)
</pre>
this loops infinitely why wont it push??
Nice simple job well done.. Very useful tutorial written.
oh finally got it.I wasn't resting the tweet mentions .Great tut!
Aight ;) glad you solved it!
Hi thanks for the code..
The question is where do I run this command?
# php oauth.php register
Request tokens aquired, proceed to this link: https://twitter.com/oauth/authorize?oauth_token=w…
# php oauth.php validate 123456
Access tokens stored, identified as @twittername
Thanks
Joe, that assumes you're familiar with SSH …
So this mean I can't run it on shared hosting?
dude.. i hav reg. for the app, but couldn't post to twitter.. some pro.. can u just upload as files ?? including lib ??
I haven't finished it yet, maybe I will upload a demo as soon as I'm done ;)
In this way, when i tried to post to twitter with my access token i got, its not working !!
setToken($_GET['oauth_token']);
$token = $twitterObj->getAccessToken();
$twitterObj->setToken($oauth_token, $oauth_token_secret);
$twitterInfo= $twitterObj->get_accountVerify_credentials();
$twitterInfo->response;
echo "Your twitter username is {$twitterInfo->screen_name} and your profile picture is profile_image_url}">";
//$message Status update
$status = 'Testing API..';
$update_status = $twitterObj->post_statusesUpdate(array('status' => $status));
$update_status->response;
echo" Default tweet posted ( Testing API.. )";
?>
Strange.. You should try to use a pastebin or something to post your code, I don't understand a single bit of it ;)
here it is..
http://pastebin.com/aazg28j2
Got it. That is SO strange.. You should use Abraham's Twitter OAuth class, it's much more easy to understand, and all my source code is based on that.
SO strange ??
well can u provide links ?? or ur updated working files ??
Please read through the post, there are tonnes of links to the library itself and a bunch of examples with working code.
hello. does anyone could please give me some directions on how http://rt.water.org was done? this is an oauth implementation that allows users to allow me to retweet my own tweets on their stauses. pretty cool. But I don't find a starting point on how to implement it. Any ideas? Thanks a lot! Tilman
[…] Create Your Own Automated Twitter Robot in PHP […]
Thanks for a great post. I've found it quite useful.
One thing that's worth mentioning (regarding assumptions made here and in the earlier — and also excellent — "Automated Serverside Tweeting" post) is that Twitter is strange about appending values to urls. "Client" is indeed the best choice when setting up the Application Type in twitter. However, if "Client" (rather than "Browser") is chosen during initial application setup, the token success screen at twitter.com/oauth/authenticate only gives one value (a number); only one value provided, that is, rather than the two variable values needed (acess_token and access_token_secret), with no information appended to the URL. (That's assuming Twitter doesn't fix this, of course.)
Changing the application type briefly to "Browser" (or setting it up that way initially), running the token-generation script, then switching it to "Client" and running it again should provide valid values appended to the url, as described in your tutorial. Thanks again for providing it!
[…] I should embrace the robotic future of twitter and create automated twitter robots for all four… That just isn’t my style though. I believe in sincere, honest […]