public FacebookShopRequestContainer SyncProduct(ContentItem product) { var productPart = product.As <ProductPart>(); try { var facebookPart = product.As <FacebookShopProductPart>(); if (productPart != null && facebookPart != null && facebookPart.SynchronizeFacebookShop) { var jsonTemplate = facebookPart.Settings.GetModel <FacebookShopProductPartSettings>().JsonForProductUpdate; _fsssp = _workContext.GetContext().CurrentSite.As <FacebookShopSiteSettingsPart>(); if (string.IsNullOrWhiteSpace(jsonTemplate)) { // Fallback to FacebookShopSiteSettingsPart jsonTemplate = _fsssp.DefaultJsonForProductUpdate; } if (!string.IsNullOrWhiteSpace(jsonTemplate)) { // jsonTemplate typically begins with a double '{' and ends with a double '}' (to make tokens work). // For this reason, before deserialization, I need to replace tokens and replace double parenthesis. string jsonBody = _tokenizer.Replace(jsonTemplate, product); jsonBody = jsonBody.Replace("{{", "{").Replace("}}", "}"); var jsonContext = FacebookShopProductUpdateRequest.From(jsonBody); CheckCompliance(jsonContext, product); if (jsonContext != null && jsonContext.Valid) { return(SyncProduct(jsonContext)); } else if (jsonContext != null) { // I need to tell it was impossible to synchronize the product on Facebook Shop. Logger.Debug(T("Product {0} can't be synchronized on Facebook catalog.", productPart.Sku).Text); Logger.Debug(jsonContext.Message.Text); var returnValue = new FacebookShopRequestContainer(); returnValue.Requests.Add(jsonContext); return(returnValue); } } } } catch (Exception ex) { // I need to tell it was impossible to synchronize the product on Facebook Shop. if (productPart != null) { Logger.Debug(ex, T("Product {0} can't be synchronized on Facebook catalog.", productPart.Sku).Text); } else { Logger.Debug(ex, T("Product part or Facebook part are not valid.").Text); } return(null); } return(null); }
public void CheckFacebookHandles(string handle, string containerJson) { if (!string.IsNullOrWhiteSpace(handle)) { _fsssp = _workContext.GetContext().CurrentSite.As <FacebookShopSiteSettingsPart>(); string url = _fsssp.ApiBaseUrl + (_fsssp.ApiBaseUrl.EndsWith("/") ? _fsssp.CatalogId : "/" + _fsssp.CatalogId); url = string.Format(url + "/check_batch_request_status?handle={0}&access_token={1}", handle, _fsssp.AccessToken); HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; try { request.Method = WebRequestMethods.Http.Get; using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { if (response.StatusCode == HttpStatusCode.OK) { using (var reader = new StreamReader(response.GetResponseStream())) { string respJson = reader.ReadToEnd(); var handlesJson = JObject.Parse(respJson); var errors = handlesJson["data"].First["errors"]; if (errors != null) { var error = errors.First; if (error != null) { // Quoted for the moment, it can be useful in the future if we want to have more structured intel on Facebook handles. //var line = error["line"]; //var productSku = error["id"]; //var message = error["message"]; var errorLog = T("Error when checking Facebook Shop handle").Text; errorLog += Environment.NewLine + containerJson; errorLog += Environment.NewLine + handlesJson.ToString(); Logger.Error(errorLog); // Quoted for the moment, it can be useful in the future if we want to have more structured intel on Facebook handles. //while (error != null) { // error = error.Next; // if (error != null) { // line = error["line"]; // productSku = error["id"]; // message = error["message"]; // } //} } } } } else { Logger.Debug(T("Invalid Facebook api response. Product is not synchronized on Facebook Shop.").Text); } } } catch (Exception ex) { Logger.Debug(ex, T("Invalid Facebook api response. Product is not synchronized on Facebook Shop.").Text); } } }
public static FacebookShopServiceContext From(FacebookShopSiteSettingsPart part) { return(new FacebookShopServiceContext() { ApiBaseUrl = part.ApiBaseUrl, DefaultJsonForProductUpdate = part.DefaultJsonForProductUpdate, BusinessId = part.BusinessId, CatalogId = part.CatalogId, //AppId = part.AppId, //AppSecret = part.AppSecret, AccessToken = part.AccessToken }); }
public void SyncProducts() { // Facebook Shop Site Settings: I need url, catalog id and access token. _fsssp = _workContext.GetContext().CurrentSite.As <FacebookShopSiteSettingsPart>(); FacebookShopServiceContext ctx = new FacebookShopServiceContext() { ApiBaseUrl = _fsssp.ApiBaseUrl, BusinessId = _fsssp.BusinessId, CatalogId = _fsssp.CatalogId, AccessToken = _fsssp.AccessToken }; // Query on published products, to send them all in a single request to Facebook api. // Every call to Facebook api sends the update of 20 products. int step = 20; // I look for the FacebookShopPart because I may have some products I don't need to synchronize on Facebook Shop (without the FacebookShopProductPart or with the SynchronizeFacebookShopFlag disabled). var query = _contentManager.Query <FacebookShopProductPart, FacebookShopProductPartRecord>(VersionOptions.Published) .Where(fp => fp.SynchronizeFacebookShop == true); for (int count = 0; count < query.Count(); count += step) { var facebookParts = _contentManager.Query <FacebookShopProductPart, FacebookShopProductPartRecord>(VersionOptions.Published) .Where(fp => fp.SynchronizeFacebookShop == true) .Slice(count, step); // I build a container for each slice of the query results. FacebookShopRequestContainer requestContainer = new FacebookShopRequestContainer(); foreach (var facebookPart in facebookParts) { var jsonContext = GetJsonContext(facebookPart.ContentItem); if (jsonContext != null && jsonContext.Valid) { requestContainer.Requests.Add(jsonContext); } else if (jsonContext != null) { Logger.Error(T("Product {0} can't be synchronized on Facebook catalog.", jsonContext.RetailerId).Text); Logger.Error(jsonContext.Message.Text); } } // I can now send the request to Facebook api. // This call contains every valid product in the slice from the query. FacebookShopProductBatch(requestContainer); } }
public FacebookShopRequestContainer RemoveProduct(FacebookShopProductDeleteRequest context) { FacebookShopRequestContainer requestContainer = new FacebookShopRequestContainer(); requestContainer.Requests.Add(context); // Facebook Shop Site Settings: I need url, catalog id and access token. _fsssp = _workContext.GetContext().CurrentSite.As <FacebookShopSiteSettingsPart>(); FacebookShopServiceContext ctx = new FacebookShopServiceContext() { ApiBaseUrl = _fsssp.ApiBaseUrl, BusinessId = _fsssp.BusinessId, CatalogId = _fsssp.CatalogId, AccessToken = _fsssp.AccessToken }; FacebookShopProductBatch(requestContainer); return(requestContainer); }