I'm working on a mobile project and decided to try out the LWUIT framework for development. So far it has been quite interesting although I wish the documentation was a bit better.
I run into a problem trying to post content to facebook using the recently released Facebook API. I'm able to authenticate without issues. However, when I try to post comments to the user's wall, I get a http 404 error.
Has anyone else had this sort of challenge. Below is an excerpt from my code;
protected boolean onShareScreenPost() {
// If the resource file changes the names of components this call will break notifying you that you should fix the code
//boolean val = super.onShareScreenPost();
Form shareForm = Display.getInstance().getCurrent();
final TextField shareField = findShareField(shareForm);
String postText = shareField.getText();
try {
makeFacebookAuthenticationRequest();
FaceBookAccess.getInstance().postOnWall(me.getId(), postText);
} catch (IOException ex) {
ex.printStackTrace();
//Include a dialog saying unable to post or connect to the internet or whatever
}
return true;
}
private void makeFacebookAuthenticationRequest() throws IOException {
FaceBookAccess.getInstance().authenticate("125527160846284", "http://a.b.c/", new String[]{ "publish_stream"});
me = new User();
FaceBookAccess.getInstance().getUser("me", me, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("returned user");
}
});
}
Seeing this question 24 hours later makes me feel a bit silly.
The answer was quite simple and staring me in the face all along. I needed to wait for the Facebook API to return a User object before making additional calls to the API. Failure to do this resulted in a null reference for my user object and this was being used in the wall post request causing the facebook api to return a http 404.
Hope this helps someone...
Related
I am using Volley to submit POST requests to the Facebook Graph API in order to retrieve information about photos and videos from a user account using their BATCH facility so I get it all in one go (rather than making one call for photos, one for videos). The first call works perfectly:
request = new StringRequest(Request.Method.POST,
"https://graph.facebook.com",
future,
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Timber.e("Got VolleyError: %s", error.getMessage());
}
}) {
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=" + getParamsEncoding();
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
JSONArray batchRequest = new JSONArray();
JSONObject photoRequest = new JSONObject();
JSONObject videoRequest = new JSONObject();
try {
photoRequest.put("method", "GET");
photoRequest.put("relative_url",facebookUserID + String.format("?fields=photos.limit(%1$s){id,created_time,images{source},picture}",batchSize));
videoRequest.put("method", "GET");
videoRequest.put("relative_url",facebookUserID + String.format("?fields=videos.limit(%1$s){id,created_time,source,picture}",batchSize));
batchRequest.put(photoRequest);
batchRequest.put(videoRequest);
} catch (JSONException e) {
Timber.d("Lifecycle: Exception constructing batch request: %s", e.getMessage());
return null;
}
//try {
// Timber.d("Lifecycle: batchRequest: %s", batchRequest.toString(2));
//} catch (JSONException e) {
// e.printStackTrace();
//}
params.put("batch", batchRequest.toString());
params.put("include_headers", "false");
params.put(FB_BASE_ACCESSTOKEN_KEY, facebookToken);
return params;
}
};
InTouchUtils.addToRequestQueue(request);
// Using a blocking volley request, this chain has been called on a separate async task
// See SO: https://stackoverflow.com/questions/16904741/can-i-do-a-synchronous-request-with-volley
facebookRetval = future.get(VOLLEY_REQUEST_DEFAULT_TIMEOUT, TimeUnit.SECONDS);
returnResult = parseBatchRequest(facebookRetval);
The returned JSON has all the fields I've requested, as well as the pagination block with cursors, and a "next" and/or "previous" url, per the Facebook documentation.
A "next" URL looks something like:
https://graph.facebook.com/v7.0/FACEBOOK_ID_HERE/photos?access_token=ACCESS_TOKEN_HERE&fields=id,created_time,images{source},picture&limit=5&after=AFTER_TOKEN_HERE
There is one of these that gets passed back from the batch operation for each of the original GET operations (assuming both photos and videos have greater than LIMIT items).
Again, this part works fine.
But when I try and use that "next" URL to create another BATCH call, it fails with an "unsupported GET operation" error. This is true even though I can use a standard Volley GET using that exact same URL and it works perfectly.
I have tried using the "https://graph.facebook.com" portion of the above URL as the root of the POST (like what worked in the initial call), and everything after that as the "relative_url" parameter. No go.
Then I tried parsing out just the "after" portion of the "next" url, and constructing a new relative_url that was exactly like the first one, but tacking on a "&after=" + AFTER_VALUE to it as the relative_url. No go - in fact, while this succeeded in making the call, I keep getting the initial batch over and over and over. It is like it is ignoring the "&after=" parameter.
For now I am back to making two GET calls (one for photos, one for videos) just using the NEXT url as long as it keeps being passed back to me. This works fine, but obviously I'm making two network calls instead of the single batch one.
Ideas?
A little more examination revealed that I had made a string parsing error on the subsequent batch operation, and was inadvertently including a forward slash when I should not have been.
For those new to using the batch API, the lesson is that you need "https://graph.facebook.com" as the POST url (no trailing forward slash), then your relative url should NOT start with a forward slash. So the URL I was trying to utilize on calls 2..N like this:
https://graph.facebook.com/v7.0/FACEBOOK_ID_HERE/photos?access_token=ACCESS_TOKEN_HERE&fields=id,created_time,images{source},picture&limit=5&after=AFTER_TOKEN_HERE
should be broken out as:
photoRequest.put("relative_url", "v7.0/FACEBOOK_ID_HERE/photos?access_token=ACCESS_TOKEN_HERE&fields=id,created_time,images{source},picture&limit=5&after=AFTER_TOKEN_HERE");
The API handles putting in the forward slash between the root and the relative url.
what i am trying to achieve should be simple by theory but hell by implementation, if you think otherwise please help.
so what i am trying to achieve here is that I have my facebook page which I created a developer acount for it, and what i want is to take albums from the page to my website.
I am using the latest stable facebook sdk for .net 6.8.0, and i am assuming that the graph api is on v2.2.
this is the code i am using below to get the access token and access my albums
try
{
var fb = new FacebookClient();
dynamic result = fb.Get("oauth/access_token", new
{
client_id = "---my application number---",
client_secret = "---my application secret---",
grant_type = "client_credentials"
});
var fb2 = new FacebookClient(result.access_token);
dynamic albums = fb2.Get("my application number/albums");
foreach (dynamic albumInfo in albums)
{
try
{
dynamic albumsPhotos = fb2.GetTaskAsync(albumInfo.id + "/photos");
}
catch (Exception Exception)
{
throw Exception;
}
}
}
catch (Exception e)
{
throw e;
}
The data returned in the dynamic albums variables is empty, the thing that confused me more is when i use facebook graph api explorer the call work fine and it return the albums. so what exactly i am missing.
I also read in some threads that you can access your albums without the secret password if they are public but that didn't work for me either i tried it in javascript but no joy.
Thank you in advance.
Since this is your page, it should be pretty easy to retrieve your own photos using Windows PowerShell and http://facebookpsmodule.codeplex.com Get-FBAlbums.
I am developing a multi protocol client (currently Twitter, Facebook and Google Reader) for Windows using C# and wanted to extend its functions to send links to Facebook (currently I "only" have text status messages, comments and likes).
So I wrote this quite small method here:
public void PostLink(string text, string url)
{
if (string.IsNullOrEmpty(url))
{
PostTextStatus(text);
return;
}
dynamic parameters = new ExpandoObject();
parameters.message = text;
parameters.link = System.Web.HttpUtility.UrlEncode(url);
dynamic result = facebookClient.Post("me/links", parameters);
UpdateNewsFeed();
}
But I get the following error message back from Facebook: "(OAuthException) (#1500) The url you supplied is invalid"
But at least as I read the API docs this should be the right url and I tried it also with my user ID instead of "me" and without the UrlEncode - no luck so far.
Any help appreciated :)
(Using latest stable version für Facebook C# SDK)
The used client is initiated by
facebookClient = new FacebookClient(AccessToken);
dynamic result = (IDictionary<string, object>)facebookClient.Get("me");
if (result != null)
{
LoginSuccessfull = true;
}
}
and the AccesToken and its permissions were retrieved using
IDictionary<string, object> loginParameters = new Dictionary<string, object>
{
{ "response_type", "token" },
{ "appId", appId},
{ "secret", appSecret }
};
Uri redirectUri = new Uri("http://www.li-ghun.de/Nymphicus/");
loginUri = FacebookOAuthClient.GetLoginUrl(appId, null, _extendedPermissions, loginParameters);
with I think quite more than enough permissons:
private string[] _extendedPermissions = new[] {
"user_activities",
"user_birthday",
"user_checkins",
"user_education_history",
"user_events",
"user_games_activity",
"user_groups",
"user_hometown",
"user_interests",
"user_likes",
"user_location",
"user_notes",
"user_online_presence",
"user_photo_video_tags",
"user_photos",
"user_questions",
"user_relationship_details",
"user_relationships",
"user_religion_politics",
"user_status",
"user_subscriptions",
"user_videos",
"user_website",
"user_work_history",
"friends_about_me",
"friends_activities",
"friends_birthday",
"friends_checkins",
"friends_education_history",
"friends_events",
"friends_games_activity",
"friends_groups",
"friends_hometown",
"friends_interests",
"friends_likes",
"friends_location",
"friends_notes",
"friends_online_presence",
"friends_photo_video_tags",
"friends_photos",
"friends_questions",
"friends_relationship_details",
"friends_relationships",
"friends_religion_politics",
"friends_status",
"friends_subscriptions",
"friends_videos",
"friends_website",
"friends_work_history",
"create_event",
"create_note",
"email",
"export_stream",
"manage_friendlists",
"manage_notifications",
"manage_pages",
"offline_access",
"photo_upload",
"publish_actions",
"publish_checkins",
"publish_stream",
"read_friendlists",
"read_insights",
"read_mailbox",
"read_requests",
"read_stream",
"rsvp_event",
"share_item",
"status_update",
"video_upload",
};
Problem has been all the time at myself being stupid - I accidently exchanged the parameters when calling my method so the text of the entry was in the link property and vica versa.
Stupid me :(
I think your issue lies in the URL being posted as the link. Be sure that URL is visible to the linter (https://developers.facebook.com/tools/lint).
Another thing is to try playing with the Graph API Explorer tool and see if you can use it to post a link. If so, then try changing the application drop down to the app you're having issues with and try posting the link again.
In my case i was posting "http://localhost:3000" and facebook reject it. I tried with "www.google.com" and it works
The error I was getting was, even though the URL itself was valid, the og:image was being set to //example.com/example.jpg and missing http: or https:. I blame Facebook for this one, for not accepting a valid URL that any browser will accept, but the Debugger definitely helped identify this and solved the issue.
https://developers.facebook.com/tools/lint
Currently I'm working on my HTML 5 ASP.Net Application,
Which has requirement of Graffiti Wall, When user draw something on my Wall(means on my HTML 5 Canvas element), and Press Share Button on my Page, at that time the whole picture should need to be post on one of the Facebook Page.
Now my question is that is this thing possible using C# facebook sdk by codeplex ?
if its possible, than how to post image on facebook fan page using this SDK??
Where can I get the good resource the implement this kind of functionality or similar code.
I've check the all examples given by them, there is no any example which post on the facebook fan page.
Or even other library that can implement this kind of functionality.
I've check this library, and see that it has FacebookClient,ExpandoObject, FacebookMediaObject kind of classes, but how to and where to use this classes,where are the description and sample code.
Thanks,
Jigar Shah
you can post to others wall using "{id}/feed"
if you want to post image/video on wall. Try downloading the samples from nuget.
Install-Package Facebook.Sample
Here is how to do using the graph api.
public static string UploadPictureToWall(string id, string accessToken, string filePath)
{
var mediaObject = new FacebookMediaObject
{
FileName = System.IO.Path.GetFileName(filePath),
ContentType = "image/jpeg"
};
mediaObject.SetValue(System.IO.File.ReadAllBytes(filePath));
try
{
var fb = new FacebookClient(accessToken);
var result = (IDictionary<string, object>)fb.Post(id + "/photos", new Dictionary<string, object>
{
{ "source", mediaObject },
{ "message","photo" }
});
var postId = (string)result["id"];
Console.WriteLine("Post Id: {0}", postId);
// Note: This json result is not the orginal json string as returned by Facebook.
Console.WriteLine("Json: {0}", result.ToString());
return postId;
}
catch (FacebookApiException ex)
{
// Note: make sure to handle this exception.
throw;
}
}
I've just found a great sample of Facebook Connect on Blackberry by Eki Y. Baskoro,
The following is a short HOWTO on using Facebook Connect on Blackberry. I created a simple Facade encapsulating the Facebook REST API as well as added 'rough' MVC approach for screen navigation. I have tested on JDE 4.5 using 8320 simulator. This is still work in progress and all work is GPLed.
It works great for reading stuff.
NB Don't forget to get Facebook App Key and set it in TestBB class.
But now I want to post something on my wall. So I've add new method to FacebookFacade class using Stream.publish API:
/***
* Publishes message to the stream.
* #param message - message that will appear on the facebook stream
* #param targetId - The ID of the user, Page, group, or event where
* you are publishing the content.
*/
public void streamPublish(String message, String targetId)
{
Hashtable arguments = new Hashtable();
arguments.put("method", "stream.publish");
arguments.put("message", message);
arguments.put("target_id", targetId);
try {
JSONObject result = new JSONObject(
int new JSONTokener(sendRequest(arguments)));
int errorCode = result.getInt("error_code");
if (errorCode != 0) System.out.println("Error Code: "+errorCode);
} catch (Exception e) {
System.out.println(e);
}
}
/***
* Publishes message on current user wall.
* #param message - message that will appear on the facebook stream
*/
public void postOnTheWall(String message)
{
String targetId = String.valueOf(getLoggedInUserId());
streamPublish(message, targetId);
}
This will return Error code 200, "The user hasn't authorized the application to perform this action"
First I thought it's related with Facebook -> Application Settings -> Additional Permissions -> Publish recent activity (one line stories) to my wall but even checked, no difference...
Then I've found this post explains that issue related with extended permissions.
This in turn should be fixed by modifying url a little in LoginScreen class :
public LoginScreen(FacebookFacade facebookFacade) {
this.facebookFacade = facebookFacade;
StringBuffer data = new StringBuffer();
data.append("api_key=" + facebookFacade.getApplicationKey());
data.append("&connect_display=popup");
data.append("&v=1.0");
//revomed
//data.append("&next=http://www.facebook.com/connect/login_success.html");
//added
data.append("&next=http://www.facebook.com/connect/prompt_permissions.php?" +
"api_key="+facebookFacade.getApplicationKey()+"&display=popup&v=1.0"+
"&next=http://www.facebook.com/connect/login_success.html?"+
"xxRESULTTOKENxx&fbconnect=true" +
"&ext_perm=read_stream,publish_stream,offline_access");
data.append("&cancel_url=http://www.facebook.com/connect/login_failure.html");
data.append("&fbconnect=true");
data.append("&return_session=true");
(new FetchThread("http://m.facebook.com/login.php?"
+ data.toString())).start();
}
Unfortunately it's not working. Still Error Code 200 in return to stream.publish request...
Do you have any suggestions how to resolve this?
Thank you!
I have posted the updated API on my website (http://www.baskoro.web.id/facebook-connect-blackberry-HOWTO.html) and this should solve this issue. Please let me know otherwise.
Salam. Cheers!
Eki