How to attach multiple videos and photos to a status post with Facebook graph API - facebook

I'm trying to publish a post with multiple attached videos and photos via the Facebook Graph API. I uploaded the videos and photos first using a batch request and get the ids successfully for the uploaded media. Then I pass the media ids along with the post data using attached_media. Things work fine for single or multiple photos. But not for a single video or multiple videos. I got this error: "Graph returned an error: (#10) Application does not have permission for this action" whenever ids of videos are included in attached_media.
I know as a user you have the ability to attach multiple videos and photos to a Facebook post. Does the Facebook Graph API just flat out not support this for multiple videos?
I am working with C# and Unity
Here is the function that uploads videos and then sends a post with attached result videos ids:
private IEnumerator UploadMediaWithStatus(string message, string[] mediaUrls)
{
FacebookPostStatusUpdatedEvent.Invoke("Submitting FB post ... ");
var curPage = m_UserPages[FacebookFeedsList.GetInstance().ActiveFeed] as IDictionary<string, object>;
var fbClient = new FacebookClient(curPage["access_token"].ToString());
List<string> mediaIDs = new List<string> ();
foreach (string mediaUrl in mediaUrls)
{
WWW _media = new WWW("file://" + mediaUrl);
yield return _media;
if (!System.String.IsNullOrEmpty(_media.error))
{
FacebookPostStatusUpdatedEvent.Invoke("FB post failed: error loading media " + mediaUrl);
//TruLogger.LogError("cant load Image : " + _image.error);
yield break;
}
byte[] mediaData = null;
FacebookMediaObject medObj = new FacebookMediaObject();
JsonObject p = new JsonObject();
mediaData = _media.bytes;
medObj.SetValue(mediaData);
medObj.FileName = "InteractiveConsole.mp4";
medObj.ContentType = "multipart/form-data";
p.Add("description", message);
p.Add("source", medObj);
uploadedImgID = "";
fbClient.PostCompleted += OnPostImageUploadComplete;
fbClient.PostAsync("/me/videos", p);
//wait for image upload status and hopefully it returned a media ID on successful image upload
while (uploadedImgID == "")
{
//if image updload failed because of rate limit failure we can just abort rest of this
if (rateLimitErrorOccurred)
{
rateLimitErrorOccurred = false;
yield break;
}
yield return true;
}
//if video uploaded succesfully
if (uploadedImgID != null)
{
mediaIDs.Add (uploadedImgID);
var response = (JsonObject)fbClient.Get("/" + uploadedImgID + "?fields=status,published");
TruLogger.LogError("Video Status Details: " + response.ToString());
string vidStatus = (response["status"] as IDictionary<string, object>)["video_status"] as string;
while( vidStatus != "ready")
{
yield return new WaitForSeconds(5.0f);
response = (JsonObject)fbClient.Get("/" + uploadedImgID + "?fields=status,published");
TruLogger.LogError("Video Status Details: " + response.ToString());
vidStatus = (response["status"] as IDictionary<string, object>)["video_status"] as string;
}
TruLogger.LogError("Video ready");
yield return new WaitForSeconds(5.0f);
}
}
if (mediaIDs.Count > 0)
{
curPage = m_UserPages[FacebookFeedsList.GetInstance().ActiveFeed] as IDictionary<string, object>;
fbClient = new FacebookClient(curPage["access_token"].ToString());
JsonObject p = new JsonObject();
p.Add("message", message);
for (int i = 0; i < mediaIDs.Count; i++)
{
p.Add ("attached_media["+ i + "]", "{\"media_fbid\":\"" + mediaIDs[i] + "\"}");
}
fbClient.PostCompleted += OnPostUploadComplete;
fbClient.PostAsync("/me/feed", p);
}
}
void OnPostImageUploadComplete(object sender, FacebookApiEventArgs args)
{
//if successful store resulting ID of image on Facebook
try
{
var json = args.GetResultData<JsonObject>();
uploadedImgID = json["id"].ToString();
//TruLogger.LogError(json.ToString());
}
catch (Exception e)
{
apiPostStatusMessage = "FB post failed: media upload error";
TruLogger.LogError (e.Message);
TruLogger.LogError (e.InnerException.ToString());
FacebookOAuthException oEx = (FacebookOAuthException)(e.InnerException);
if (oEx != null) {
TruLogger.LogError ("Error Type: " + oEx.ErrorType);
TruLogger.LogError ("Error Code: " + oEx.ErrorCode);
TruLogger.LogError ("Error Subcode: " + oEx.ErrorSubcode);
apiAbortErrorCode = oEx.ErrorCode;
if (apiAbortErrorCode == 32 || apiAbortErrorCode == 4)
{
rateLimitErrorOccurred = true;
apiPostAbortErrorMessage = "WHOOPS! Looks like you have exceeded the daily API rate quota for one or more of your feeds. You may have to wait between 1-24 hours until Facebook replenishes your balance for these feeds: \n\n" + e.InnerException.ToString ();
}
else
{
rateLimitErrorOccurred = false;
apiPostAbortErrorMessage = "WHOOPS! Looks like your session has expired or become invalid. Try Signing in again to revalidate your session: \n\n" + e.InnerException.ToString ();
}
}
else
{
rateLimitErrorOccurred = false;
apiAbortErrorCode = -1;
apiPostAbortErrorMessage = "WHOOPS! Looks like your session has expired or become invalid. Try Signing in again to revalidate your session: \n\n" + e.InnerException.ToString ();
}
uploadedImgID = null;
}
}
//generic call back for any post calls
void OnPostUploadComplete(object sender, FacebookApiEventArgs args)
{
try
{
var json = args.GetResultData();
TruLogger.LogError(json.ToString());
apiPostStatusMessage = "FB post successfully submitted";
//FacebookPostStatusUpdatedEvent.Invoke("FB post successfully submitted");
}
catch (Exception e)
{
apiPostStatusMessage = "FB post failed to submit";
//FacebookPostStatusUpdatedEvent.Invoke("FB post failed to submit");
TruLogger.LogError (e.Message);
TruLogger.LogError (e.InnerException.ToString());
FacebookOAuthException oEx = (FacebookOAuthException)(e.InnerException);
if (oEx != null) {
TruLogger.LogError ("Error Type: " + oEx.ErrorType);
TruLogger.LogError ("Error Code: " + oEx.ErrorCode);
TruLogger.LogError ("Error Subcode: " + oEx.ErrorSubcode);
apiAbortErrorCode = oEx.ErrorCode;
if (apiAbortErrorCode == 32 || apiAbortErrorCode == 4)
{
rateLimitErrorOccurred = true;
apiPostAbortErrorMessage = "WHOOPS! Looks like you have exceeded the daily API rate quota for one or more of your feeds. You may have to wait between 1-24 hours until Facebook replenishes your balance for these feeds: \n\n" + e.InnerException.ToString ();
}
else
{
rateLimitErrorOccurred = false;
apiPostAbortErrorMessage = "WHOOPS! Looks like your session has expired or become invalid. Try Signing in again to revalidate your session: \n\n" + e.InnerException.ToString ();
}
}
else
{
rateLimitErrorOccurred = false;
apiAbortErrorCode = -1;
apiPostAbortErrorMessage = "WHOOPS! Looks like your session has expired or become invalid. Try Signing in again to revalidate your session: \n\n" + e.InnerException.ToString ();
}
}
}

Facebook doesn't directly allow to upload multiple videos or photos with videos on the business page. However, it is possible on a personal page so as an alternate solution you can create a post on a personal page and share it on the business page.
Check this video for more information: https://www.youtube.com/watch?v=AoK_1S71q1o

Related

How do I upload files from a phone to my Amazon S3 server?

I'm developing a mobile app with Unity and using S3 to store and retrieve assets, I can download asset bundles just fine from the server to the phone, but how do I upload files from the phone to the server?
I used the PostObject function from the AWS Unity SDK, and it works fine if I upload from the computer as I know the directory, but I'm not sure how to get the phone's photo gallery to upload to the s3 server.
This is the PostObject function
public void PostObject(string fileName)
{
ResultText.text = "Retrieving the file";
var stream = new FileStream("file://" + Application.streamingAssetsPath + "/" + fileName,
FileMode.Open, FileAccess.Read, FileShare.Read);
Debug.Log("kek");
ResultText.text += "\nCreating request object";
var request = new PostObjectRequest()
{
Bucket = S3BucketName,
Key = fileName,
InputStream = stream,
CannedACL = S3CannedACL.Private,
Region = _S3Region
};
ResultText.text += "\nMaking HTTP post call";
Client.PostObjectAsync(request, (responseObj) =>
{
if (responseObj.Exception == null)
{
ResultText.text += string.Format("\nobject {0} posted to bucket {1}",
responseObj.Request.Key, responseObj.Request.Bucket);
}
else
{
ResultText.text += "\nException while posting the result object";
ResultText.text += string.Format("\n receieved error {0}",
responseObj.Response.HttpStatusCode.ToString());
}
});
}
And this is where I'm using it to upload the picture taken from the phone to the server
public void TakePicture(int maxSize)
{
NativeCamera.Permission permission = NativeCamera.TakePicture((path) =>
{
Debug.Log("Image path: " + path);
if (path != null)
{
// Create a Texture2D from the captured image
Texture2D imageTexture = NativeCamera.LoadImageAtPath(path, maxSize);
if (imageTexture == null)
{
Debug.Log("Couldn't load texture from " + path);
return;
}
//picturePreview.gameObject.SetActive(true);
//picturePreview.texture = imageTexture;
Texture2D readableTexture = DuplicateTexture(imageTexture);
StartCoroutine(AddImageJob(readableTexture));
//Saves taken photo to the Image Gallery
if (isSaveFiles)
{
NativeGallery.SaveImageToGallery(imageTexture, "AReview", "test");
//Upload to Amazon S3
aws.PostObject(imageTexture.name);
aws.PostObject("test");
}
}
}, maxSize);
Debug.Log("Permission result: " + permission);
}
Any clues?
Thank you.

How do I get friends Faceook ID from App Request deep link using FB.GetAppLink in Unity?

I am using Unity 5.4 with the latest Facebook API (7.8) for this.
I am trying to find out what my friends Facebook ID is after clicking a Game Request they sent me. I have looked into and have been using FB.GetAppLink but it doesnt appear to give me the friends Facebook ID, only my Facebook ID and the games ID.
I am needing this information so that after accepting their challenge I can send them back a gift if I was successful.
Thanks
Found the answer after umping through a lot of hoops...
public void GetDeepLink ()
{
FB.GetAppLink(DeepLinkCallBack);
}
public void DeepLinkCallBack(IAppLinkResult result)
{
if (string.IsNullOrEmpty(result.Error))
{
IDictionary<string, object> dict = result.ResultDictionary;
if (dict.ContainsKey("target_url"))
{
string url = dict["target_url"].ToString();
string keyword = "request_ids=";
int k = 0;
while (k < url.Length - keyword.Length && !url.Substring(k, keyword.Length).Equals(keyword))
k++;
k += keyword.Length;
int l = k;
while (url[l] != '&' && url[l] != '%')
l++;
string id = url.Substring(k, l - k);
FB.API("/" + id + "_" + AccessToken.CurrentAccessToken.UserId, HttpMethod.GET, DeepLinkCallBackCallBack);
}
else
{
Debug.Log("Applink Error :" + result.Error);
}
}
}
void DeepLinkCallBackCallBack(IGraphResult result)
{
Debug.Log("Request callback");
Debug.Log("========================");
if (string.IsNullOrEmpty(result.Error))
{
IDictionary<string, object> dict = result.ResultDictionary;
if (dict.ContainsKey("from"))
{
IDictionary<string,object> from = dict["from"] as Dictionary<string, object>;
if (from.ContainsKey("name"))
{
Debug.Log(from["name"]);
deepLinkUserName = from["name"].ToString();
}
if (from.ContainsKey("id"))
{
deepLinkUserName = from["name"].ToString();
FB.API("/" + dict["id"], HttpMethod.DELETE, null);
}
}
}
else
{
Debug.Log("Error in request:" + result.Error);
}
}

Getting page details from Facebook account using App Access Token

I am stuck into a problem for which I have not found any solution or documentation.
I am building an app using Facebook API in which user will create an app and will give their APP ID & APP SECRET to the application in order to create pages or post to pages.
Now the problem is they will only login into my application not in facebook nor login using FB.
I am getting APP ACCESS TOKEN from APP ID & APP SECRET.
Using https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=client_credentials
But how could i use it to get pages for that account or generate USER ACCESS TOKEN from it?
Please help me with your expert guidance.
Thanks.
You cannot create Apps nor Pages by using the Graph API! See https://developers.facebook.com/docs/graph-api/reference/v2.0/page
If you want to publish to a Page the logged-in User administrers, you can request the respective Page Access Token (with publish_actions and manage_pages permissions!) via
GET /me/accounts
See
https://developers.facebook.com/docs/graph-api/reference/v2.0/user/accounts/
https://developers.facebook.com/docs/facebook-login/access-tokens#pagetokens
first of create developer apps and get token give some permission
public ActionResult Index()
{
var url = "http://www.facebook.com/v2.0/dialog/oauth/?scope=user_friends,read_friendlists,read_stream,read_insights,manage_pages,user_checkins,user_photos,read_mailbox,manage_notifications,read_page_mailboxes,email,user_videos,user_groups,offline_access,publish_actions,manage_pages&client_id=" + ConfigurationManager.AppSettings["ClientId"] + "&redirect_uri=" + ConfigurationManager.AppSettings["RedirectUrl"] + "&response_type=code";
return Redirect(url);
}
that automatic redirect call back url for example
public ActionResult AddFacebookAccount(string code)
{
string ret = string.Empty;
string client_id = ConfigurationManager.AppSettings["ClientId"];
string redirect_uri = ConfigurationManager.AppSettings["RedirectUrl"];
string client_secret = ConfigurationManager.AppSettings["ClientSecretKey"];
long friendscount = 0;
try
{
FacebookClient fb = new FacebookClient();
string profileId = string.Empty;
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("client_id", client_id);
parameters.Add("redirect_uri", redirect_uri);
parameters.Add("client_secret", client_secret);
parameters.Add("code", code);
JsonObject fbaccess_token = null;
try
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;
fbaccess_token = (JsonObject)fb.Get("/oauth/access_token", parameters);
}
catch (Exception ex)
{
try
{
fbaccess_token = (JsonObject)fb.Get("/oauth/access_token", parameters);
}
catch (Exception ex1)
{
ViewBag.acc_tkn= "issue_access_token";
}
}
string accessToken = fbaccess_token["access_token"].ToString();
Session["AccessToken"] = accessToken;
if (accessToken != null)
{
fb.AccessToken = accessToken;
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;
dynamic profile = fb.Get("v2.2/me");
dynamic friends = fb.Get("v2.2/me/friends");
try
{
Session["uid"] = profile.id;
friendscount = Convert.ToInt16(friends["summary"]["total_count"].ToString());
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
ViewBag.acc_tkn = accessToken;
ViewBag.Uid = profile.id;
}
return View();
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
ViewBag.acc_tkn= "Something Went Wrong";
return View();
}
}
you will get access Token when post data on page refer Bellow Code
public void FacebookPostonPage(string file, string message, string tokenid)
{
JsonObject fbaccess_token = null;
FacebookClient fb = new FacebookClient();
fb.AccessToken = tokenid;
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;
fbaccess_token = (JsonObject)fb.Get("v2.0/me/accounts");
dynamic Result = fbaccess_token["data"];
foreach (var obj in Result)
{
string result = FacebookComposeMessage(obj.access_token, obj.id, message, file);
}
}
public string FacebookComposeMessage(string tokenid,string userid ,String message,string imagepath)
{
FacebookClient fb = new FacebookClient();
string ret = "";
fb.AccessToken = tokenid;
fb.AppId = ConfigurationManager.AppSettings["ClientId"];
fb.AppSecret = ConfigurationManager.AppSettings["ClientSecretKey"];
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;
var args = new Dictionary<string, object>();
args["message"] = message;
if (!string.IsNullOrEmpty(imagepath))
{
var media = new FacebookMediaObject
{
FileName = "filename",
ContentType = "image/jpeg"
};
byte[] img = System.IO.File.ReadAllBytes(imagepath);
media.SetValue(img);
args["source"] = media;
ret = fb.Post("v2.0/" + userid + "/photos", args).ToString();
}
else
{
ret = fb.Post("v2.0/" + userid + "/feed", args).ToString();
// ret = fb.Post("/" + objFacebookAccount.FbUserId + "/photos", args).ToString();
// var data = fb.Get("v2.2" + ret);
}
return ret;
}
You will post Successfully try now

twitter4j - get tweets by ID

How can I get the tweets when I have the tweet ID and the user ID ? I have a file containing lines like :
userID tweetID
I guess I should go by :
Query query = new Query("huh ?");
QueryResult result = twitter.search(query);
List<Status> tweets = result.getTweets();
but I have no clue how to spell the query
Thanks
Well it was no search call. The tweet apparently is called Status and the code to retrieve one by ID is :
final Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_KEY_SECRET);
AccessToken accessToken = new AccessToken(TWITTER_TOKEN,
TWITTER_TOKEN_SECRET);
twitter.setOAuthAccessToken(accessToken);
try {
Status status = twitter.showStatus(Long.parseLong(tweetID));
if (status == null) { //
// don't know if needed - T4J docs are very bad
} else {
System.out.println("#" + status.getUser().getScreenName()
+ " - " + status.getText());
}
} catch (TwitterException e) {
System.err.print("Failed to search tweets: " + e.getMessage());
// e.printStackTrace();
// DON'T KNOW IF THIS IS THROWN WHEN ID IS INVALID
}
The accepted answer is no longer valid. Based on the answer in this page, the code should be changed to the following:
String consumerKey = xxxxxxx,
consumerSecret = xxxxxxx,
twitterAccessToken = xxxxxxx,
twitterAccessTokenSecret = xxxxxxx,
Tweet_ID = xxxxxxx;
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(consumerKey);
builder.setOAuthConsumerSecret(consumerSecret);
Configuration configuration = builder.build();
TwitterFactory factory = new TwitterFactory(configuration);
final Twitter twitter = factory.getInstance();
//twitter.setOAuthConsumer(consumerKey, consumerSecret);
AccessToken accessToken = new AccessToken(twitterAccessToken, twitterAccessTokenSecret);
twitter.setOAuthAccessToken(accessToken);
try {
Status status = twitter.showStatus(Long.parseLong(Tweet_ID));
if (status == null) { //
// don't know if needed - T4J docs are very bad
} else {
System.out.println("#" + status.getUser().getScreenName()
+ " - " + status.getText());
}
} catch (
TwitterException e) {
System.err.print("Failed to search tweets: " + e.getMessage());
// e.printStackTrace();
// DON'T KNOW IF THIS IS THROWN WHEN ID IS INVALID
}
A very easy way to get a list of tweets by their ID is to use the lookup function like this:
public static void main(String[] args) throws TwitterException {
ConfigurationBuilder cfg = new ConfigurationBuilder();
cfg.setOAuthAccessToken("key");
cfg.setOAuthAccessTokenSecret("key");
cfg.setOAuthConsumerKey("key");
cfg.setOAuthConsumerSecret("key");
Twitter twitter = new TwitterFactory(cfg.build()).getInstance();
long[] ids = new long [3];
ids[0] = 568363361278296064L;
ids[1] = 568378166512726017L;
ids[2] = 570544187394772992L;
ResponseList<Status> statuses = twitter.lookup(ids);
for (Status status : statuses) {
System.out.println(status.getText());
}
}
The advantage of using lookup is that you can get with a sigle call up to 100 tweets, this means that if you have to download a big number of tweets you will need to do a lot less calls to the twitter API and speed up the process (this is because twitter limits the number of calls you can do).
You can even check the number of calls that you can do before twitter puts you in timeout like this:
RateLimitStatus searchLimits = twitter.getRateLimitStatus("statuses").get("/statuses/lookup");
int remain = searchLimits.getRemaining();
int limit = searchLimits.getLimit();
int secToReset = searchLimits.getSecondsUntilReset();
System.out.println(remain); // this returns the number of calls you have left
System.out.println(limit); // this returns how many calls you have max(this is a fixed number)
System.out.println(secToReset); // this returns the number of second before the reset
// after the reset you return to have the number of calls specified by "limit"

apache HttpClient to access facebook

Any examples, tips, guidance for the following scenario?
I have used Apache HttpClient to simulate the functionality of browser to access facebook through java application. to do that first i have to provide user credentials. i have used examples provided in the following web site.
http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/examples/
But non of these methods works for facebook, following is the test code i have written for this purpose. i have not provided the all the methods written, only the method used to login to the facebook account is given here. relay appreciate any help
private static int connectAndLogin(String email, String pass){
logger.trace("Facebook: =========connectAndLogin begin===========");
String httpResponseBody = getMethod("http://www.facebook.com/login.php");
if(httpResponseBody == null){
//Why don't we try again?
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
logger.trace(e.getMessage());
}
httpResponseBody = getMethod("http://www.facebook.com/login.php");
}
logger.trace("Facebook: ========= get login page ResponseBody begin===========");
logger.trace(httpResponseBody);
logger.trace("Facebook: +++++++++ get login page ResponseBody end+++++++++");
logger.trace("Facebook: Initial cookies: ");
List<Cookie> cookies = getCookies();
if (cookies.isEmpty()) {
logger.trace("Facebook: None");
} else {
for (int i = 0; i < cookies.size(); i++) {
logger.trace("Facebook: - " + cookies.get(i).toString());
}
}
if(httpResponseBody == null){
logger.warn("Facebook: Warning: Failed to get facebook login page.");
}
try
{
HttpPost httpost = new HttpPost("http://www.facebook.com/login.php");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("email", email));
nvps.add(new BasicNameValuePair("pass", pass));
//don't know if is this necessary
nvps.add(new BasicNameValuePair("login", ""));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
logger.info("Facebook: #executing post method to:" + "http://www.facebook.com/login.php");
HttpResponse loginPostResponse = getHttpClient().execute(httpost);
HttpEntity entity = loginPostResponse.getEntity();
logger.trace("Facebook: Login form post: " + loginPostResponse.getStatusLine());
if (entity != null) {
logger.trace("Facebook: "+EntityUtils.toString(entity));
entity.consumeContent();
} else {
logger.error("Facebook: Error: login post's response entity is null");
return FacebookErrorCode.kError_Login_GenericError;
}
logger.trace("Facebook: Post logon cookies:");
cookies = getCookies();
if (cookies.isEmpty()) {
logger.trace("Facebook: None");
} else {
for (int i = 0; i < cookies.size(); i++) {
logger.trace("Facebook: - " + cookies.get(i).toString());
}
}
int statusCode = loginPostResponse.getStatusLine().getStatusCode();
logger.info("Facebook: Post Method done(" + statusCode + ")");
switch(statusCode){
case 100: break;//we should try again;
case 301:
case 302:
case 303:
case 307:
{
//redirect
// Header[] headers = loginPostResponse.getAllHeaders();
// for (int i=0; i<headers.length; i++) {
// logger.trace("Facebook: "+headers[i]);
// }
// Header locationHeader = loginPostResponse.getFirstHeader("location");
// if(locationHeader != null){
// homePageUrl = locationHeader.getValue();
// logger.info("Facebook: Redirect Location: " + homePageUrl);
// if(homePageUrl == null
// || !homePageUrl.contains("facebook.com/home.php")){
// logger.error("Facebook: Login error! Redirect Location Url not contains \"facebook.com/home.php\"");
// return FacebookErrorCode.kError_Login_GenericError;
// }
// } else {
// logger.warn("Facebook: Warning: Got no redirect location.");
// }
}
break;
default:;
}
}
catch (IOException ioe)
{
logger.error("Facebook: IOException\n" + ioe.getMessage());
return FacebookErrorCode.kError_Global_ValidationError;
}
logger.trace("Facebook: =========connectAndLogin end==========");
return FacebookErrorCode.Error_Global_NoError;
}
The following code, based on that sample, worked for me:
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.facebook.com/login.php");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
entity.consumeContent();
}
System.out.println("Initial set of cookies:");
List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
HttpPost httpost = new HttpPost("http://www.facebook.com/login.php");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("email", "******"));
nvps.add(new BasicNameValuePair("pass", "*******"));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = httpclient.execute(httpost);
entity = response.getEntity();
System.out.println("Double check we've got right page " + EntityUtils.toString(entity));
System.out.println("Login form get: " + response.getStatusLine());
if (entity != null) {
entity.consumeContent();
}
System.out.println("Post logon cookies:");
cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
httpclient.getConnectionManager().shutdown();
I am not sure if your code was managing properly cookies (and session id kept within one of them), maybe that was the problem. Hope this will help you.
Just to make clear version issue: I was using HttpClient version 4.X, not the old one (3.X). They differ significantly.
Perhaps you should use a tool, such as Selenium
Have you taken a look at HtmlUnit. It wraps the HttpClient to create a headless Java browser, with javaScript execution. This way you are not trying to hack the individual forms all the time.