I´m using Facebook graph API thru the JS SDK and the Php SDK. While all is working in development environement, in production, on a shared hosting, it is partially working and this is quite disturbing.
First, the facebook app is exatly the same between tests in dev and tests in prod, I´ve just changed the domain.
Second, outbound ports 80 and 443 are opened on my hosting provider.
Dev : windows, php 5.3.8, curl 7.21.7
Prod: Linux, php 5.3.17, curl 7.24.0
I´m presenting here under the results of my tests.
Dev
- Publish a message in user : OK
- Publish a message in page : OK
- Publish a photo in user : OK
- Publish a photo in page : OK
- Delete a message in user : OK
- Delete a message in page : OK
- Delete a photo in user : OK
- Delete o photo in page : OK
Prod
- Publish a message in user : OK
- Publish a message in page : OK
- Publish a photo in user : OK
- Publish a photo in page : OAuthException: An unexpected error has
occurred. Please retry your request later. - Delete a message in user : not tested
- Delete a message in page : OAuthException: (#100) Invalid parameter
- Delete a photo in user : OAuthException: (#221) Photo not visible
- Delete a photo in page : unable to test
Does any one have a clue on this ? How can I debug what is going on (I on a shared hosting provider) ?
EDIT
This is the code to publish a photo on a page which is KO in prod
// I´m using Yii framework with a wrapper around Facebook php sdk
// retreiving the page acces token
$page_at = Yii::app()->facebook->api('/'.$fb_page->page_id.'?fields=access_token');
Yii::app()->facebook->setFileUploadSupport(true);
// model contains the post data from the user. For the message it is a text area
// Yii::app()->params->uploadPath is a global param with path where the image resides.
// Directory separator where created with php´s DIRECTORY_SEPARATOR
$data = array(
"message" => $model->attributes['descricao'],
"source" => "@".Yii::app()->params->uploadPath.$model->image,
"access_token" => $page_at['access_token']);
$result = Yii::app()->facebook->api('/'.$fb_page->page_id.'/photos', "POST", $data);
This is the code to publish to a user which is OK in prod
Yii::app()->facebook->setFileUploadSupport(true);
$data = array(
"message" => $model->attributes['descricao'],
"source" => "@".Yii::app()->params->uploadPath.$model->image,
);
$result = Yii::app()->facebook->api('/'.$fb_page->page_id.'/photos', "POST", $data);
The only difference between the two is that I don´t need the access_token for the user
EDIT
The delete problem seems to be resolved by putting the page access token in the url instead of putting it in the post. Strange since I remember I was forced to put it in the post in my dev to make the delete work…
Now I´m focused on the image post for which I´m getting the same behavior after a zilion different combinations. The API call is doing something despite the error : it creates the app album if it does not exists but the image is not uploaded.
Could it be related to this bug : https://developers.facebook.com/bugs/376442565760536?browse=search_5099ba94055685677909148
EDIT
Following cpiko advice I´ve worked on CRLF potential problems. I´ve set CURLOPT_CRLF to true. Now I get : OAuthException: A user access token is required to request this resource.
EDIT
After fighting a little with fiddler I could compare the facebook api curl request sent between dev and prod. Well…. absolutly identicals. I´m starting to be out of ideas…
Well after so much tests, what was blocking is the Country restriction setting in the facebook app advanced settings.
The problem is that my hosting provider is in the US and I restricted the facebook app to my country (which is not US). What is strange is that this setting only applies to photo upload in my case and not the rest (feed posting for example). Also, it does not restrict based on the client (browser) origin but in this case fron the server originating the curl.
UPDATE
The error upon deleting a user photo (Photo not visible) was different. Even if I was the publisher of the photo thru my facebook app, I had to add the user_photos permission so I could delete it