How to retrieve request info by request id? - facebook-graph-api

When I invite my friends I get back request_ids. After that I proceed those ids to get info about users invites have been sent to and create records in my database based on user's public profile info. But when I try to get request info by request id I get error message saying "Unsupported get request" nevertheless access token is fine.
// create data object to be sent to FB API
var data = new Object();
data.method = 'apprequests';
data.message = MESSAGE_TEXT;
data.display = 'iframe';
data.access_token = ACCESS_TOKEN;
data.show_error = 'Yes';
data.title = TITLE_TEXT;
// call FB API
FB.ui(data, function(aResponse)
{
var request_ids = '';
if (aResponse && aResponse.request_ids)
request_ids = aResponse.request_ids.join(',');
if (request_ids)
{
// send request_ids string to my server for further processing
}
});
Example of such broken request id: 1930910810837. Trying to get info for it like this:
https://graph.facebook.com/1930910810837?access_token=ACCESS_TOKEN
Please help me understand what is wrong. May it be issue on Facebook side, for example, Facebook returned broken id for some reason? Thank you!!!

Related

Facebook Matching API - Returns empty data for any other user

I have a problem when I use the Facebook Checkbox Plugin in order to connect my users to a Facebook chatbot. When they click and the checkbox is checked, I get their user reference, and sending him/her a message, I get the user page-scoped id.
Using this user page-scoped id, I should be able to get the user app-scoped id, that I need to get more information from this user.
In order to to this, I use the facebook Matching API, and it works great for my administrator user, but as soon as I login using any other user, even if it is registered as a developer, the data that I get from the matching API is empty.
[https://developers.facebook.com/docs/messenger-platform/identity/id-matching]
Anybody has an idea about what could be happening here? My app is live (not approved), and I believe the permissions and tokens are right... If there is a problem, it should be about tokens, but I'm not sure about this.
Here, some of my code:
const accessToken = config.facebook.unlimitedPageAccessToken;
const clientSecret = config.facebook.clientSecret;
const appsecretProof = CryptoJS.HmacSHA256(accessToken, clientSecret).toString(CryptoJS.enc.Hex);
request({
url: 'https://graph.facebook.com/v2.10/'+ recipientId +'/ids_for_apps',
qs: { access_token: accessToken, appsecret_proof: appsecretProof }
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
body = JSON.parse(body);
console.log("data --> " + JSON.stringify(body, null, 4));
const userAppId = body.data[0].id;
return userAppId;
} else {
console.error("Error trying to translate ID's.");
}
});
As I said, when I log in with any other user than the administrator, I get this:
{
"data": []
}
For every Facebook page, a user has a different psid. So until you get that page scoped id, you won't be able to send them a message. So may be what you can do is link the users to the page first to initialize the conversation.

Identity Server 3 Facebook Login Get Email

Identity server is implemented and working well. Google login is working and is returning several claims including email.
Facebook login is working, and my app is live and requests email permissions when a new user logs in.
The problem is that I can't get the email back from the oauth endpoint and I can't seem to find the access_token to manually request user information. All I have is a "code" returned from the facebook login endpoint.
Here's the IdentityServer setup.
var fb = new FacebookAuthenticationOptions
{
AuthenticationType = "Facebook",
SignInAsAuthenticationType = signInAsType,
AppId = ConfigurationManager.AppSettings["Facebook:AppId"],
AppSecret = ConfigurationManager.AppSettings["Facebook:AppSecret"]
};
fb.Scope.Add("email");
app.UseFacebookAuthentication(fb);
Then of course I've customized the AuthenticateLocalAsync method, but the claims I'm receiving only include name. No email claim.
Digging through the source code for identity server, I realized that there are some claims things happening to transform facebook claims, so I extended that class to debug into it and see if it was stripping out any claims, which it's not.
I also watched the http calls with fiddler, and I only see the following (apologies as code formatting doesn't work very good on urls. I tried to format the querystring params one their own lines but it didn't take)
(facebook.com)
/dialog/oauth
?response_type=code
&client_id=xxx
&redirect_uri=https%3A%2F%2Fidentity.[site].com%2Fid%2Fsignin-facebook
&scope=email
&state=xxx
(facebook.com)
/login.php
?skip_api_login=1
&api_key=xxx
&signed_next=1
&next=https%3A%2F%2Fwww.facebook.com%2Fv2.7%2Fdialog%2Foauth%3Fredirect_uri%3Dhttps%253A%252F%252Fidentity.[site].com%252Fid%252Fsignin-facebook%26state%3Dxxx%26scope%3Demail%26response_type%3Dcode%26client_id%3Dxxx%26ret%3Dlogin%26logger_id%3Dxxx&cancel_url=https%3A%2F%2Fidentity.[site].com%2Fid%2Fsignin-facebook%3Ferror%3Daccess_denied%26error_code%3D200%26error_description%3DPermissions%2Berror%26error_reason%3Duser_denied%26state%3Dxxx%23_%3D_
&display=page
&locale=en_US
&logger_id=xxx
(facebook.com)
POST /cookie/consent/?pv=1&dpr=1 HTTP/1.1
(facebook.com)
/login.php
?login_attempt=1
&next=https%3A%2F%2Fwww.facebook.com%2Fv2.7%2Fdialog%2Foauth%3Fredirect_uri%3Dhttps%253A%252F%252Fidentity.[site].com%252Fid%252Fsignin-facebook%26state%3Dxxx%26scope%3Demail%26response_type%3Dcode%26client_id%3Dxxx%26ret%3Dlogin%26logger_id%3Dxxx
&lwv=100
(facebook.com)
/v2.7/dialog/oauth
?redirect_uri=https%3A%2F%2Fidentity.[site].com%2Fid%2Fsignin-facebook
&state=xxx
&scope=email
&response_type=code
&client_id=xxx
&ret=login
&logger_id=xxx
&hash=xxx
(identity server)
/id/signin-facebook
?code=xxx
&state=xxx
I saw the code parameter on that last call and thought that maybe I could use the code there to get the access_token from the facebook API https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow
However when I tried that I get a message from the API telling me the code has already been used.
I also tried to change the UserInformationEndpoint to the FacebookAuthenticationOptions to force it to ask for the email by appending ?fields=email to the end of the default endpoint location, but that causes identity server to spit out the error "There was an error logging into the external provider. The error message is: access_denied".
I might be able to fix this all if I can change the middleware to send the request with response_type=id_token but I can't figure out how to do that or how to extract that access token when it gets returned in the first place to be able to use the Facebook C# sdk.
So I guess any help or direction at all would be awesome. I've spent countless hours researching and trying to solve the problem. All I need to do is get the email address of the logged-in user via IdentityServer3. Doesn't sound so hard and yet I'm stuck.
I finally figured this out. The answer has something to do with Mitra's comments although neither of those answers quite seemed to fit the bill, so I'm putting another one here. First, you need to request the access_token, not code (authorization code) from Facebook's Authentication endpoint. To do that, set it up like this
var fb = new FacebookAuthenticationOptions
{
AuthenticationType = "Facebook",
SignInAsAuthenticationType = signInAsType,
AppId = ConfigurationManager.AppSettings["Facebook:AppId"],
AppSecret = ConfigurationManager.AppSettings["Facebook:AppSecret"],
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook"));
return Task.FromResult(0);
}
}
};
fb.Scope.Add("email");
app.UseFacebookAuthentication(fb);
Then, you need to catch the response once it's logged in. I'm using the following file from the IdentityServer3 Samples Repository, which overrides (read, provides functionality) for the methods necessary to log a user in from external sites. From this response, I'm using the C# Facebook SDK with the newly returned access_token claim in the ExternalAuthenticationContext to request the fields I need and add them to the list of claims. Then I can use that information to create/log in the user.
public override async Task AuthenticateExternalAsync(ExternalAuthenticationContext ctx)
{
var externalUser = ctx.ExternalIdentity;
var claimsList = ctx.ExternalIdentity.Claims.ToList();
if (externalUser.Provider == "Facebook")
{
var extraClaims = GetAdditionalFacebookClaims(externalUser.Claims.First(claim => claim.Type == "urn:facebook:access_token"));
claimsList.Add(new Claim("email", extraClaims.First(k => k.Key == "email").Value.ToString()));
claimsList.Add(new Claim("given_name", extraClaims.First(k => k.Key == "first_name").Value.ToString()));
claimsList.Add(new Claim("family_name", extraClaims.First(k => k.Key == "last_name").Value.ToString()));
}
if (externalUser == null)
{
throw new ArgumentNullException("externalUser");
}
var user = await userManager.FindAsync(new Microsoft.AspNet.Identity.UserLoginInfo(externalUser.Provider, externalUser.ProviderId));
if (user == null)
{
ctx.AuthenticateResult = await ProcessNewExternalAccountAsync(externalUser.Provider, externalUser.ProviderId, claimsList);
}
else
{
ctx.AuthenticateResult = await ProcessExistingExternalAccountAsync(user.Id, externalUser.Provider, externalUser.ProviderId, claimsList);
}
}
And that's it! If you have any suggestions for simplifying this process, please let me know. I was going to modify this code to do perform the call to the API from FacebookAuthenticationOptions, but the Events property no longer exists apparently.
Edit: the GetAdditionalFacebookClaims method is simply a method that creates a new FacebookClient given the access token that was pulled out and queries the Facebook API for the other user claims you need. For example, my method looks like this:
protected static JsonObject GetAdditionalFacebookClaims(Claim accessToken)
{
var fb = new FacebookClient(accessToken.Value);
return fb.Get("me", new {fields = new[] {"email", "first_name", "last_name"}}) as JsonObject;
}

Facebook graph API fail to load resource bad request 400

I have the following code on my controller.js and works when I request from Facebook Graph 2.4
request.open("GET","https://graph.facebook.com/v2.4/katyperry/posts?"+access_token,true);
However this only returns few fields: message, story, created_time, and id.
I need some additional more fields: message, picture, likes, created_time, link, type, comments and object_id.
So I tried the following:
request.open("GET","https://graph.facebook.com/v2.4/katyperry?fields=posts.limit(2){message,picture,likes,created_time,link,type,comments,object_id}"+access_token,true);
The last one sent me the error:
Failed to load resource: the server responded with a status of 400 (Bad Request)
I tested both options the request on the Graph API Explorer and it worked properly. How can I get those extra fields? what am I missing?
I am adding the precedent code to show how access_token is builded:
var appID ="138429819833219";
var appSecret ="dada0a4d7f7717b0d37fd637d9e1522a";
var accessTokenRq = makeHttpRequest();
var httpString = 'https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id='+appID+'&client_secret='+appSecret;
accessTokenRq.open("GET",httpString,true);
accessTokenRq.send(null);
var access_token;
accessTokenRq.onreadystatechange = function() {
if (accessTokenRq.readyState == 4) {
access_token = accessTokenRq.responseText;
//alert("Hat geklappt - Trabajó :)");
var request = makeHttpRequest();
// the following request works
request.open("GET","https://graph.facebook.com/v2.2/katyperry/posts?"+access_token,true);
// next one don't - I checked inspector and access_token contains: 138429819833219|CewVrYOd86ctJ0HTP2X0XAS9m4o
request.open("GET","https://graph.facebook.com/v2.4/katyperry?fields=posts.limit(2){message,picture,likes,created_time,link,type,comments,object_id}"+access_token,true);
What is contained in the access_token variable? The request
/katyperry?fields=posts.limit(2){message,picture,likes,created_time,link,type,comments,object_id}
works in the Graph API Explorer, so I guess your access_token variable only contains the actual access token, and not the parameter key/value pair.
This
request.open("GET","https://graph.facebook.com/v2.4/katyperry?fields=posts.limit(2){message,picture,likes,created_time,link,type,comments,object_id}&access_token="+access_token,true);
should hopefully work then.
The error it was syntax, the right code as follow:
request.open("GET","https://graph.facebook.com/v2.4/katyperry/posts?limit=2&fields=message,picture,likes,created_time,link,type,comments,object_id&"+access_token,true);

How to call processing page via web service

I have a processing page and I want to run function process all via web service (add web reference into my C# window form app). My code below:
var context = new ModuleABCService.Screen() // limk web services: http://localhost:8686/soap/DMSBL009.asmx
{
CookieContainer = new CookieContainer(),
AllowAutoRedirect = true,
EnableDecompression = true,
Timeout = 60000
};
var loginResult = context.Login(string.Format("{0}#{1}", val.UserName, company), val.Password);
if (loginResult.Code != ErrorCode.OK)
{
throw new Exception(string.Format("Can not login {0}", company));
}
Content content = context.GetSchema();
context.Clear();
context.Submit(
new Command[]
{
content.Actions.ProcessAll
}
);
And I got an exception message:
System.Web.Services.Protocols.SoapExceptio:n Server was unable to process request. ---> PX.Data.PXUndefinedCompanyException: Unable determine proper company id for the request. at PX.Data.PXDatabaseProviderBase.getCompanyID(String tableName, companySetting& setting) in c:\Builders\4_10-2014_4_28-21_21_17-Full\Scripts\BuildTemp\NetTools\PX.Data\Database\Common\DbProviderBaseCompanies.cs:line 471...
Have you ever got this error before? Could you please give me any suggestion? Thank you so much!
Ok, I found out, because Acumatica's license

facebook create_event posts on my app's wall not the user's wall

i'm attempting to provide a facility on my site that allows a user to create a facebook event for their booking.
http://developers.facebook.com/docs/reference/api/event/
now im doing the correct process:
1) first getting authorisation from the user
https://graph.facebook.com/oauth/authorize?client_id=APP_ID&redirect_uri=http://urlimredirectingto.comtype=web_server
2) requesting for an access token with the "code" that is returned in step 1
https://graph.facebook.com/oauth/access_token
3) using the access_token to create the event ...
string facebookCreateUri = string.Format("https://graph.facebook.com/{0}/events", loggedInMember.FacebookUID);
var formData = new HttpUrlEncodedForm()
{
{"access_token", accessToken},
{"owner", loggedInMember.FacebookUID},
{"description", "nice event that should be on the owners wall"},
{"name", "event on the users wall"},
{"start_time", "1272718027"},
{"end_time", "1272718027"},
{"location", "rochester"},
{"privacy","OPEN"}
};
HttpContent content = HttpContent.Create(formData);
HttpClient client = new HttpClient();
var response = client.Post(facebookCreateUri, "application/x-www-form-urlencoded", content);
but the event is posted on my app's wall, not the user's wall. It shouldn't have anything to do with the authentication/access_token elements because i use the same process to post on the user's wall. (http://developers.facebook.com/docs/reference/api/status/) and that works just fine.
I came back with a solution, after a week of working at many features with Facebook SDK, it finally works!
protected void onPostEvent(object sender, EventArgs e)
{
if (CanvasAuthorizer.Authorize())
{
var fb = new FacebookWebClient(CanvasAuthorizer.FacebookWebRequest);
dynamic parameters = new ExpandoObject();
parameters.description = txtEvDett.Text;
parameters.name = txtEvName.Text;
parameters.start_time = DateTime.Now.ToString("yyyyMMdd");
parameters.end_time = DateTime.Now.AddDays(1).ToString("yyyyMMdd");
parameters.access_token = CanvasAuthorizer.FacebookWebRequest.AccessToken;
dynamic eventDet = fb.Post("me/events", parameters);
litEvent.Text = String.Format("You have created the event with ID: {0}", eventDet.id);
lnkEvent.Visible = true;
lnkEvent.NavigateUrl = String.Format("http://www.facebook.com/event.php?eid={0}", eventDet.id);
}
}
For events, you have to request the create_event permission.
You should use /me/events to post on your events.
I user the C# SDK for Facebook from Codeplex - last version available for dld (aug 2011 - v5.2.1).
Good luck!
I don;t see in your request for Authorization any permission.. base permissions are not enough to do the postings.
i used:
https://www.facebook.com/dialog/permissions.request?app_id=MY_APP_ID&next=MY_APP_URL&display=page&response_type=code&canvas=1&perms=publish_stream,user_about_me,email
This is in the context of a canvas app. where MY_APP_URL is the url from facebook of the app:
http://apps.facebook.com/MY_APP_NAME_OR_ID
See extended permissions for events and check event's page in documentation
[EDIT] - I came back, sorry, now i did a test, and indeed, it works for me, but only of i post on my app's wall; even if i provided the 'user_events' permission i get this error:
The remote server returned an error: (403) Forbidden when posting on a user's wall.
This being said, i also subscribe to this question.