I published "Facebook Remote Status Update with PHP/cURL Bot" in Feb 4 2014. The script was working well until early this year. I received comments and emails that script no longer working and requested an update. So here I try to find out any changes to Facebook login form and status update.
In summary, the login portion still working fine. However, Facebook has converted status update form into unicode format as well as one of the key value in the status update form. In fact, just need to change one line of my old script to continue our facebook autologin and status update.
Note: Check out the code sample at bottom of this article.
Go to mobile facebook login page, http://m.facebook.com from Chrome browser and view source file. Search for "form method" and cut out the form for analysis.
<form method="post" class="mobile-login-form _5spm" id="u_0_0" novalidate="1" action="https://m.facebook.com/login.php?refsrc=https%3A%2F%2Fm.facebook.com%2Fhome.php&lwv=100&refid=8"><input type="hidden" name="lsd" value="AVpPXY97" autocomplete="off" /> <input type="hidden" name="charset_test" value="€,´,€,´,水,Д,Є" /> <input type="hidden" name="version" value="1" /><input type="hidden" id="ajax" name="ajax" value="0" /> <input type="hidden" id="width" name="width" value="0" /><input type="hidden" id="pxr" name="pxr" value="0" /> <input type="hidden" id="gps" name="gps" value="0" /><input type="hidden" id="dimensions" name="dimensions" value="0" /> <input type="hidden" name="m_ts" value="1441159046" /> <input type="hidden" name="li" value="hlfmVbnK1HO5OMmfgTU0sWjD" /> <input autocorrect="off" autocapitalize="off" class="_56bg _55ws _5ruq" name="email" placeholder="Email address or phone number" type="text" /> <input autocorrect="off" autocapitalize="off" class="_56bg _55ws _5ruq" name="pass" placeholder="Password" type="password" data-sigil="login-password-field" /><div class="_55ws"> <input type="hidden" name="_fb_noscript" value="true" /> </form>
As you can see, there are no significant changes compared to previous form. I login mobile facebook and view source file again. Search for "form method" again.
\u003Cform method=\"post\" class=\"_15nr _15nx\" action=\"\/composer\/mbasic\/?av=100007586291391&refid=7\" id=\"mbasic_inline_feed_composer\" data-sigil=\"mbasic_inline_feed_composer\">\u003Cinput type=\"hidden\" name=\"fb_dtsg\" value=\"AQG0HK9h0N6b\" autocomplete=\"off\" \/>\u003Cinput type=\"hidden\" name=\"charset_test\" value=\"€,´,€,´,水,Д,Є\" \/>\u003Cinput type=\"hidden\" name=\"privacyx\" value=\"300645083384735\" \/>\u003Cinput type=\"hidden\" name=\"target\" value=\"100007586291391\" \/>\u003Cinput type=\"hidden\" name=\"c_src\" value=\"feed\" \/>\u003Cinput type=\"hidden\" name=\"cwevent\" value=\"composer_entry\" \/>\u003Cinput type=\"hidden\" name=\"referrer\" value=\"feed\" \/>\u003Cinput type=\"hidden\" name=\"ctype\" value=\"inline\" \/>\u003Cinput type=\"hidden\" name=\"cver\" value=\"amber\" \/>\u003Cinput type=\"hidden\" name=\"rst_icv\" \/>\u003Cdiv class=\"_55wo\">\u003Cdiv class=\"_15ny\">\u003Cdiv class=\"_d6-\">\u003Cspan class=\"_3scq mfss fcg\">\u003Cbutton type=\"submit\" value=\"Add Photos\" class=\"_56bz _54k8 _5j35\" name=\"lgc_view_photo\" data-sigil=\"touchable\">\u003Ci class=\"_56br img sp_u3S-VfFA87s sx_c80b4f\">\u003C\/i>\u003Cspan class=\"_55sr\">Add Photos\u003C\/span>\u003C\/button>\u003Cbutton type=\"submit\" value=\"Check In\" class=\"_56bz _54k8 _5j35\" name=\"view_location\" data-sigil=\"touchable\">\u003Ci class=\"_56br img sp_u3S-VfFA87s sx_961033\">\u003C\/i>\u003Cspan class=\"_55sr\">Check In\u003C\/span>\u003C\/button>\u003Cbutton type=\"submit\" value=\"More\" class=\"_56bz _54k8 _5j35\" name=\"view_overview\" data-sigil=\"touchable\">\u003Ci class=\"_56br img sp_u3S-VfFA87s sx_e446f6\">\u003C\/i>\u003Cspan class=\"_55sr\">More\u003C\/span>\u003C\/button>\u003C\/span>\u003C\/div>\u003C\/div>\u003Cdiv>\u003Clabel class=\"_15nz\">\u003Cdiv class=\"_4g33\">\u003Cdiv class=\"_5s61 _15n-\">\u003Ca href=\"\/profile_picture\/?refid=7\">\u003Ci class=\"img profpic\" aria-label=\"Chin Hock Tan\" role=\"img\" style=\"background:#d8dce6 url("https:\/\/fbcdn-profile-a.akamaihd.net\/hprofile-ak-xpf1\/v\/t1.0-1\/c9.0.32.32\/p32x32\/10354686_10150004552801856_220367501106153455_n.jpg?efg=eyJpIjoidCJ9&oh=1ef7b70e890a13f203815ba364a68e9a&oe=56712FE4&__gda__=1449910805_6e352091a4bf1af747430b43812035cd") no-repeat center;background-size:100\u0025 100\u0025;-webkit-background-size:100\u0025 100\u0025;width:30px;height:30px;\">\u003C\/i>\u003C\/a>\u003C\/div>\u003Cdiv class=\"_4g34\">\u003Ctextarea class=\"_1svy _2ya3 _3jce _2_8i\" name=\"xc_message\" placeholder=\"What's on your mind?\" rows=\"1\" id=\"u_0_26\" data-sigil=\"expandable-textarea composer-text-area\">\u003C\/textarea>\u003C\/div>\u003Cdiv class=\"_5s61\">\u003C\/div>\u003C\/div>\u003C\/label>\u003C\/div>\u003Cdiv class=\"_4g33 _15n_\">\u003Cdiv class=\"_4g34\">\u003Cbutton type=\"submit\" value=\"\" class=\"_54k8 _8l7\" name=\"view_privacy\" data-sigil=\"touchable\">\u003Cspan class=\"_55sr\">\u003Cspan>\u003Ci class=\"img img\" style=\"background-image: url("https:\/\/fbstatic-a.akamaihd.net\/rsrc.php\/v2\/y8\/r\/JTip4PFvKxq.png");background-repeat:no-repeat;background-size:100\u0025 100\u0025;-webkit-background-size:100\u0025 100\u0025;width:32px;height:26px;\" aria-label=\"Public\" role=\"img\">\u003C\/i>\u003Ci class=\"img img\" style=\"background-image: url("https:\/\/fbstatic-a.akamaihd.net\/rsrc.php\/v2\/ya\/r\/N8JqY4-hPad.png");background-repeat:no-repeat;background-size:100\u0025 100\u0025;-webkit-background-size:100\u0025 100\u0025;width:11px;height:25px;\">\u003C\/i>\u003C\/span>\u003C\/span>\u003C\/button>\u003C\/div>\u003Cdiv class=\"_5s61\">\u003Cbutton type=\"submit\" value=\"Post\" class=\"_54k8 _56bs _56bu\" name=\"view_post\" data-sigil=\"touchable\">\u003Cspan class=\"_55sr\">Post\u003C\/span>\u003C\/button>\u003C\/div>\u003C\/div>\u003C\/div>\u003C\/form>
Now Facebook has converted the status update form from text to unicode format. To analyze Facebook status update form so that we can parse correctly in our script, we need to decode unicode back to text format. We can use online conversion tools or PHP function json_decode().
<?php echo json_decode('"\u003Cform method=\"post\" class=\"_15nr _15nx\" action=\"\/composer\/mbasic\/?av=1294028074&refid=8\" id=\"mbasic_inline_feed_composer\" data-sigil=\"mbasic_inline_feed_composer\">\u003Cinput type=\"hidden\" name=\"fb_dtsg\" value=\"AQGQqJ1ER50p\" autocomplete=\"off\" \/>\u003Cinput type=\"hidden\" name=\"charset_test\" value=\"€,´,€,´,水,Д,Є\" \/>\u003Cinput type=\"hidden\" name=\"privacyx\" value=\"291667064279714\" \/>\u003Cinput type=\"hidden\" name=\"target\" value=\"1294028074\" \/>\u003Cinput type=\"hidden\" name=\"c_src\" value=\"feed\" \/>\u003Cinput type=\"hidden\" name=\"cwevent\" value=\"composer_entry\" \/>\u003Cinput type=\"hidden\" name=\"referrer\" value=\"feed\" \/>\u003Cinput type=\"hidden\" name=\"ctype\" value=\"inline\" \/>\u003Cinput type=\"hidden\" name=\"cver\" value=\"amber\" \/>\u003Cinput type=\"hidden\" name=\"rst_icv\" \/>\u003Cdiv class=\"_55wo\">\u003Cdiv class=\"_15ny\">\u003Cdiv class=\"_d6-\">\u003Cspan class=\"_3scq mfss fcg\">\u003Cbutton type=\"submit\" value=\"Add Photos\" class=\"_56bz _54k8 _5j35\" name=\"lgc_view_photo\" data-sigil=\"touchable\">\u003Ci class=\"_56br img sp_u3S-VfFA87s sx_c80b4f\">\u003C\/i>\u003Cspan class=\"_55sr\">Add Photos\u003C\/span>\u003C\/button>\u003Cbutton type=\"submit\" value=\"Check In\" class=\"_56bz _54k8 _5j35\" name=\"view_location\" data-sigil=\"touchable\">\u003Ci class=\"_56br img sp_u3S-VfFA87s sx_961033\">\u003C\/i>\u003Cspan class=\"_55sr\">Check In\u003C\/span>\u003C\/button>\u003Cbutton type=\"submit\" value=\"More\" class=\"_56bz _54k8 _5j35\" name=\"view_overview\" data-sigil=\"touchable\">\u003Ci class=\"_56br img sp_u3S-VfFA87s sx_e446f6\">\u003C\/i>\u003Cspan class=\"_55sr\">More\u003C\/span>\u003C\/button>\u003C\/span>\u003C\/div>\u003C\/div>\u003Cdiv>\u003Clabel class=\"_15nz\">\u003Cdiv class=\"_4g33\">\u003Cdiv class=\"_5s61 _15n-\">\u003Ca href=\"\/dzicrystal?refid=8\">\u003Ci class=\"img profpic\" aria-label=\"Tan Chin Hock\" role=\"img\" style=\"background:#d8dce6 url("https:\/\/fbcdn-profile-a.akamaihd.net\/hprofile-ak-xfa1\/v\/t1.0-1\/c63.38.474.474\/s32x32\/486498_4475184559750_1404325329_n.jpg?efg=eyJpIjoidCJ9&oh=4e02d8891697287d5ba18b8581729454&oe=56839EA5&__gda__=1451142700_b2b3bdd51c36508f1c92faa8d4fe86c2") no-repeat center;background-size:100\u0025 100\u0025;-webkit-background-size:100\u0025 100\u0025;width:30px;height:30px;\">\u003C\/i>\u003C\/a>\u003C\/div>\u003Cdiv class=\"_4g34\">\u003Ctextarea class=\"_1svy _2ya3 _3jce _2_8i\" name=\"xc_message\" placeholder=\"What's on your mind?\" rows=\"1\" id=\"u_0_10\" data-sigil=\"expandable-textarea composer-text-area\">\u003C\/textarea>\u003C\/div>\u003Cdiv class=\"_5s61\">\u003C\/div>\u003C\/div>\u003C\/label>\u003C\/div>\u003Cdiv class=\"_4g33 _15n_\">\u003Cdiv class=\"_4g34\">\u003Cbutton type=\"submit\" value=\"\" class=\"_54k8 _8l7\" name=\"view_privacy\" data-sigil=\"touchable\">\u003Cspan class=\"_55sr\">\u003Cspan>\u003Ci class=\"img img\" style=\"background-image: url("https:\/\/fbstatic-a.akamaihd.net\/rsrc.php\/v2\/yW\/r\/Y9r9qnFfHyi.png");background-repeat:no-repeat;background-size:100\u0025 100\u0025;-webkit-background-size:100\u0025 100\u0025;width:32px;height:26px;\" aria-label=\"Friends\" role=\"img\">\u003C\/i>\u003Ci class=\"img img\" style=\"background-image: url("https:\/\/fbstatic-a.akamaihd.net\/rsrc.php\/v2\/ya\/r\/N8JqY4-hPad.png");background-repeat:no-repeat;background-size:100\u0025 100\u0025;-webkit-background-size:100\u0025 100\u0025;width:11px;height:25px;\">\u003C\/i>\u003C\/span>\u003C\/span>\u003C\/button>\u003C\/div>\u003Cdiv class=\"_5s61\">\u003Cbutton type=\"submit\" value=\"Post\" class=\"_54k8 _56bs _56bu\" name=\"view_post\" data-sigil=\"touchable\">\u003Cspan class=\"_55sr\">Post\u003C\/span>\u003C\/button>\u003C\/div>\u003C\/div>\u003C\/div>\u003C\/form>"'); ?>
If we view source file for the output of json_decode() and clean up HTML tags in the form, here is the output we need to focus:
<form method="post" class="_15nr _15nx" action="/composer/mbasic/?av=1294028074&refid=8" id="mbasic_inline_feed_composer" data-sigil="mbasic_inline_feed_composer"> <input type="hidden" name="fb_dtsg" value="AQGQqJ1ER50p" autocomplete="off" /> <input type="hidden" name="charset_test" value="€,´,€,´,水,Д,Є" /> <input type="hidden" name="privacyx" value="291667064279714" /> <input type="hidden" name="target" value="1294028074" /> <input type="hidden" name="c_src" value="feed" /><input type="hidden" name="cwevent" value="composer_entry" /> <input type="hidden" name="referrer" value="feed" /> <input type="hidden" name="ctype" value="inline" /> <input type="hidden" name="cver" value="amber" /> <input type="hidden" name="rst_icv" /><div class="_55wo"> <textarea class="_1svy _2ya3 _3jce _2_8i" name="xc_message" placeholder="What's on your mind?" rows="1" id="u_0_10" data-sigil="expandable-textarea composer-text-area"></textarea> </form>
Not much changes compared to old HTML form. However, at the text area, the "name" parameter is now changed to "xc_message". So in this case, I changed one line in my old script. In the fbform.php,
public function fbStatusUpdate($status) { unset ($this->_inputs); unset ($this->_url); $this->getFormFields(); // $this->_inputs['status']=$status; // Not working anymore. Change to xc_message $this->_inputs['xc_message']=$status; $this->_url = FB . $this->_url; $post_field = $this->arrayImplode( '=', '&', $this->_inputs); $this->post($this->_url, $post_field); }
In the fbautopost.php, set the status update you want and run the script. REMEMBER: set your login email and password in this script.
<?php include 'httpcurl.php'; include 'fbform.php'; $fbhomepage = 'http://m.facebook.com'; $username = "xxxxx"; // Insert your login email $password = "zzzzz"; // Insert your password $status = "New and Updated! Check it out at http://php8legs.com/en/facebook/45-new-and-updated-facebook-remote-status-update-with-php-curl-bot!"; $pages = new FBform(); $pages->get($fbhomepage); $pages->fblogin($username, $password); $pages->get($fbhomepage); $pages->fbstatusupdate($status); ?>
Here is the output and we are back to business again! Good luck!
Code:
1. fbform.php
<?php define('FB','https://m.facebook.com'); define('FORM','~<form method="post" (.*?)</form>~s'); define('ACTION','~action=(?:["\'])?([^"\'\s]*)~i'); define('INPUT','~<input(.*?)>~'); define('NAME','~name=(?:["\'])?([^"\'\s]*)~i'); define('VALUE','~value=(?:["\'])?([^"\'\s]*)~i'); class FBform extends HttpCurl { private $_url; private $_inputs = array(); public function __construct() {} public function __destruct() {} public function fbLogin($username, $password) { unset ($this->_inputs); unset ($this->_url); $this->getFormFields(); $this->_inputs['email']=$username; $this->_inputs['pass']=$password; // $this->_url = FB . $this->_url; $post_field = $this->arrayImplode( '=', '&', $this->_inputs); $this->post($this->_url, $post_field); } public function fbStatusUpdate($status) { unset ($this->_inputs); unset ($this->_url); $this->getFormFields(); // $this->_inputs['status']=$status; // Not working anymore. Change to xc_message $this->_inputs['xc_message']=$status; $this->_url = FB . $this->_url; $post_field = $this->arrayImplode( '=', '&', $this->_inputs); $this->post($this->_url, $post_field); } public function arrayImplode( $glue, $separator, $array ) { $string = array(); foreach ( $array as $key => $val ) { if ( is_array( $val ) ) $val = implode( ',', $val ); $string[] = "{$key}{$glue}{$val}"; } return implode( $separator, $string ); } public function getFormFields() { if (preg_match(FORM, parent::getBody(), $form)) { preg_match(ACTION, $form[0], $action); $this->_url= $action[1]; preg_match_all(INPUT, $form[0], $fields); foreach ($fields[0] as $field) { if (preg_match(NAME, $field, $name)) { $name = $name[1]; $value = ''; if (preg_match(VALUE, $field, $value)) $value = $value[1]; if ($value!=NULL) $this->_inputs[$name] = $value; } } return $this->_inputs; } else { echo "Error, Form not found!"; } } } ?>
2. httpcurl.php
<?php // Class HttpCurl class HttpCurl { private $_ch, $_cookie, $_info, $_body, $_error; public function __construct() { if (!function_exists('curl_init')) { throw new Exception('cURL not enabled!'); } } public function get($url) { $this->_ch = curl_init(); curl_setopt($this->_ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101 Firefox/22.0'); curl_setopt($this->_ch, CURLOPT_POST, 0); curl_setopt($this->_ch, CURLOPT_FOLLOWLOCATION, TRUE); curl_setopt($this->_ch, CURLOPT_MAXREDIRS, 5); curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($this->_ch, CURLOPT_COOKIEFILE, getcwd () . '/facebook_cookie' ); curl_setopt($this->_ch, CURLOPT_COOKIEJAR, getcwd () . '/facebook_cookie' ); curl_setopt($this->_ch, CURLOPT_SSL_VERIFYPEER, false ); curl_setopt($this->_ch, CURLOPT_SSL_VERIFYHOST, false ); curl_setopt($this->_ch, CURLOPT_URL, $url); $this->_body = curl_exec($this->_ch); $this->_info = curl_getinfo($this->_ch); $this->_error = curl_error($this->_ch); curl_close($this->_ch); } public function post($url, $post_data) { $this->_ch = curl_init(); curl_setopt($this->_ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101 Firefox/22.0'); curl_setopt($this->_ch, CURLOPT_FOLLOWLOCATION, TRUE); curl_setopt($this->_ch, CURLOPT_MAXREDIRS, 5); curl_setopt($this->_ch, CURLOPT_HEADER, 0); curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($this->_ch, CURLOPT_SSL_VERIFYPEER, false ); curl_setopt($this->_ch, CURLOPT_SSL_VERIFYHOST, false ); curl_setopt($this->_ch, CURLOPT_ENCODING, "" ); curl_setopt($this->_ch, CURLOPT_POST, TRUE); curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $post_data); curl_setopt($this->_ch, CURLOPT_COOKIEFILE, getcwd () . '/facebook_cookie' ); curl_setopt($this->_ch, CURLOPT_COOKIEJAR, getcwd () . '/facebook_cookie' ); curl_setopt($this->_ch, CURLOPT_URL, $url); $this->_body = curl_exec($this->_ch); $this->_info = curl_getinfo($this->_ch); $this->_error = curl_error($this->_ch); curl_close($this->_ch); } // Get http_code public function getStatus() { return $this->_info[http_code]; } // Get web page header information public function getHeader() { return $this->_info; } public function getHandle() { return $this->_ch; } // Get web page content public function getBody() { return $this->_body; } public function __destruct() { } } ?>
3. fbautopost.php
<?php include 'httpcurl.php'; include 'fbform.php'; $fbhomepage = 'http://m.facebook.com'; $username = "xxxx"; // Insert your login email $password = "yyyy"; // Insert your password $status = "New and Updated! Check it out at http://php8legs.com/en/facebook/45-new-and-updated-facebook-remote-status-update-with-php-curl-bot!"; $pages = new FBform(); $pages->get($fbhomepage); $pages->fblogin($username, $password); $pages->get($fbhomepage); $pages->fbstatusupdate($status); ?>
Related items
- Pinterest bot - How to auto-login with php-webdriver + Selenium
- How to auto publish post on Instagram Page with PHP/cURL and without using Instagram API (1)
- How to auto publish post on Facebook Fan Page as admin using Facebook PHP SDK V4 Graph API v2.2 (4) - Integrate with Opencart
- How to auto publish post on Facebook Fan Page as admin using Facebook PHP SDK V4 Graph API v2.2 (3) - Single Product Manual Posting
- How to auto publish post on Facebook Fan Page as admin using Facebook PHP SDK V4 Graph API v2.2 (2) - Get Permanent Page Access Token