/** * ─────────────────────────────────────────────────────────────────────────────────────────────────┐ * This Utility class is use for create and delete Webhook into the Shopify platform. * We use rest callout for create and delete webhooks into the Shopify platform. * Shopify API Documentation: https://shopify.dev/docs/admin-api/rest/reference * Create Shopify Store: https://www.shopify.com/signup?itcat=identity&itterm=create-new-store * Shopify API Release 2020: https://www.shopify.in/partners/blog/shopify-api-release-january-2020 * What is Person Account in Salesforce ? https://help.salesforce.com/articleView?id=account_person.htm&type=5 * ────────────────────────────────────────────────────────────────────────────────────────────────── * @author Sumit * ────────────────────────────────────────────────────────────────────────────────────────────────── */ public with sharing class HICWebhookUtility { //Providing Username and Password public static string USER_NAME; public static string PASSWORD; //Provide URL of the Shopify store to HTTP requests public static string shopifyUrl; public static List configurationList = new List(); public HICWebhookUtility(String store){ String query = 'Select '+CheckAccessibility.isAccessible('name, HIC_ShopifySync__Shopify_URL__c, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Opportunity__c, HIC_ShopifySync__Order__c, HIC_ShopifySync__Opportunity_Line_Item__c, HIC_ShopifySync__Order_Line_Item__c, HIC_ShopifySync__Order_Fulfillment__c, HIC_ShopifySync__Person_Account__c ','HIC_ShopifySync__HIC_Configuration__c')+' from HIC_ShopifySync__HIC_Configuration__c where '+CheckAccessibility.isAccessible('HIC_ShopifySync__Store__c', 'HIC_ShopifySync__HIC_Configuration__c')+' = \''+store+'\' LIMIT 1'; configurationList = Database.query(query); if(!configurationList.isEmpty()){ USER_NAME = configurationList[0].HIC_ShopifySync__API_Key__c; PASSWORD = configurationList[0].HIC_ShopifySync__Private_Key_Password__c; shopifyUrl = configurationList[0].HIC_ShopifySync__Shopify_URL__c; } } public HICWebhookUtility(List configList){ //String query = 'Select '+CheckAccessibility.isAccessible('name, HIC_ShopifySync__Shopify_URL__c, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Opportunity__c, HIC_ShopifySync__Order__c, HIC_ShopifySync__Opportunity_Line_Item__c, HIC_ShopifySync__Order_Line_Item__c, HIC_ShopifySync__Order_Fulfillment__c, HIC_ShopifySync__Person_Account__c ','HIC_ShopifySync__HIC_Configuration__c')+' from HIC_ShopifySync__HIC_Configuration__c where '+CheckAccessibility.isAccessible('HIC_ShopifySync__Store__c', 'HIC_ShopifySync__HIC_Configuration__c')+' = \''+store+'\' LIMIT 1'; configurationList = configList; if(!configurationList.isEmpty()){ USER_NAME = configurationList[0].HIC_ShopifySync__API_Key__c; PASSWORD = configurationList[0].HIC_ShopifySync__Private_Key_Password__c; shopifyUrl = configurationList[0].HIC_ShopifySync__Shopify_URL__c; } } @future(callout=true) public static void deleteWebhook(string objectName, string forDML, string store){ List webhookList = new list(); String trimmedObjectName = objectName.Trim(); // String query = 'Select '+CheckAccessibility.isAccessible('HIC_ShopifySync__Shopify_Object__c,HIC_ShopifySync__DML_Type__c,HIC_ShopifySync__SF_URL_Mapping__c, HIC_ShopifySync__Topic__c, HIC_ShopifySync__Webhook_Id__c ','HIC_ShopifySync__Webhook__c')+ ' from HIC_ShopifySync__Webhook__c where '+CheckAccessibility.isAccessible('HIC_ShopifySync__Shopify_Object__c','HIC_ShopifySync__Webhook__c')+' = \''+trimmedObjectName+'\' AND '+CheckAccessibility.isAccessible('HIC_ShopifySync__DML_Type__c','HIC_ShopifySync__Webhook__c')+' = \''+forDML+'\' LIMIT 500'; // webhookList = database.query(query); webhookList = [Select HIC_ShopifySync__Shopify_Object__c,HIC_ShopifySync__DML_Type__c,HIC_ShopifySync__Metafields_Namespace__c,HIC_ShopifySync__SF_URL_Mapping__c, HIC_ShopifySync__Topic__c, HIC_ShopifySync__Webhook_Id__c from HIC_ShopifySync__HIC_Webhook__c where HIC_ShopifySync__Shopify_Object__c =: trimmedObjectName AND HIC_ShopifySync__DML_Type__c =: forDML and HIC_ShopifySync__Store__c =: store LIMIT 500]; if(webhookList.isEmpty()) return; if(webhookList[0].HIC_ShopifySync__Webhook_Id__c != '' && webhookList[0].HIC_ShopifySync__Webhook_Id__c != null){ string webhookURL = 'webhooks/'+webhookList[0].HIC_ShopifySync__Webhook_Id__c; map responseMap = processRequest(webhookURL,'DELETE','',store); if(responseMap.containsKey('Ok')){ webhookList[0].HIC_ShopifySync__Webhook_Id__c = null; try{ Update webhookList[0]; }catch(Exception e){ system.debug('***Error in--'+e.getMessage()); } } }else{ list configList = new list(); // String Configquery = 'Select '+CheckAccessibility.isAccessible('id,HIC_ShopifySync__Salesforce_Site_URL__c,HIC_ShopifySync__Order_Sync__c,HIC_ShopifySync__Draft_Order_Sync__c,HIC_ShopifySync__Product_Sync__c,HIC_ShopifySync__Inventory_Location_Sync__c,HIC_ShopifySync__Customer_Sync__c,HIC_ShopifySync__Collection_Sync__c,name,HIC_ShopifySync__Default_Field_Mapping__c,HIC_ShopifySync__Batch_Is_Processing__c,HIC_ShopifySync__Specify_Close_Date__c, HIC_ShopifySync__Account_Contact__c, HIC_ShopifySync__Person_Account__c, HIC_ShopifySync__Default_Account__c, HIC_ShopifySync__Shopify_URL__c, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Opportunity__c, HIC_ShopifySync__Order__c, HIC_ShopifySync__Opportunity_Line_Item__c, HIC_ShopifySync__Order_Line_Item__c, HIC_ShopifySync__Order_Fulfillment__c','HIC_ShopifySync__Configuration__c')+' from HIC_ShopifySync__Configuration__c where '+CheckAccessibility.isAccessible('name','HIC_ShopifySync__Configuration__c')+' = \'Default\' LIMIT 1'; // configList = database.query(Configquery); configList = [Select id,HIC_ShopifySync__Salesforce_Site_URL__c,HIC_ShopifySync__Order_Sync__c,HIC_ShopifySync__Draft_Order_Sync__c,HIC_ShopifySync__Product_Sync__c,HIC_ShopifySync__Inventory_Location_Sync__c,HIC_ShopifySync__Customer_Sync__c,HIC_ShopifySync__Collection_Sync__c,name,HIC_ShopifySync__Default_Field_Mapping__c,HIC_ShopifySync__Batch_Is_Processing__c,HIC_ShopifySync__Specify_Close_Date__c, HIC_ShopifySync__Account_Contact__c, HIC_ShopifySync__Person_Account__c, HIC_ShopifySync__Default_Account__c, HIC_ShopifySync__Shopify_URL__c, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Opportunity__c, HIC_ShopifySync__Order__c, HIC_ShopifySync__Opportunity_Line_Item__c, HIC_ShopifySync__Order_Line_Item__c, HIC_ShopifySync__Order_Fulfillment__c from HIC_ShopifySync__HIC_Configuration__c where HIC_ShopifySync__Store__c =: store LIMIT 1]; if(configList.isEmpty()) return; System.debug('CheckingWebhookExist Called'); CheckingWebhookExist(webhookList[0].HIC_ShopifySync__Topic__c,configList[0].HIC_ShopifySync__Salesforce_Site_URL__c, webhookList[0].HIC_ShopifySync__SF_URL_Mapping__c,configList,webhookList,store); } } public static void CheckingWebhookExist(String topic,String SiteUrl,String returnClassUrl,list configList,List webhookList, String store){ String hiturl = 'webhooks.json?topic='+topic+'&address='+SiteUrl+'/services/apexrest/HIC_ShopifySync/'+returnClassUrl+'?objectname='+webhookList[0].HIC_ShopifySync__Shopify_Object__c+'%26DMLType='+webhookList[0].HIC_ShopifySync__DML_Type__c+'%26store='+store; String WebhookExistResponse ; if(!Test.isRunningTest()){ WebhookExistResponse = HIC_ShopifyUtility.fetchAllDataUsingId(hiturl,configList); }else{ WebhookExistResponse = '{ "webhooks": [{ "id": 515347349585, "address": "https://hic-sf-shopify-developer-edition.ap15.force.com/services/apexrest/HIC_ShopifySync/UpdateCollectionAndCollectAuthentication", "topic": "collections/update", "created_at": "2019-09-14T12:43:21+05:30", "updated_at": "2019-09-14T12:43:21+05:30", "format": "json", "fields": [], "metafield_namespaces": [], "api_version": "2019-07" }] }'; } if(WebhookExistResponse != null && WebhookExistResponse !=''){ map main = ( map)Json.deserializeUntyped(WebhookExistResponse); list listofExistingWebhook =(List) main.get('webhooks'); for(Object webobj: listofExistingWebhook){ Map singlewebhook = (Map) webobj; if(singlewebhook.containsKey('id')){ String webhookURL = 'webhooks/'+String.valueof(singlewebhook.get('id')); map responseMap = processRequest(webhookURL,'DELETE','',store); if(responseMap.containsKey('Ok')){ system.debug('Done'); } } } } } public static map processRequest(string objectType, string method, string body, string store){ new HICWebhookUtility(store); Http h = new Http(); HttpRequest req = new HttpRequest(); string ResponseBody; map statusVsBodyMap = new map(); string endPointValue = shopifyUrl + '/admin/'+objectType+'.json'; req.setEndpoint(endPointValue); //Adding certificate to HTTP Requests req.setClientCertificateName('Shopify'); /*Blob headerValue = Blob.valueOf(USER_NAME + ':' + PASSWORD); String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue); req.setHeader('Authorization', authorizationHeader);*/ req.setHeader('X-Shopify-Access-Token', PASSWORD); req.setHeader('content-type', 'application/json'); //Use get Method as we are retrieving data from shopify req.setMethod(method); req.setTimeout(120000); if(method == 'POST'){ req.setBody(body); } try { HttpResponse res = h.send(req); ResponseBody = res.getBody(); System.debug('ResponseBody--' +ResponseBody); System.debug('res Status--' +res.getStatusCode()); if(res.getStatusCode() == 200 || res.getStatusCode() == 201 || res.getStatusCode() == 204){ statusVsBodyMap.put('Ok',ResponseBody); return statusVsBodyMap; } }catch(Exception e){ if(ResponseBody == '' || ResponseBody == null){ ResponseBody = e.getMessage(); } System.debug('error --' +e.getMessage()); } statusVsBodyMap.put('Error',ResponseBody); return statusVsBodyMap; } //Deprecated @future(callout=true) public static void deleteWebhook(string objectName, string forDML){} @future(callout=true) public static void deleteWebhook(string objectName, string forDML, string store, String config){ List configList = (List)JSON.deserialize(config, List.Class); List webhookList = new list(); String trimmedObjectName = objectName.Trim(); // String query = 'Select '+CheckAccessibility.isAccessible('HIC_ShopifySync__Shopify_Object__c,HIC_ShopifySync__DML_Type__c,HIC_ShopifySync__SF_URL_Mapping__c, HIC_ShopifySync__Topic__c, HIC_ShopifySync__Webhook_Id__c ','HIC_ShopifySync__Webhook__c')+ ' from HIC_ShopifySync__Webhook__c where '+CheckAccessibility.isAccessible('HIC_ShopifySync__Shopify_Object__c','HIC_ShopifySync__Webhook__c')+' = \''+trimmedObjectName+'\' AND '+CheckAccessibility.isAccessible('HIC_ShopifySync__DML_Type__c','HIC_ShopifySync__Webhook__c')+' = \''+forDML+'\' LIMIT 500'; // webhookList = database.query(query); webhookList = [Select HIC_ShopifySync__Shopify_Object__c,HIC_ShopifySync__DML_Type__c,HIC_ShopifySync__SF_URL_Mapping__c,HIC_ShopifySync__Metafields_Namespace__c,HIC_ShopifySync__Topic__c, HIC_ShopifySync__Webhook_Id__c from HIC_ShopifySync__HIC_Webhook__c where HIC_ShopifySync__Shopify_Object__c =: trimmedObjectName AND HIC_ShopifySync__DML_Type__c =: forDML and HIC_ShopifySync__Store__c =: store LIMIT 500]; if(webhookList.isEmpty()) return; if(webhookList[0].HIC_ShopifySync__Webhook_Id__c != '' && webhookList[0].HIC_ShopifySync__Webhook_Id__c != null){ string webhookURL = 'webhooks/'+webhookList[0].HIC_ShopifySync__Webhook_Id__c; map responseMap = processRequest(webhookURL,'DELETE','',store, configList); if(responseMap.containsKey('Ok')){ webhookList[0].HIC_ShopifySync__Webhook_Id__c = null; try{ Update webhookList[0]; }catch(Exception e){ system.debug('***Error in--'+e.getMessage()); } } }else{ //configList = new list(); // String Configquery = 'Select '+CheckAccessibility.isAccessible('id,HIC_ShopifySync__Salesforce_Site_URL__c,HIC_ShopifySync__Order_Sync__c,HIC_ShopifySync__Draft_Order_Sync__c,HIC_ShopifySync__Product_Sync__c,HIC_ShopifySync__Inventory_Location_Sync__c,HIC_ShopifySync__Customer_Sync__c,HIC_ShopifySync__Collection_Sync__c,name,HIC_ShopifySync__Default_Field_Mapping__c,HIC_ShopifySync__Batch_Is_Processing__c,HIC_ShopifySync__Specify_Close_Date__c, HIC_ShopifySync__Account_Contact__c, HIC_ShopifySync__Person_Account__c, HIC_ShopifySync__Default_Account__c, HIC_ShopifySync__Shopify_URL__c, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Opportunity__c, HIC_ShopifySync__Order__c, HIC_ShopifySync__Opportunity_Line_Item__c, HIC_ShopifySync__Order_Line_Item__c, HIC_ShopifySync__Order_Fulfillment__c','HIC_ShopifySync__Configuration__c')+' from HIC_ShopifySync__Configuration__c where '+CheckAccessibility.isAccessible('name','HIC_ShopifySync__Configuration__c')+' = \'Default\' LIMIT 1'; // configList = database.query(Configquery); //configList = [Select id,HIC_ShopifySync__Salesforce_Site_URL__c,HIC_ShopifySync__Order_Sync__c,HIC_ShopifySync__Draft_Order_Sync__c,HIC_ShopifySync__Product_Sync__c,HIC_ShopifySync__Inventory_Location_Sync__c,HIC_ShopifySync__Customer_Sync__c,HIC_ShopifySync__Collection_Sync__c,name,HIC_ShopifySync__Default_Field_Mapping__c,HIC_ShopifySync__Batch_Is_Processing__c,HIC_ShopifySync__Specify_Close_Date__c, HIC_ShopifySync__Account_Contact__c, HIC_ShopifySync__Person_Account__c, HIC_ShopifySync__Default_Account__c, HIC_ShopifySync__Shopify_URL__c, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Opportunity__c, HIC_ShopifySync__Order__c, HIC_ShopifySync__Opportunity_Line_Item__c, HIC_ShopifySync__Order_Line_Item__c, HIC_ShopifySync__Order_Fulfillment__c from HIC_ShopifySync__HIC_Configuration__c where HIC_ShopifySync__Store__c =: store LIMIT 1]; if(configList.isEmpty()) return; System.debug('CheckingWebhookExist Called'); CheckingWebhookExist(webhookList[0].HIC_ShopifySync__Topic__c,configList[0].HIC_ShopifySync__Salesforce_Site_URL__c, webhookList[0].HIC_ShopifySync__SF_URL_Mapping__c,configList,webhookList,store); } } public static map processRequest(string objectType, string method, string body, string store, List configList){ new HICWebhookUtility(configList); Http h = new Http(); HttpRequest req = new HttpRequest(); string ResponseBody; map statusVsBodyMap = new map(); string endPointValue = shopifyUrl + '/admin/'+objectType+'.json'; req.setEndpoint(endPointValue); //Adding certificate to HTTP Requests req.setClientCertificateName('Shopify'); /*Blob headerValue = Blob.valueOf(USER_NAME + ':' + PASSWORD); String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue); req.setHeader('Authorization', authorizationHeader);*/ req.setHeader('X-Shopify-Access-Token', PASSWORD); req.setHeader('content-type', 'application/json'); //Use get Method as we are retrieving data from shopify req.setMethod(method); req.setTimeout(120000); if(method == 'POST'){ req.setBody(body); } try { HttpResponse res = h.send(req); ResponseBody = res.getBody(); System.debug('ResponseBody--' +ResponseBody); System.debug('res Status--' +res.getStatusCode()); if(res.getStatusCode() == 200 || res.getStatusCode() == 201 || res.getStatusCode() == 204){ statusVsBodyMap.put('Ok',ResponseBody); return statusVsBodyMap; } }catch(Exception e){ if(ResponseBody == '' || ResponseBody == null){ ResponseBody = e.getMessage(); } System.debug('error --' +e.getMessage()); } statusVsBodyMap.put('Error',ResponseBody); return statusVsBodyMap; } }