private void HandleFBFailure(string szUser, string szResult) { // see https://developers.facebook.com/docs/authentication/access-token-expiration/ for what we're trying to do here. try { FacebookResponseError fberr = MFBFacebook.ParseJSonError(szResult); if (fberr.Error != null) { if (fberr.Error.Code == 190) { // De-authorize Profile pf = Profile.GetUser(szUser); pf.FacebookAccessToken = null; pf.FCommit(); // let them know that there is a problem. util.NotifyUser(String.Format(CultureInfo.CurrentCulture, Resources.WebService.NotifyFacebookSetup, Branding.CurrentBrand.AppName), String.Format(CultureInfo.CurrentCulture, Resources.EmailTemplates.ReauthFacebook, pf.UserFullName, fberr.Error.Code, fberr.Error.ErrorSubcode, fberr.Error.Message), new MailAddress(pf.Email, pf.UserFullName), false, false); } else { // send the raw result so we can debug. util.NotifyAdminEvent("Facebook posting error", String.Format(CultureInfo.CurrentCulture, "user: {0}. FB Response: {1}", szUser, szResult), ProfileRoles.maskSiteAdminOnly); } } } catch (MyFlightbookException) { } }
public bool PostToSocialMedia(IPostable o, string szUser, string szHost = null) { if (o == null) { throw new ArgumentNullException("o"); } if (!o.CanPost) { return(false); } if (String.IsNullOrEmpty(szUser)) { throw new ArgumentNullException("szUser"); } if (String.IsNullOrEmpty(szHost)) { szHost = Branding.CurrentBrand.HostName; } Profile pf = Profile.GetUser(szUser); // Check for user not configured if (pf.FacebookAccessToken == null || String.IsNullOrEmpty(pf.FacebookAccessToken.AccessToken)) { return(false); } // NOTE: We need to update the version code below periodically as the API updates const string szUrl = "https://graph.facebook.com/v2.10/me/feed"; MultipartFormDataContent form = new MultipartFormDataContent(); Uri uriItem = o.SocialMediaItemUri(szHost); MyFlightbook.Image.MFBImageInfo img = o.SocialMediaImage(szHost); // Add in the main parameters: Dictionary <string, string> dictParams = new Dictionary <string, string>() { { "access_token", pf.FacebookAccessToken.AccessToken }, { "message", string.Empty } }; if (uriItem != null) { dictParams.Add("link", uriItem.AbsoluteUri); } if (img != null) { dictParams.Add("picture", img.URLFullImage.ToAbsoluteURL("http", Branding.CurrentBrand.HostName).ToString()); } foreach (string key in dictParams.Keys) { StringContent sc = new StringContent(dictParams[key]); sc.Headers.ContentDisposition = (new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") { Name = key }); sc.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain") { CharSet = "ISO-8859-1" }; form.Add(sc); } // The remainder can run on a background thread, since we don't do anything that requires a result from here. new System.Threading.Thread(() => { using (HttpClient httpClient = new HttpClient()) { try { HttpResponseMessage response = httpClient.PostAsync(new Uri(szUrl), form).Result; string szResult = response.Content.ReadAsStringAsync().Result; if (response.IsSuccessStatusCode) { // do a refresh, to extend as much as possible if (MFBFacebook.ExchangeToken(pf.FacebookAccessToken)) { pf.FCommit(); } } else { HandleFBFailure(szUser, szResult); } } catch (MyFlightbookException) { } catch (System.ArgumentNullException) { } finally { form.Dispose(); } } }).Start(); return(true); }