Just after implementing the Twitter Oauth API to publish tweets from a PHP application, I thought that doing the same with Facebook would be a piece of cake. Well, not quite, although I’ve finally managed to have the messages published to a page wall, or even to an application’s page wall from an automated script. In this article I explain some of the problems I encountered and how to solved them. I hope this example may be of help if you are having trouble with this.
Publishing to a page’s wall
According to the Facebook documentation, we need to register an application in order to use it to publish messages to a page’s wall. The process is explained on that page, so this should be a good moment to read it.
The process could be summarized as follows:
- Create an application.
- Get the token for that application to manage the user’s pages (where the user is administrator of those pages).
- Get the specific token for that application through the user to a precise page.
While it should have been worked as it is explained on the documentation, I was having the following error:
(#200) The user hasn’t authorized the application to perform this action
So… why? According to the documentation, manage_pages
is the only permission required for an application to access a page, and everything seemed in order. Actually, it wasn’t. After some tests going back and forth and some googleing, I realized I didn’t have enough scope, and adding publish_stream
and read_stream
seemed to be a requirement for the application to actually write to page’s wall. In addition, offline_access
would produce a token that does not expire.
According to the updated information on the Facebook documentation page, the only permissions required to publish on a page wall as the page itself are manage_pages and publish_pages
Once this issue fixed, the following steps should lead to a successful publication in a page’s wall from an external script:
- Register your application here.
- Obtain a short-lived access token to manage pages from the authorized page administrator by opening this URL on your browser
https://www.facebook.com/dialog/oauth?client_id=$client_id&client_secret=$secret&redirect_uri=$uri&scope=manage_pages,publish_pages&response_type=token
; it will redirect to the redirect_uri
you specified with your $all_apps_token
as a query parameter. This token will last 2 hours.
- Exchange that short-lived token with a long-lived one by calling this endpoint:
https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token&client_id=$client_id&client_secret=$client_secret&fb_exchange_token=$all_apps_token
. This token will last 2 months.
- Get an access token to the precise page of that administrator
https://graph.facebook.com/$page_id?fields=access_token&access_token=$short_lived_token
. This token will not expire.
- Now you should be able to publish to that page with this token through a POST call to
https://graph.facebook.com/$page_id/feed
More detais here.
Here you are an example in PHP that uses this token to publish messages:
class Facebook
{
/**
* @var The page id to edit
*/
private $page_id = 'XXX';
/**
* @var the page access token given to the application above
*/
private $page_access_token = 'YYY';
/**
* @var The back-end service for page's wall
*/
private $post_url = '';
/**
* Constructor, sets the url's
*/
public function Facebook()
{
$this->post_url = 'https://graph.facebook.com/'.$this->page_id.'/feed';
}
/**
* Manages the POST message to post an update on a page wall
*
* @param array $data
* @return string the back-end response
* @private
*/
public function message($data)
{
// need token
$data['access_token'] = $this->page_access_token;
// init
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->post_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// execute and close
$return = curl_exec($ch);
curl_close($ch);
// end
return $return;
}
}
$facebook = new Facebook();
$facebook->message(array( 'message' => 'The status header',
'link' => 'http://theurltopoint.to',
'picture' => 'http://thepicturetoinclude.jpg',
'name' => 'Name of the picture, shown just above it',
'description' => 'Full description explaining whether the header or the picture' ) );
Publishing to an app’s wall
In some cases, we might want to publish to the application’s wall itself, so that there is no need to have a second application to publish to the first one’s wall.
According to some of the discussions on the matter that can be found on the internet, this should work by simply using $page_id
as the target and the same $page_id
to request the manage_pages permission.
In this case, we would follow the same process explained above, but slightly simplified:
- Register your application here.
- Obtain an access code for your application to your page
https://graph.facebook.com/oauth/access_token?type=client_cred&client_id=$id&client_secret=$secret
- Now you should be able to publish to the application’s wall with the token obtained through a POST call to
https://graph.facebook.com/$app_id/feed
However, Following the steps above, I obtained an error again:
{“error”:{“type”:”OAuthException”,”message”:”(#200) Posts where the actor is a page cannot also include a target_id”}}
Which was way confusing since there shouldn’t be any limitation according to Facebook’s documentation. After some searching and reading literature about (here and here), I discovered that publishing from an application to its own wall is doable, and in fact it works very well with the JS API provided by Facebook.
Then why the JS API would achieve the goal while its web service sister just throws a mystic error? It was quite obvious that they had to be using somewhat different service url’s… after inspecting the HTTP calls made by the JS API and was surprised to found that it is actually a GET (instead of POST
call):
https://graph.facebook.com/$app_id/feed?access_token=$token&callback=FB.ApiServer._callbacks.$some_callback_id&message=Hello%2C%20World!&method=post&pretty=0&sdk=joey
I just had to test this new url with the parameters of my application, and this time it just worked as expected:
https://graph.facebook.com/$app_id/feed?access_token=$api_access_token&message=Hello%2C%20World!&method=post
This is the only solution I have found so far to be able to publish messages from PHP on behalf of an application itself. It is a bit awful, but I haven’t found any other way to make this work, and the documentation provided by Facebook seems like knocking on a wall.
Has anybody found any better solution for this problem? Comments are welcome!