I'm struggling to connect to the Facebook Messenger API. The server keeps returning:
The remote server returned an error: (400) Bad Request.
I've been at this for a few days, tried multiple methods, even tried a few VS packages that don't quite work. I've checked my Auth Token several times, and I don't know what else it might be.
Is there something obvious that's causing a bad request? I've copied the root URL from Facebook's API page. The token in the code below has been removed. The application throws an exception when I attempt to read the response. (WebResponse FBresponse = FBrequest.GetResponse();)
private string FBSendMessage(string user, string message)
{
string result = null;
string FBroot = "https://graph.facebook.com/v2.6/me/messages?access_token=";
string token = "EAA...DZD";
string FBURI = FBroot + token;
string FBstring = "{ \"recipient\": { \"id\":\"" + user + "\" }, \"message\": { \"text\":\"" + message + "\" } }";
try
{
//using (WebClient FBclient = new WebClient())
//{
// result =
// FBclient.UploadString(FBURI, FBstring);
//}
HttpWebRequest FBrequest = (HttpWebRequest)WebRequest.Create(FBURI);
FBrequest.Credentials = CredentialCache.DefaultCredentials;
FBrequest.ProtocolVersion = HttpVersion.Version11;
FBrequest.Method = "POST";
FBrequest.ContentType = "application/json";
byte[] FBbytes = Encoding.UTF8.GetBytes(FBstring);
FBrequest.ContentLength = FBbytes.Length;
Stream FBstream = FBrequest.GetRequestStream();
FBstream.Write(FBbytes, 0, FBbytes.Length);
FBstream.Close();
WebResponse FBresponse = FBrequest.GetResponse();
Output((((HttpWebResponse)FBresponse).StatusDescription), Log.Error);
FBstream = FBresponse.GetResponseStream();
StreamReader FBreader = new StreamReader(FBstream);
result = FBreader.ReadToEnd();
FBreader.Close();
FBresponse.Close();
}
catch(Exception ex)
{
Output(ex.Message, Log.Error);
}
return result;
}
I have determined that my code isn't the issue. The issue is that I'm making a request with an invalid user id. Facebook creates a user ID in the application context that isn't the same as your default user id. I have to receive a message to learn that contextualized id before I can send a message.
Related
I am trying to fetch comments from Facebook and trying reply that from the application using the access token again a facebook id.
When I am using that from one location continuously it works well even on dynamic IP of my system for days .. but when I tries to use the same at my home.. it is working for 2 times hardly and then blocks the ID... please help me resolve this.
Code here :
string AccessToken = "Acess token here";
GET_POST_LINK posts;
string url = "https://graph.facebook.com/v2.11/mefields=posts%7Bmessage%2Cpermalink_url%7D&access_token=" + AccessToken + "";
HttpWebRequest feedRequest = (HttpWebRequest)WebRequest.Create(url);
feedRequest.Method = "GET";
feedRequest.Accept = "application/json";
feedRequest.ContentType = "application/json; charset=utf-8";
WebResponse feedResponse = (HttpWebResponse)feedRequest.GetResponse();
using (feedResponse)
{
using (var reader = new StreamReader(feedResponse.GetResponseStream()))
{
posts = JsonConvert.DeserializeObject<GET_POST_LINK>(reader.ReadToEnd());
int count = posts.posts.data.Count;
}
}
I have the next problem: I've made a simple application which retrieves information from a server (GET Method). The application works fine as long as the information is retrieved successfully.
In case of insuccess, I don't receive the error from the server (ex: 401 - Unauthorized, 403 - Forbidden - when the authentication token is incorrect for example).
How can I fix this so that my application will return the error from server ? I've done also a POST method and there it's working, I received all erorrs froem server in case of insuccess.
What i'm doing wrong with this code ? Why i don't receive an error in case of insuccess?
The only error I receive in output is 400 in all scenarios and this isn't enough.
For example, if the authorization token is incorrect, I should receive from server 401 - Unauthorized. I know this because i'm doing test with other REST application (like POSTMAN). Can it be fixed to show the errors related to that scenarios ?
void example2() {
// GET METHOD !
try {
String webPage = "https://www.clients.ro";
String name = "user";
String password = "pass";
String authString = name + ":" + password;
System.out.println("Decoded authorization token" + authString);
//byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
//String authStringEnc = new String(authEncBytes);
byte[] authEncBytes = authString.getBytes(StandardCharsets.UTF_8);
String authStringEnc = DatatypeConverter.printBase64Binary(authEncBytes);
System.out.println("Token encoded in Base64 " + authStringEnc);
URL url = new URL(webPage);
URLConnection urlConnection = url.openConnection();
urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
InputStream is = urlConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
int numCharsRead;
char[] charArray = new char[1024];
StringBuffer sb = new StringBuffer();
while ((numCharsRead = isr.read(charArray)) > 0) {
sb.append(charArray, 0, numCharsRead);
}
String result = sb.toString();
System.out.println(result);
System.out.println();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have a problem when trying to post on my own business time line on facebook.
I get an error that says:
"(OAuthException)(#200) The user hasn't authorized the application to perform this action"
I think this has to do with the scope "publish_actions" in somehow but how can I authorize this publish_actions permission exactly?
I have looked everywhere in my account under "https://developers.facebook.com"
I have put my App for review but I cant add "publish_actions" as a permission for Facebook to review because on this permission there is a message which says: "It looks like you haven't made any API requests to access content with the publish_actions permission in the last 30 days"
But how can I use this permission without having the permission??
I would be very greatful for help if I am on the right track and what I am missing out?
Thank you!
try
{
String appID = "12345";
String appSecret = "123456";
String accessToken = "123|1234_a-b";
String clientToken = "1234567";
String pageID = "123456789";
Facebook.FacebookClient client = new Facebook.FacebookClient(accessToken);
var dicParams = new Dictionary<string, object>();
dicParams["message"] = "Hello on the time line message!";
dicParams["caption"] = string.Empty;
dicParams["description"] = string.Empty;
dicParams["name"] = "Some Name";
dicParams["req_perms"] = "publish_stream,manage_pages,status_update,publish_actions";
dicParams["scope"] = "publish_stream,manage_pages,status_update,publish_actions";
dicParams["access_token"] = accessToken;
var publishResponse = client.Post("/" + pageID + "/feed", dicParams);
MessageBox.Show("You posted on the timeline successfully!");
}
catch (Exception ex)
{ MessageBox.Show(ex.ToString()); }
Attempt 2:
I was looking at the facebook documentation and found an URL which seems relevant to post a message on the business page timeline:
POST graph.facebook.com/{user-id}/feed?message={message}&access_token={access-token}
I have tried to put it down in code like below but again, I receive the same error message:
(OAuthException)(#200) The user hasn't authorized the application to perform this action
Question is what I do wrong. Do I need to get any other access token with "publish_action" permission?. If that is the case I can't figure out how to get such token?
String appID = "12345";
String appSecret = "123456";
String accessToken = "123|1234_a-b";
String clientToken = "1234567";
String pageID = "123456789";
String message = "Hello World";
String requestUrl = "https://graph.facebook.com/" + pageID + "/feed?message=" + message + "&access_token=" + accessToken;
RestSharp.RestClient rc = new RestSharp.RestClient();
RestSharp.RestRequest request = new RestSharp.RestRequest(requestUrl, RestSharp.Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("x-li-format", "json");
request.RequestFormat = RestSharp.DataFormat.Json;
RestSharp.RestResponse restResponse = (RestSharp.RestResponse)rc.Execute(request);
RestSharp.ResponseStatus responseStatus = restResponse.ResponseStatus;
//"(OAuthException)(#200) The user hasn't authorized the application to perform this action"
MessageBox.Show(restResponse.Content.ToString());
I have found a solution which works. This code do post a "Message" to the timeline.
Question This code works for my business page. I also like to post on my personal page for friends. So tried to change the pageID to the the ID which is my personal page: (pageID = "987654321") but still it posts on my business page.
I wonder if I need to get a page token specifically for the personal page as well?
If that is the case, I wonder how this token can be achieved?
/*********************************************************************************************************************************************************************/
//STEPS!!! to get a non-expiring page access token:
//1. access the following URL and note the returned access token within the browser's address bar:
//https://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=REDIRECT_URI&scope=manage_pages,publish_actions&response_type=token
//2. access the following URL and within the returned data find the desired page's name and note the access token:
//https://graph.facebook.com/me/accounts?access_token=ACCESS_TOKEN_RETURNED_FROM_STEP_1
//3. access the following URL and note the returned access token:
//https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=fb_exchange_token&fb_exchange_token=PAGES_ACCESS_TOKEN_FROM_STEP_2
//use the Access Token Debugger to ensure your access token's profile ID matches the desired page's ID and it never expires
String newaccesstoken = "aaaaaaaaaaaabbbbbbbbbbbbbbccccccccccccccddddddddddddddddddd";
/*********************************************************************************************************************************************************************/
String appID = "12345";
String appSecret = "123456";
String accessToken = "123|1234_a-b";
String clientToken = "1234567";
String pageID = "123456789"; //Business page
//String pageID = "987654321"; //Personal page
String redirectURI = "http://example.com";
String message = "Hello Facebook";
String imageURL = "http://example.com/images/example-image.png";
String link = "http://example.co";
String caption = "example";
//Post a message to the time line
String requestUrl = "https://graph.facebook.com/" + pageID + "/feed?message=" + message + "&url=" + imageURL +
"&access_token=" + newaccesstoken;
RestSharp.RestClient rc = new RestSharp.RestClient();
RestSharp.RestRequest request = new RestSharp.RestRequest(requestUrl, RestSharp.Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("x-li-format", "json");
request.RequestFormat = RestSharp.DataFormat.Json;
RestSharp.RestResponse restResponse = (RestSharp.RestResponse)rc.Execute(request);
RestSharp.ResponseStatus responseStatus = restResponse.ResponseStatus;
MessageBox.Show(restResponse.Content.ToString() + "," + responseStatus.ToString());
I have facebook integrated on my login page, and now I'm trying to call a build-in action: books.rates using a Test App.
My app gets a valid access_token, and creates new feed items without problems. But when I'm tryng to make a books.rates API call, only works if the logged user is a real person (in my tests is me, also the App administrator), and fails allways with Error 400 when I try to rate a book with a Test User.
In both cases, the code is the same (only access_token and userid changes) and has "publish_actions" premission enabled. I think I'm missing something on Test App configuration, but I'm really lost right now.
Thanks!
Update 1
This is the code that makes the action. It's a test code so its very basic
Dictionary<string, string> postInfo = new Dictionary<string, string>();
postInfo["book"] = "http://www.whakoom.com/comics/6jMl7/52/4";
postInfo["rating:value"] = "4";
postInfo["rating:scale"] = "5";
postInfo["fb:explicitly_shared"] = "true";
string graphUrl = string.Format("https://graph.facebook.com/v2.1/{0}/books.rates?access_token={1}", FbUserID, FbAccessToken);
string fbResp = PostPageContent(graphUrl, postInfo);
private static string PostPageContent(string url, Dictionary<string,string> postData)
{
string postInfo = string.Empty;
foreach(string key in postData.Keys)
{
if (postInfo.Length > 0)
postInfo += "&";
postInfo += string.Format("{0}={1}", HttpContext.Current.Server.UrlEncode(key), HttpContext.Current.Server.UrlEncode(postData[key]));
}
var request = WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postInfo.Length;
StreamWriter streamOut = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
streamOut.Write(postInfo);
streamOut.Close();
string retValue = string.Empty;
WebResponse response = request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
retValue = reader.ReadToEnd();
reader.Close();
return retValue;
It seems that Test App with Test Users is unable to make books.rates calls until the main App is approved. The same api calls targeting a real App with a Test User works without problems.
I want to update the facebookpage using c# sdk. I have partially successful with this, the problem is whenever I post messages to the page, post is visible only for admin(i am the admin of the page)is logged In. I want the post or feed to be visible to every one who visit the page.
(even admin is logged out post's are not visible to admin also)
The following code i am trying to achieve
public ActionResult FacebookPagePost()
{
string app_id = "xxxx";
string app_secret = "xxx";
string scope = "publish_stream,manage_pages";
string page_Id = "xxX";
if (Request["code"] == null)
{
return Redirect(string.Format(
"https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}",
app_id, Request.Url.AbsoluteUri, scope));
}
else
{
try
{
Dictionary<string, string> tokens = new Dictionary<string, string>();
string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&scope={2}&code={3}&client_secret={4}",
app_id, Request.Url.AbsoluteUri, scope, Request["code"].ToString(), app_secret);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string vals = reader.ReadToEnd();
foreach (string token in vals.Split('&'))
{
tokens.Add(token.Substring(0, token.IndexOf("=")),
token.Substring(token.IndexOf("=") + 1, token.Length - token.IndexOf("=") - 1));
}
}
string access_token = tokens["access_token"];
var client = new FacebookClient(access_token);
dynamic fbAccounts = client.Get("/me/accounts");
dynamic messagePost = new ExpandoObject();
messagePost.picture = "http://pic.com/pic.png";
messagePost.link = "http://www.examplearticle.com";
messagePost.name = "name goes here";
messagePost.description = "description goes here";
//Loop over the accounts looking for the ID that matches your destination ID (Fan Page ID)
foreach (dynamic account in fbAccounts.data) {
if (account.id == page_Id)
{
//When you find it, grab the associated access token and put it in the Dictionary to pass in the FB Post, then break out.
messagePost.access_token = account.access_token;
break;
}
}
client.Post("/" + page_Id + "/feed", messagePost);
}
catch (FacebookOAuthException ex)
{
}
catch (Exception e)
{
}
}
}
1) Create a Facebook App at: developers.facebook.com and get yourself an APPID and APPSECRET. (there are a lot of tutorials online for doing this so I will skip repeating it)
2) Go to: http://developers.facebook.com/tools/explorer and choose your app from the dropdown and click "generate access token".
3) After that do the following steps here:
https://stackoverflow.com/questions/17197970/facebook-permanent-page-access-token to get yourself a permanent page token.
(I can not stress this enough, follow the steps carefully and thoroughly)*
*I have tool I built that does this for me, all I enter is the APPID, APPSECRET and ACCESSTOKEN which the tool then generates a permanent page token for me. Anyone is welcomed to use it and help make it better,
https://github.com/devfunkd/facebookpagetokengenerator
=========================================================================
Ok at this point you should have your APPID, APPSECRET and a PERMANENT PAGE TOKEN.
=========================================================================
In your Visual Studio solution:
4) Using Nuget:Install-Package Facebook
5) Implement the Facebook client:
public void PostMessage(string message)
{
try
{
var fb = new FacebookClient
{
AppId = ConfigurationManager.AppSettings.Get("FacebookAppID"),
AppSecret = ConfigurationManager.AppSettings.Get("FacebookAppSecret"),
AccessToken = ConfigurationManager.AppSettings.Get("FacebookAccessToken")
};
dynamic result = fb.Post("me/feed", new
{
message = message
});
}
catch (Exception exception)
{
// Handle your exception
}
}
I hope this helps anyone who is struggling to figure this out.