Facebook API partially working in production - facebook-graph-api

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

Related

How can I post content to an app users page, linking to their website, from an app running on my website?

I am creating an app for a client that allows their clients to schedule posts and post to facebook from the app.
Clients log into my-domain and the app requests permissions to post to their pages. I am fine with getting a list of pages from facebook and requesting the pages_read_engagement and pages_manage_posts permissions.
My app needs to allow users to select an image (hosted on my-domain) and post that with a link that points at their-domain, along with the post content. Here is an example of an api call I am making using the Javascript SDK (from my app at my-domain):
FB.api('/' + page_id + '/feed', 'POST', {
message: post.content,
link: user.website,
picture: image.url,
access_token: page_access_token
}, () => {})
I get back an error:
(#100) Only owners of the URL have the ability to specify the picture, name, thumbnail or description params.
I have had a read through the domain verification docs but I don't understand what I need to do next. Do all of my users have to verify their own domain via DNS verification? Is there a way for me to allow users to post to their own pages, linking to their websites, from my app, without them having to do anything technical? Am I missing something?

How to manage admin authentication with Oauth flow to Microsoft Graph API in Rails App

I am deeply struggling to find the right flow. I have a rails app, registered on Microsft App portal (with Id, Pwd and Scopes). To be be as simple as possible : I need to have access through my app to all emails (only read) of a company. It is a server app, which processes informations during the night.
What I understood and tried :
Get a login link for the administrator of the company :
https://login.microsoftonline.com/{TENANT_ID}/oauth2/authorize?client_id={MY_APP_ID}&response_type=code&redirect_uri=MY_APP_ADDRESS&response_mode=query&prompt=admin_consent
In callback, I do get a code in params. From that code, I get a token with a POST request, specifying :
client_id: MY_APP_ID,
grant_type: "authorization_code",
code: MY_RECEIVED_CODE,
redirect_uri: MY_APP_ADDRESS,
client_secret: MY_CLIENT_SECRET,
resource: "https://graph.microsoft.com/"
From that I get a Token. A simple request to get messages works well for the administrator mailbox (the one who validated the access) ; 'Access is denied' when I try for any other person from the organization.
Last point. Scopes defined in Microsoft App portal : Group.Read.All and Mail.Read (both for apps or delegated services)
What is the right way to get that done ? Thanks !
add the query parameter prompt=admin_consent to the authorization request, that way the admin will consent on behalf of the entire organization and not just for his/herself.

ASP.NET WebApi Identity Facebook login access denied

I'm building a ASP.NET (4.6) WebApi project and I'm using ASP.NET Identity to authenticate with Facebook, Google and Microsoft to my API. I have managed to authenticate with Google and Microsoft, but not with Facebook.
I'm using Visual Studio 2015
The problem is that I get access denied every time I authenticate. The scenario goes like this:
I make an API call to localhost:2975/api/Account/ExternalLogins?returnUrl=%2F&generateState=true through my browser.
I receive a link to my API for every external provider my API support. In the Facebook case I got localhost:2975/api/Account/ExternalLogin?provider=Facebook&response_type=token&client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A2975%2F&state=99...01
I go to that link with my browser, and gets redirected to the Facebook login page.
I authenticate to Facebook, and a dialog window appears and asks permission for the requested information about me.
I accept and gets redirected back to my API with the error "access_denied". localhost:2975/api/Account/ExternalLogin gets called.
I haven't figured out where the problem comes from, whether its some permission setting in my Facebook app, the Facebook user I log in with, or if the problem lies in the ASP.NET Identity template.
Regarding Facebook I have created a test app of my app, as well as pushed it as a live app. I can find the app on my Facebook profile, and I've removed it several times. My Facebook profile has the administrator role of the app. I have created test users, as well as added a friend of mine as developer/tester of the app. The problem remains. I read somewhere that there should be a pending request for the app that I should accept, but I haven't found any.
Regarding the ASP.NET Identity template the error is received very early in the process:
AccountController.cs:
public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
{
if (error != null)
{
// This is where the API comes in step 5 above
return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
}
if (!User.Identity.IsAuthenticated)
{
// This is where the API comes in step 2 above before it redirects me to Facebook login
return new ChallengeResult(provider, this);
}
ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
// Untouched logic
// ....
}
When I use Google Chromes Network tool I can see that I gets redirected to this link:
facebook.com/login.php?skip_api_login=1&api_key=XXX&signed_next=1&next=https%3A%2F%2Fwww.facebook.com%2Fv2.6%2Fdialog%2Foauth%3Fredirect_uri%3Dhttp%253A%252F%252Flocalhost%253A2975%252Fsignin-facebook%26state%3D...%26scope%3Demail%252Cpublic_profile%26response_type%3Dcode%26client_id%3D...%26ret%3Dlogin%26logger_id%3D...&cancel_url=http%3A%2F%2Flocalhost%3A2975%2Fsignin-facebook%3Ferror%3Daccess_denied%26error_code%3D200%26error_description%3DPermissions%2Berror%26error_reason%3Duser_denied%26state%3D...%23_%3D_&display=page&locale=sv_SE&logger_id=...
There is a cancel url with predefined error: "access_denied", error code: 200, reason: "user_denied", so maybe the "access_denied" error I receive isn't very accurate?
Other relevant code I can come up with is in Startup.Auth.cs (I never get to the OnAuthenticated part though):
var facebookOptions = new FacebookAuthenticationOptions()
{
AppId = "XXX",
AppSecret = "XXX",
Scope = { "email", "public_profile" }
};
facebookOptions.Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook"));
context.Identity.AddClaim(new Claim("urn:facebook:email", context.Email, ClaimValueTypes.Email, "Facebook"));
return Task.FromResult(0);
}
};
app.UseFacebookAuthentication(facebookOptions);
It feels like I've tried everything. Any ideas on how to solve this?
Thanks in advance!
Update NuGet packages solved my issue.
From this post in the line
context.Identity.AddClaim(new Claim("urn:facebook:email", context.Email, ClaimValueTypes.Email, "Facebook"));
the context.Email is null.
try to update the nuget package which Microsoft.Owin.Security,Microsoft.Owin.Security.Facebook and so on
Those who were unable to resolve the issue by just updating nuget packages, it might help.
Our Web App was working fine with External Login, what was happening before was our app redirected the users to Facebook or Google for authentication and returned the relevant details from their account. But then this issue arises in which the redirect url contains an error with a value Access_Denied. which is not descriptive at all so you need to manually find the errors.
After a lot of debugging and nuget updates I was still unable to resolve the issue and then it turned out the solution was the IP whitelisting for the server as our IT team and few developers changed the the server settings or migrated the website to new server which obviously had a different IP. Hence, I added the IP address in Facebook dev console to whitelist the address and it worked like a charm.
Whereas, Google authentication was fixed without whitelisting anything, just updating the nuget packages did the job.

notification from app request Facebook not received

Im making an application on Phonegap, and therefore using javascript. I have added the facebook plugin, and everything seems to work fine. The user can log in and make app requests to friends using the FB.ui:
FB.ui({method: 'apprequests',
message: 'Try this application, and get ready to Guess This Sound!'
}, requestCallback);
The dialog pop up, and when I send an invitation my requestCallback method return OK
function requestCallback(response){
alert("response " + response);
}
However, my friends do not receive any notification about the request. My application is no longer i sandbox mode, and I can't figure out whats the problem is. Since Im using phonegap, I have added ios and android platform on facebook, and I guess no canvas URL is needed.
UPDATE
Some users do now receive the notifications from the application, but not everyone.However, when my friend clicks on the notification he receive this message: "The requested page can not be viewed right now. It could be temporary unavailable." Is it because my application is not available on google play and app store for the moment?
You have to Add app in your developer account
facebook -> Apps -> "You app" -> Setting -> add platform -> App on Facebook -> Add any URl
Now you will get app request notification
The problem was due to wrong set up in facebook developer API. The error still remains, but is because the app is not released yet. To see the solution to this, see:
Facebook invite request error android

Why would the same FB insights query work in a browser and Graph API Explorer, but return null with PHP SDK?

As you can see in this picture
I have a valid long-life Access Token for my app (390068587730802) with the following permissions: ads_management, manage_pages, read_insights, user_friends
I can use it to get data on another accessible app (50813163906) using the Graph API Explorer,
$facebook->getUser(); does return my user id
HOWEVER, I get NULL from the same request via the PHP SDK.
I have tested locally on xampp and on an apache server. I have updated the PHP SDK today to include the latest changes surrounding offline_access and long life tokens. I have read dozens of posts and FB documentation. I´m glad to read more you think will help, but please note that my token is valid, long lived, and I am successfully getting "/me" from the graph API. All of this happens under http or https.
UPDATE "Facebook: Sorry, something went wrong. We're working on getting this fixed as soon as we can."
As seen in this next picture below, I´ve var_dump´d the CURL options to verify the correct access_token and URL is actually being called. Furthermore, I can copy these urls directly into the browser and get complete data return!!
If during my testing I have created "two active sessions" - as some docs warn - how can you test for that? Most importantly, why would the same FB insights query work in the Graph API Explorer, but return null with PHP SDK?
It turns out that "since=30 days ago" was giving a 400 (bad request) response. This error was not showing up in the CURL errors. Only via
curl_getinfo($this -> ch,CURLINFO_HTTP_CODE);
When i changed
$period = "{$period} days ago";
to
$period = urlencode("{$period} days ago");
//or
$period = strtotime("- {$period} days");
everything worked via CURL.