Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Picture post to Facebook ends up in the wrong place

I am trying to post a picture to Facebook page with id= 226338660793052, but it keeps ending up in /me/photos. What am I doing wrong?

NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   imageToSend, @"source",
                                   facebookMessageTextView.text, @"message",
                                   nil];
[facebook requestWithGraphPath:@"/226338660793052/photos" andParams:params andHttpMethod:@"POST" andDelegate:self]; 

I get no error message. I get nothing, except that the photo ends up in my own album, me/photos, and not in the album of 226338660793052/photos.

But when I just post a message to that page, I do get a successful post on the timeline of the page:

NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   @"http://www.bitsonthego.com", @"link",
                                   @"my profile", @"name",
                                   facebookMessageTextView.text, @"message",
                                   nil];
[facebook requestWithGraphPath:@"/226338660793052/feed" andParams:params andHttpMethod:@"POST" andDelegate:self]; 

What am I missing here? I know this must be possible, as I can use a browser to upload a picture to the desired page, as a random non-admin user. I just can't seem to do it from the graph API.

UPDATE:

I've resolved part of the issue. You have to use the destination page's access_token. This is how you get it:

    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   @"access_token",  @"fields",
                                   nil];
    FBRequest *request = [facebook requestWithGraphPath:@"226338660793052" andParams:params andDelegate:self];

When you get the result, then you add it to the transaction above:

    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   image, @"source",
                                  [result objectForKey:@"access_token"], @"access_token",
                                   facebookMessageTextView.text, @"message",
                                   nil];

    FBRequest *request = [facebook requestWithGraphPath:[[result objectForKey:@"id"] stringByAppendingString:@"/photos"] andParams:params andHttpMethod:@"POST" andDelegate:self];

But, this won't work because Facebook.m will replace this new access_token with the default user access_token, so I made a change to Facebook.m at around line 166, from:

  if ([self isSessionValid]) {
        [params setValue:self.accessToken forKey:@"access_token"];
  }

to:

  if ([self isSessionValid]) {
    if ([params valueForKey:@"access_token"] == nil)
        [params setValue:self.accessToken forKey:@"access_token"];
  }

That keeps an access code you specify as part of the params, from getting clobbered by the Facebook.accessToken. Now this will post the picture to the page I am interested in.

However, this works because I am an admin on the page in question. Other users will not be able to post pictures and the pictures again will end up in their own albums, because the call to get an access_token for the page will return nil.

According to Facebook docs, if the page is unrestricted, as this page is, then it should be possible to post a picture to it:

NOTE:

For connections that require an access token, you can use any valid access token if the page is public and not restricted. Connections on restricted pages require a user access token and are only visible to users who meet the restriction criteria (e.g. age) set on the page.

Did I mention that my page is public and not restricted?

Page Access Tokens

To perform the following operations as a Page, and not the current user, you must use the Page's access token, not the user access token commonly used for reading Graph API objects. This access token can be retrieved by issuing an HTTP GET to /USER_ID/accounts with the manage_pages permission. This will return a list of Pages (including application profilePages) to which the user has administrative access, along with access_tokens for those Pages. Alternatively, you can get a page access token for a single, specific, page by issuing an HTTP GET to /PAGE_ID?fields=access_token with themanage_pages permission, as described above. Publishing to a Page also requires the publish_stream permission, unless otherwise noted.

So how does one post a picture to a public/unrestricted page? I can do it from any browser, so it is possible, but how is it done using the Graph API? Given that I can post to the feed with no access_token shenanigans, what about posting a picture is different?

In summary, what I am trying to do is to post a picture, not just a thumbnail URL, to a public/non-restricted page, using the Graph API.

like image 898
mahboudz Avatar asked Feb 21 '12 08:02

mahboudz


1 Answers

My issue as well at the moment! I believe the problem is with the lines in framework you rewrote, which became impossible since the Facebook SDK is now static library which can't be edited. However, I've figured out how to create the photos posts without having to change the SDK - I create new token data with the token string I get from an app:

FBAccessTokenData *tokenData = [FBAccessTokenData createTokenFromString:tokenString permissions:[FBSession activeSession].accessTokenData.permissions expirationDate:[FBSession activeSession].accessTokenData.expirationDate loginType:FBSessionLoginTypeFacebookApplication refreshDate:nil];

then I create new FBSession with fb appID (and nullCacheInstance, somehow it seems to be important):

FBSession *sessionFb = [[FBSession alloc] initWithAppID:appID permissions:[NSArray arrayWithObjects: @"publish_stream", @"manage_pages", nil] urlSchemeSuffix:nil tokenCacheStrategy:[FBSessionTokenCachingStrategy nullCacheInstance]];

and then I open the newly created session with tokenData created up, set this new session to be the active session, and it works!

[sessionFb openFromAccessTokenData:tokenData completionHandler:^(FBSession *session, FBSessionState status, NSError *error)
 {
 }];

[FBSession setActiveSession:sessionFb];

Then calling request for PageAppID/photos with Post parameters and source image works, and it posts image on Facebook Page wall as being from itself!

[FBRequestConnection startWithGraphPath:[NSString stringWithFormat:@"%@/photos", PageAppID] parameters:params HTTPMethod:@"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
 }];

I think the changing of activeSession is the thing that's similar to changing the lines in Facebook.m

hope this helps someone today

like image 90
Gyfis Avatar answered Oct 13 '22 00:10

Gyfis