Field permission with access token on facebook graph api - facebook-graph-api

I'm requesting graph.facebook.com like that :
graph.facebook.com/bordeauxmaville?fields=posts.limit(1).fields(message,picture,created_time,shares,likes,actions)&access_token=MYAPIKEY|MYAPPSECRET
You can try it with your own access-token on :
https://developers.facebook.com/tools/explorer/?method=GET&path=bordeauxmaville%3Ffields%3Dposts.limit(1).fields(message%2Cpicture%2Ccreated_time%2Cshares%2Clikes%2Cactions)
I get message, picture, created_time, shares, and likes but with the last : actions, the graph api writes : field is empty or disallowed by the access-token.
It works with the access-token of my Facebook account with the permission user_friends enabled.
On my app's authorizations parameters on developers.facebook.com I tried to set :
user_actions.news, manage_pages, read_stream, and user_friends
But I still can't get the actions field.
==>Which parameter should I set to get this field with the same access token ?
Thx
--It's my First Ask
--I'm French and trying to speak English, sorry for grammar

I solved the problem by using the "id" field given with the request :
graph.facebook.com/bordeauxmaville?fields=posts.limit(1).fields(message,picture,created_time,shares,likes)&access_token=MYAPIKEY|MYAPPSECRET
I got : "10655XXXX47646_530492XXX87198"
I split it into two string :
String str1 = "10655XXXX47646";
String str2 = "530492XXX87198";
String link = "https://www.facebook.com/" + str1 + "/posts/" + str2
I finally got the same information as in the disallowed field named "actions".

Related

Get ACCESS_TOKEN_SCOPE_INSUFFICIENT error migrating to People API

I have a desktop Java app that I am migrating from Google Contacts API to People API. I have some of it working. For example, I can retrieve contact information. But when I tried to create a new contact, I get the following error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
POST https://people.googleapis.com/v1/people:createContact
{
"code" : 403,
"details" : [ {
"#type" : "type.googleapis.com/google.rpc.ErrorInfo",
"reason" : "ACCESS_TOKEN_SCOPE_INSUFFICIENT"
} ],
"errors" : [ {
"domain" : "global",
"message" : "Insufficient Permission",
"reason" : "insufficientPermissions"
} ],
"message" : "Request had insufficient authentication scopes.",
"status" : "PERMISSION_DENIED"
}
Here's the relevant code:
protected void createContact() throws Exception {
Credential credential = authorize(PeopleServiceScopes.CONTACTS, "people");
PeopleService service = new PeopleService.Builder(
httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
Person contactToCreate = new Person();
List<Name> names = new ArrayList<Name>();
names.add(new Name().setGivenName("John").setFamilyName("Doe"));
contactToCreate.setNames(names);
Person createdContact = service.people().createContact(contactToCreate).execute();
System.out.println("CREATED Contact: " + createdContact.getNames().get(0).getDisplayName());
}
protected Credential authorize(String scope, String subDir) throws Exception {
File dataStoreDir = new File(System.getProperty("user.home"), ".store/myapp/" + cfg.dataStore + "/" + subDir);
// initialize the transport
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
// initialize the data store factory
dataStoreFactory = new FileDataStoreFactory(dataStoreDir);
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(SyncMgr.class.getResourceAsStream("/client_secrets.json")));
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=calendar "
+ "into /client_secrets.json");
System.exit(1);
}
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(scope)).setDataStoreFactory(dataStoreFactory).build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize(cfg.gUser);
}
When I first ran it, I had the scope set to CONTACTS_READONLY. And I got the consent screen. But then I changed the scope to CONTACTS when I added the code to create a new contact. And that's when I got the ACCESS_TOKEN_SCOPE_INSUFFICIENT error.
I saw in another post that I need to force your app to reauthorize the user when you change the scope, so that you get the consent screen again. But I'm not sure how to do that. Any suggestions?
Thanks.
UPDATE 1/4/22
I tried Gabriel's suggestion of removing access to the application. After removing access, I ran the application again. This time I got this error on the execute() call:
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
POST https://oauth2.googleapis.com/token
{
"error" : "invalid_grant",
"error_description" : "Token has been expired or revoked."
}
And even the execute() statement that worked before to retrieve contacts is giving the same error now.
My application also used the Calendar API. I didn't touch that code. But when I try to use it, I get the same "invalid_grant" error. What do I do now?
You appear to be using the People.createContact method. If we take a look at the documentation we will see that this method requires a consent to the following scope of permissions from the user
Now if we check your code you apear to be using
Credential credential = authorize(PeopleServiceScopes.CONTACTS, "people");
Which is the exact scope needed. But you oringally had readonly there. So when your code ran the first time the user authorized to the read only scope and not the full contacts scope and your stuck.
The key here is this section of code.
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(scope)).setDataStoreFactory(dataStoreFactory).build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize(cfg.gUser);
Kindly note I am not a Java developer I am a .net developer. The libraries are very close and i have been helping with questions this in both languages for years.
dataStoreFactory is where the consent from the user is stored. There should be a json file some where in your directory structure with the users name associated with it this is how your system reloads it. When your code runs it will look for a file in that directory with cfg.gUser name.
There should be a way in the Java client library to force it to rerequest authorization of the user. prompt type force. But i will have to look around to see how to do it in java.
The easiest solution now would be to find that directory and delete the file for the user or just change the users name cfg.gUser to cfg.gUser +"test" or something this will cause the name to change and the file name as well. Forcing it to prompt the user for authorization again.
This time when it requests consent take note which scope of permissions it asks for.
Token has been expired or revoked.
This is probably due to the fact that your refresh tokens are expiring. When your application is in the testing phase the refresh tokens are expired or revoked automatically by google after seven days.
This is something new and something that Google added in the last year or so. Unfortunately the client libraries were not designed to request access again if the refresh token was expired in this manner.
If you are looking to retrieve the consent screen again you can remove access to your application from your account settings by following the steps in this documentation and then try to authorize the app again. As you mentioned, the error received is due to the scope that was granted with authorization was CONTACTS_READONLY instead of CONTACTS when checking the authorization scope for this specific create contacts method.

Why am I getting this Authentication required error even though I am using my client id and client secret for the Foursquare API?

I getting back into Python and wanted to use the pyfoursquare package to access the Foursquare API. I'm trying to get information about venues using the venues method in the API class. I'm primarily trying to find out whether a venue page is verified with Foursquare or not. When I provide my client id, client secret, and venue id I keep getting back an error that states "Authentication required", which doesn't makes sense because I'm providing that information. Any help would be great. Thank you.
import pyfoursquare as foursquare
client_id = ""
client_secret = ""
callback = ""
auth = foursquare.OAuthHandler(client_id, client_secret, callback)
api = foursquare.API(auth)
result = api.venues("4e011a3e62843b639cfa9449")
print result[0].name
Let me know if you would like to see the error message. Thanks again.
I believe you are skipping the step of grabbing your OAuth2 access token, so you're not technically authenticated.
Have a look at the following instructions, under "How to Use It":
https://github.com/marcelcaraciolo/foursquare
The lines that might be useful to you are:
#First Redirect the user who wish to authenticate to.
#It will be create the authorization url for your app
auth_url = auth.get_authorization_url()
print 'Please authorize: ' + auth_url
#If the user accepts, it will be redirected back
#to your registered REDIRECT_URI.
#It will give you a code as
#https://YOUR_REGISTERED_REDIRECT_URI/?code=CODE
code = raw_input('The code: ').strip()
#Now your server will make a request for
#the access token. You can save this
#for future access for your app for this user
access_token = auth.get_access_token(code)
print 'Your access token is ' + access_token

Posting data to Silex app ( jwt authentication using cnam/security-jwt-service-provider )

I am creating web service using silex micro framework. This is first time i am using it and I dont have prior knowledge on symfony. I could be able to understand how silex works and how to write controller providers , service providers etc ..
I couldnt work out authentication for my webservice.
I want to use JWT authentication and I found this cnam/security-jwt-service-provider extending firebase/php-jwt.
I set it up right and I get this output when I access protected resource
{"message":"A Token was not found in the TokenStorage."}
which is correct.
Question: I want to post the username , password to application and get token back. ( username=admin , password=foo )
I am using postman chrome extension ( also used Advanced rest client ) to post values to url ( http://silex.dev/api/login)
Post data I am sending
Key=> username Value=> admin
Key=> password Value=> foo
I also tried
Key=> _username Value=> admin
Key=> _password Value=> foo
Aldo tried key vaule pairs in basic auth headers.
response I get id
{
"success": false,
"error": "Invalid credentials"
}
When I debug the Application I see no post data at all.
$vars = json_decode($request->getContent(), true);
I get null $var.
PS: I know I will get a valid token back if I get these values posted correctly because I edited values from empty to correct values in breakpoint.
Apparently I should send data in json format and should set content-type appication/json
eg:
{
"_username":"admin",
"_password":"foo"
}
and response will something be like
{
success: true
token: "eyJ0eXAiOisKV1diLCJfbGgiOhJIjzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJleHAiOjE0Mzk5MDUxMjh9.DMdXAv2Ay16iI1UQbHZABLCU_gsD_j9-gEU2M2L2MFQ"
}

Getting feeds for Public Pages of Facebook using Spring Social or Restfb

I need to build a server which would get the public feed details of various companies/ brands. For example, I should be able to get the feed for last one week for Cocacola (facebook.com/cocacolaindia) , Pepsi, Levis etc. Since I am only looking for public feeds I thought I dont need to use OAuth for authorization but I see no other way to get this info. For example - i tried below code but none of last three ways works.
String acessTok = "{my app id}|{app seceret key}"; //App level token
Facebook facebook = new FacebookTemplate(acessTok);
FacebookProfile profile = facebook.userOperations().getUserProfile("cocacolaIndia");
Page page = facebook.pageOperations().getPage("cocacolaIndia");
List<Post> list= facebook.feedOperations().getFeed("cocacolaIndia");
Is there a way out ? I can use httpurl to call http://graph.facebook.com/ and
parse the json but then would need my own api's to get different fields which I don't want to do..
You can use an App Access Token. Here's some RestFB example.
AccessToken accessToken = new DefaultFacebookClient().obtainAppAccessToken(MY_APP_ID, MY_APP_SECRET);
Now you can build your FacebookClient with this new access token.
With fetchConnection you can fetch the public posts from the desired "fanpage".
I had the same Problem.
I was trying to access the public Posts of an Facebook Page only with the AppId and AppSecret.
The following worked for me:
private Facebook facebook;
...
this.facebook = new FacebookTemplate("{AppId}|{AppSecret}");
...
Collection<Post> posts =this.facebook.feedOperations().getPosts("{PageId}");
I hope this is helpful.

PYTHON FB API , get token to check public post condivision

i am lookin for check te sharing of a page, for examples bill gates post:
page = '10152525603066961'
token = '***'
graph = facebook.GraphAPI(token)
profile = graph.get_object(page)
posts = graph.get_connections(profile['id'], 'sharedposts')
print posts['data'][0]['from']
it works with the graph access Token, but it will expire and it don't work with App Token.
how can i get a Token that works and will not expire?
Only App Access Tokens and Extended Page Access Tokens are valid forever. What you need is a User Access Token, you can only extend that one to 60 days.
More information:
https://developers.facebook.com/docs/facebook-login/access-tokens
http://www.devils-heaven.com/facebook-access-tokens/
https://developers.facebook.com/docs/facebook-login/v2.2