How to change twitter status with php and curl without oAuth

Twitter api authentication
Since the 31 of august 2010, twitter made its API more secure, stopping basic authentication calls.
So, if you used basic authentication you have to change your code and implement oAuth authentication model (you can read about oAuth on Wikipedia).

The oAuth authentication model
Using oAuth means that you have to register an application on twitter developer site, understand the new model and implement it (here they suggest how to pass to oAuth). In the oAuth model the process of authenticating a user need to take the user on twitter’s site, here he is recognized and he has to grant permission to your application by clicking on an “Allow” button. After this grant step the user is redirected to the application web site with a “token” and a “secret”, and the application that calls the API for posting or reading need to authenticate each call by adding some parameters created with “token” and “secret”. Before this, we needed a few lines of curl to change the status now we need a lot of code, and we really need a user that click on the “allow” button, at least the first time (than we can store “token” and “secret” for each user on database and re-use for each call).
Well, this process is also much more complex, so it’s not possible to think: “I do it by myself!”

Do It Yourself oAuth
I’m really stubborn and I’ve spent quite a day trying to make my own mini-function to post to twitter. But I did only a small part of the process and this part doesn’t fully work and also it wasn’t enough “mini” to include it in my mini php spider class.
So, if you want to use oAuth, I suggest you to use an existing class, especially if you don’t have a week of free time to spend.

Spider, the rough way
twitter php set status with curl
Thus, I did it the rough way: I wrote a bot that calls twitter home, finds the right form to login, fills it with my credentials, and post it. This post returns another page, that’s my homepage, so my bot finds the form to tweet, fills it and sends it. One hour of work, no oAuth. And here is the Php function:

function twitterSetStatus($user,$pwd,$status) {
	if (!function_exists("curl_init")) die("twitterSetStatus needs CURL module, please install CURL on your php.");
	$ch = curl_init();

	// -------------------------------------------------------
	// get login form and parse it
	curl_setopt($ch, CURLOPT_URL, "https://mobile.twitter.com/session/new");
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_FAILONERROR, 1);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch, CURLOPT_TIMEOUT, 5);
	curl_setopt($ch, CURLOPT_COOKIEJAR, "my_cookies.txt");
	curl_setopt($ch, CURLOPT_COOKIEFILE, "my_cookies.txt");
	curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 ");
	$page = curl_exec($ch);
	$page = stristr($page, "<div class='signup-body'>");
	preg_match("/form action=\"(.*?)\"/", $page, $action);
	preg_match("/input name=\"authenticity_token\" type=\"hidden\" value=\"(.*?)\"/", $page, $authenticity_token);

	// -------------------------------------------------------
	// make login and get home page
	$strpost = "authenticity_token=".urlencode($authenticity_token[1])."&username=".urlencode($user)."&password=".urlencode($pwd);
	curl_setopt($ch, CURLOPT_URL, $action[1]);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $strpost);
	$page = curl_exec($ch);
	// check if login was ok
	preg_match("/\<div class=\"warning\"\>(.*?)\<\/div\>/", $page, $warning);
	if (isset($warning[1])) return $warning[1];
	$page = stristr($page,"<div class='tweetbox'>");
	preg_match("/form action=\"(.*?)\"/", $page, $action);
	preg_match("/input name=\"authenticity_token\" type=\"hidden\" value=\"(.*?)\"/", $page, $authenticity_token);

	// -------------------------------------------------------
	// send status update
	$strpost = "authenticity_token=".urlencode($authenticity_token[1]);
	$tweet['display_coordinates']='';
	$tweet['in_reply_to_status_id']='';
	$tweet['lat']='';
	$tweet['long']='';
	$tweet['place_id']='';
	$tweet['text']=$status;
	$ar = array("authenticity_token" => $authenticity_token[1], "tweet"=>$tweet);
	$data = http_build_query($ar);
	curl_setopt($ch, CURLOPT_URL, $action[1]);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
	$page = curl_exec($ch);

	return true;
}

Bad things
A you can see from the code there are some things that are not good: we need to make 3 calls because we need to login using a hidden authentication token at the login. This means that this function is slow.
Twitter do not like these methods.
If twitter changes its code, it could happen that this function doesn’t work anymore.

Mini bot class
This class will be included in the Mini bot class, you can try a demo here.

15 comments

  1. Giulio Pons

    Nice system Phil. With your it will appear ‘sent via Simple Auth Tweeter’ with my hack it will be ‘sent via mobile web’. Can I add also your system to my Mini Bot Class?

  2. Hugo

    Hello!! Is there any way to change twitter status using the main twitter domain, not the mobile one?? So that way it appears posted as “via web”!!