API Facebook
I know there are a lot of information about working with Facebook API, but... I just think more information is better then less.
I need to post different types of context to Facebook pages (user create his own page, give us the name of page). OK, let's go!
I m using ASP.NET MVC, you know... Link to the project.
All events has been shown on the main page.
- Create our application in facebook.
You see there is secret key and application key. We need them to working with facebook through our application.
- Authorization (OAuth 2.0).
- Ask user to permission.
- User will be redirected to facebook access page.
- User give us needed permission.
- User has been redirected back to our web site with special code.
There is the step 4 (we get the code from redirecting response).
public void GetAccessToken() { if (HttpContext.Current.Request.Params.AllKeys.Contains("code")) { code = HttpContext.Current.Request.Params["code"]; //get the short-lived user access_toke string request = string.Format(_tokenEndpoint, _applicationId, _redirectTo, _applicationSecret, code); var webClient = new WebClient(); string response = webClient.DownloadString(request); string[] pairResponse = response.Split('&'); accessToken = pairResponse[0].Split('=')[1]; //get the long-lived user access_toke request = string.Format(_exchangeAccessToken, _applicationId, _applicationSecret, accessToken); webClient = new WebClient(); response = webClient.DownloadString(request); if (!accessToken.Equals(response.Split('=')[1])) { throw new AccessViolationException(); } GetUserInformation(); } else if (HttpContext.Current.Request.Params.AllKeys.Contains("error")) { error = HttpContext.Current.Request.Params["error"]; throw new AccessViolationException(error); } throw new HttpException(); }
That is my facebook controller
public ActionResult Index() { if (!Client.IsAuthorizated) { return Redirect(Client.UriToAuth); } return View(new FacebookModel {Name = ""}); } public ActionResult Authorizate() { Client.GetAccessToken(); return RedirectToAction("Index"); }
After getting code we need to get the id of the page:
private void GetUserInformation() { string request = "https://graph.facebook.com/me?access_token=" + accessToken; var webClient = new WebClient(); string response = webClient.DownloadString(request); user = JObject.Parse(response); GetPagesInformation(); } private void GetPagesInformation() { string request = "https://graph.facebook.com/" + user.SelectToken("id") + "/accounts?access_token=" + accessToken; var webClient = new WebClient(); string response = webClient.DownloadString(request); userPages = JObject.Parse(response); page = userPages.SelectToken("data").First(x => x.SelectToken("name").ToString().Equals(_pageName)); }
- OK, let's start to posting something. Here is my configuration:
private static readonly Dictionary<string, string> Config = new Dictionary<string, string> { {"AuthorizationEndpoint", "https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&scope=manage_pages,create_event,publish_stream"}, {"TokenEndpoint", "https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}"}, {"ApplicationId", "387222228001291"}, {"ApplicationSecret", "3a177e2231e2966733771775b42"}, {"RedirectTo", "http://localhost:4769/Facebook/Authorizate"}, {"PageName", "TesterMyRest Community"} };
Posting video.
public string CreateVideo(MemoryStream imageMemoryStream, string title, string fileName) { string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); var uploadRequest = (HttpWebRequest) WebRequest.Create("https://graph.facebook.com/" + page.SelectToken("id") + "/videos?access_token=" + page.SelectToken("access_token")); uploadRequest.ServicePoint.Expect100Continue = false; uploadRequest.Method = "POST"; uploadRequest.UserAgent = "Mozilla/4.0 (compatible; Windows NT)"; uploadRequest.ContentType = "multipart/form-data; boundary=" + boundary; uploadRequest.KeepAlive = false; var sb = new StringBuilder(); const string formdataTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n"; sb.AppendFormat(formdataTemplate, boundary, "title", HttpContext.Current.Server.HtmlEncode(title)); const string headerTemplate = "--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n"; sb.AppendFormat(headerTemplate, boundary, "source", fileName, @"application/octet-stream"); string formString = sb.ToString(); byte[] formBytes = Encoding.UTF8.GetBytes(formString); byte[] trailingBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); long imageLength = imageMemoryStream.Length; long contentLength = formBytes.Length + imageLength + trailingBytes.Length; uploadRequest.ContentLength = contentLength; uploadRequest.AllowWriteStreamBuffering = false; Stream strmOut = uploadRequest.GetRequestStream(); strmOut.Write(formBytes, 0, formBytes.Length); var buffer = new Byte[checked((uint) Math.Min(4096, (int) imageLength))]; int bytesRead; imageMemoryStream.Seek(0, SeekOrigin.Begin); while ((bytesRead = imageMemoryStream.Read(buffer, 0, buffer.Length)) != 0) { strmOut.Write(buffer, 0, bytesRead); } strmOut.Write(trailingBytes, 0, trailingBytes.Length); strmOut.Close(); var wresp = uploadRequest.GetResponse() as HttpWebResponse; Encoding enc = Encoding.UTF8; if (wresp != null) { var stream = wresp.GetResponseStream(); if (stream != null) { var loResponseStream = new StreamReader(stream, enc); return "https://graph.facebook.com/" + loResponseStream.ReadToEnd(); } } return string.Empty; }
- Change the information about the page.
WebHelper class:
public static class WebWorker { private static void AddPostParameter(Dictionary<string, string> values, StringBuilder postBody) { foreach (string key in values.Keys) { if (postBody.Length > 0) { postBody.Append("&"); } postBody.Append(string.Format("{0}={1}", key, values[key])); } } public static JObject DownloadJson(string requestUrl) { var webClient = new WebClient(); string response = webClient.DownloadString(requestUrl); return JObject.Parse(response); } public static string UploadString(string requstUrl, Dictionary<string, string> values) { var webClient = new WebClient(); var postBody = new StringBuilder(); AddPostParameter(values, postBody); return webClient.UploadString(requstUrl, postBody.ToString()); } }
private string CreateStatus(Dictionary<string, string> values) { string request = "https://graph.facebook.com/" + page.SelectToken("id") + "/feed?access_token=" + page.SelectToken("access_token"); return WebWorker.UploadString(request, values); }