June 17, 2023
In today's fast-paced digital world, effective management of customer information and seamless workflow integration are key to success for any business, especially in the IT industry. Two powerful platforms that can significantly enhance your productivity and customer management are ITGlue and Salesforce. In this blog post, we'll explore How to integrating ITGlue with Salesforce and how this integration can streamline your workflow, boost efficiency, and provide a better customer experience.
1. What is ITGlue Integration with Salesforce.
2. Manage Orgnization on ITGlue with Salesforce's Account.
3. Create Assets from ITGlue in Salesforce.
4. Manage Assets on ITGlue as well as Salesforce.
ITGlue Integration with Salesforce refers to the process of connecting and synchronizing data between ITGlue, a popular IT documentation platform, and Salesforce, a leading customer relationship management (CRM) platform. This integration allows businesses to seamlessly share and access information between the two systems, enabling improved collaboration, efficiency, and customer management.
The integration typically involves establishing a connection between ITGlue and Salesforce using an integration solution or middleware. This connection enables the automatic transfer of data, such as customer information, asset details, documentation, configurations, passwords, and more, between the two platforms.
Overall, the ITGlue Integration with Salesforce provides businesses with a unified system for managing customer relationships, documentation, and IT assets. This integration optimizes workflows, enhances customer service, and contributes to improved operational efficiency and business growth.
At this point, we will see the management of Organization in ITGlue. If the account record in salesforce is created, the organization record is created on ITGlue automatically and if the account record is updated in the salesforce, the organization record is updated and if the account record is deleted in the salesforce, the organization is also deleted in the ITGlue. For more information you can refer this link
To meet this requirement, we need to create an apex class named AccountService. In this class, we will call the api to manage the organization record on the ITGlue.
Copy and paste the AccountService class with the below code snippet:
public class AccountService {public static void createOrganization(String accountId,String name,String status,String type,String billingCity,String billingCountry,String billingPostalCode,String billingState,StringbillingStreet){HttpRequest req = new HttpRequest();String key = [select Key__c from Access_Key__c limit 1].key__c;String orgType = KeyBindings.organizationTypes.get(type);String orgStatus = KeyBindings.organizationStatus.get(status);DataWrapper.Organization org = new DataWrapper.Organization(null, name, orgType, orgStatus);req.setBody(DataWrapper.generateOrganization(org.getOrganization()));req.setEndpoint('https://api.itglue.com/organizations');req.setMethod('POST');req.setHeader('x-api-key', 'ITG.'+ key);req.setHeader('Content-Type', 'application/vnd.api+json');req.setTimeout(60000);Http http = new Http();HTTPResponse res = http.send(req);//Organization has been created. 201 Createdif(res.getStatusCode() == 201){Map<String, Object> deserializedBody = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());Map<String, Object> dataNode = (Map<String, Object>)deserializedBody.get('data');String orgId = String.ValueOf(dataNode.get('id'));createLocations(key, accountId, orgId, billingStreet, billingCity, billingPostalCode, billingState, billingCountry);}else{String errorLog = 'Organization Not Created. Body:'+ res.getBody() +' Status:'+res.getStatus() + ' Status Code:'+ res.getStatusCode()+ ' Request:' + req + 'Request Body:' + req.getBody();throw new APICallException(errorLog);}}private static void createLocations(String key,String accountId,String orgId,String billingStreet,String billingCity,String billingPostalCode,String billingState,String billingCountry){String endPoint = 'https://api.itglue.com/organizations/'+ orgId + '/relationships/locations';populateStateMap(key, new List<Integer>{Integer.ValueOf(KeyBindings.organizationCountry.get(billingCountry))});DataWrapper.BillingAddress biilingAddr = new DataWrapper.BillingAddress(null, billingStreet, billingCity,KeyBindings.organizationState.get(billingState),billingPostalCode,KeyBindings.organizationCountry.get(billingCountry));HttpRequest req = new HttpRequest();req.setBody(DataWrapper.generateAddress(biilingAddr));req.setEndpoint(endPoint);req.setMethod('POST');req.setHeader('x-api-key', '***********************************************************');req.setHeader('Content-Type', 'application/vnd.api+json');req.setTimeout(60000);Http http = new Http();HTTPResponse res = http.send(req);//Location 201 Createdif(res.getStatusCode() == 201){Map<String, Object> deserializedBody = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());List<Object> dataNode = (List<Object>)deserializedBody.get('data');String str = JSON.serialize(dataNode[0]);Map<String, Object> objMap = (Map<String, Object>)JSON.deserializeUntyped(str);String locationid = String.ValueOf(objMap.get('id'));Account accRecord = new Account(id=accountId);accRecord.OrganizationId__c = orgId;accRecord.LocationId__c = locationid;accRecord.ITGlue_URL__c = 'https://aspiris.itglue.com/' + orgId;update accRecord;}else{String errorLog = 'Location Not Created. Body:'+ res.getBody() +' Status:'+res.getStatus() + ' Status Code:'+ res.getStatusCode()+ ' Request:' + req + 'Request Body:' + req.getBody();throw new APICallException(errorLog);}}private static void populateStateMap(String key, List<Integer> countryIds){//String stateId = getStateId(KeyBindings.organizationCountry.get(billingCountry), billingState);String ids = '';for(Integer countryid : countryIds){ids += countryid + ',';}ids = ids.removeEnd(',');Integer pageNumber = 1;while(pageNumber != 0){pageNumber = nextPage(key, ids, pageNumber);System.Debug('pageNumber ' + pageNumber);}System.Debug('KeyBindings.organizationState values ' + KeyBindings.organizationState.keySet());}private static Integer nextPage(String key, String ids, Integer pageNumber){HttpRequest req = new HttpRequest();String endPointUrl = 'https://api.itglue.com/regions?page[size]=1000&page[number]=' + pageNumber + '&filter[country_id]=' + ids;req.setEndpoint(endPointUrl);req.setMethod('GET');req.setHeader('x-api-key', 'ITG.'+key);req.setTimeout(60000);Http http = new Http();HTTPResponse res = http.send(req);//Get region - 200 OKif(res.getStatus() == 'OK'){Map<String, Object> deserializedBody = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());List<Object> dataNode = (List<Object>)deserializedBody.get('data');for(Object obj : dataNode){String str = JSON.serialize(obj);Map<String, Object> map3 = (Map<String, Object>)JSON.deserializeUntyped(str);String externalId = String.ValueOf(map3.get('id'));Object obj1 = map3.get('attributes');String str1 = JSON.serialize(obj1);Map<String, Object> map4 = (Map<String, Object>)JSON.deserializeUntyped(str1);String name = String.valueof(map4.get('name'));KeyBindings.organizationState.put(name, externalId);}Map<String, Object> meta = (Map<String, Object>)deserializedBody.get('meta');if(meta.get('next-page') == null){return 0;}else{return Integer.valueOf(meta.get('next-page'));}}else{System.debug(' Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status Code' + res.getStatusCode());}return 0;}@future(callout = true)public static void updateOrganization(Set<Id> orgIds, Set<Id> locationIds){try{String key = [select Key__c from Access_Key__c limit 1].key__c;List<Account> updateOrganization = [select OrganizationId__c, Name, Type, Status__c from Account where Id =:orgIds];List<Account> updateLocations = [select LocationId__c, BillingCity, BillingStreet, BillingCountry,BillingState, BillingPostalCode from Account where Id =:locationIds];//Update Organizationif(!updateOrganization.isEmpty()){String orgBody = DataWrapper.generateOrganizationUpdate(updateOrganization, true);if(orgBody != null){String endPoint = 'https://api.itglue.com/organizations';HttpRequest req = new HttpRequest();req.setBody(orgBody);req.setEndpoint(endPoint);req.setMethod('PATCH');req.setHeader('x-api-key', 'ITG.' + key);req.setHeader('Content-Type', 'application/vnd.api+json');req.setTimeout(60000);Http http = new Http();HTTPResponse res = http.send(req);//Bulk Organization Updated 200 OKif(res.getStatusCode() == 200){System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status ' + res.getStatusCode());}else{System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status Code' + res.getStatusCode());String errorLog = '<b>Error Log</b> <br/> <br/> <b>Body:</b>'+ res.getBody() +' <b>Status:</b>'+res.getStatus() + ' <b>Status Code:</b>'+ res.getStatusCode()+ ' <b>Request:</b>' + req + '<b>Request Body:</b>' + req.getBody();sendEmail('Failed - Organization not Updated', errorLog);}}}if(!updateLocations.isEmpty()){List<Integer> countryIds = new List<Integer>();for(Account ac: updateLocations){countryIds.add(Integer.valueOf(KeyBindings.organizationCountry.get(ac.billingCountry)));}populateStateMap(key, countryIds);String locationBody = DataWrapper.generateOrganizationUpdate(updateLocations, false);System.Debug('locationBody ' + locationBody);if(locationBody != null){String endPoint = 'https://api.itglue.com/locations';HttpRequest req = new HttpRequest();req.setBody(locationBody);req.setEndpoint(endPoint);req.setMethod('PATCH');req.setHeader('x-api-key', 'ITG.'+ key);req.setHeader('Content-Type', 'application/vnd.api+json');req.setTimeout(60000);Http http = new Http();HTTPResponse res = http.send(req);// Bulk Location Updated - 200 OKif(res.getStatusCode() == 200){System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status ' + res.getStatusCode());}else{String errorLog = '<b>Error Log</b> <br/> <br/> <b>Body:</b>'+ res.getBody() +' <b>Status:</b>'+res.getStatus() + ' <b>Status Code:</b>'+ res.getStatusCode()+ ' <b>Request:</b>' + req + '<b>Request Body:</b>' + req.getBody();sendEmail('Failed - Location not Updated', errorLog);}}}}catch(Exception ex){String emailBody = '<b>Message:</b>' + ex.getMessage() + ' <b>Cause:</b>' + ex.getCause() + ' <b>Stacktrace:</b>' + ex.getStackTraceString() + '<br/>' ;sendEmail('Failed - Organization=Location not Updated', emailBody);}}@future(callout = true)public static void deleteOrganization(Set<String> orgIds){System.Debug('deleteOrganization invoked');try {String json = DataWrapper.generateOrganizationDelete(orgIds);HttpRequest req = new HttpRequest();String key = [select Key__c from Access_Key__c limit 1].key__c;req.setBody(json);req.setEndpoint('https://api.itglue.com/organizations');req.setMethod('DELETE');req.setHeader('x-api-key', 'ITG.'+ key);req.setHeader('Content-Type', 'application/vnd.api+json');req.setTimeout(60000);Http http = new Http();HTTPResponse res = http.send(req);//Organization has been deleted. 200if(res.getStatusCode() == 200){System.debug('Success Response ' + res.getBody());}else{System.debug('Success Response ' + res.getBody());String errorLog = '<b>Organization Not Deleted. Body:</b>'+ res.getBody() +' <b>Status:</b>'+res.getStatus() + ' <b>Status Code:</b>'+ res.getStatusCode()+ ' Request:' + req + 'Request Body:' + req.getBody();sendEmail('Failed - Organization not Deleted', errorLog);}}catch (Exception ex){String emailBody = '<b>Message:</b>' + ex.getMessage() + ' <b>Cause:</b>' + ex.getCause() + ' <b>Stacktrace:</b>' + ex.getStackTraceString() + '<br/>' ;sendEmail('Failed - Organization not Deleted', emailBody);}}public static void sendEmail(String emailSubject, String emailBody){System.Debug('emailBody ' + emailBody);Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();mail.setTargetObjectId( UserInfo.getUserId() );mail.setSaveAsActivity( false );mail.setSubject(emailSubject);mail.setHtmlBody(emailBody);Messaging.SendEmailResult[] results = Messaging.sendEmail( new Messaging.SingleEmailMessage[] { mail } );if (results[0].success){System.debug('The email was sent successfully.' + results);} else{System.debug('results ' + results);}}}
At this point, we will get all the assets and create asset records into salesforce. For more information you can refer this link
To achieve this, please create an apex class named ConfigurationService then copy and paste with the below code snippet:
public class ConfigurationService{public class Model{String name;String modelId;String manufacturedId;public Model(String id, String mi, String mani){name= id;modelId = mi;manufacturedId = mani;}}
public class Configuration{String externalId;String name;String serialNumber;String assetTag;String configurationTypeName;String configurationStatusName;String manufracturerId;String modelId;String orgId;public Configuration(String id, String hn, String sn, String at, String ctn, String csn, String mai, String mi, String oi){externalId= id;name = hn;serialNumber = sn;assetTag = at;configurationTypeName = ctn;configurationStatusName = csn;manufracturerId = mai;modelId = mi;orgId = oi;}}@future(callout = true)public static void insertConfigurations(){//It will disable the Asset Trigger because we are inserting record from here. Once this process complete//trigger will be enabled.KeyBindings.triggerDisable = true;String key = [select Key__c from Access_Key__c limit 1].key__c;Map<String, Manufacturer__c> mapIdmanufracturer = fetchManufacturer(key);List<Model> models = fetchModel(key);List<Configuration> listConfiguration = fetchConfiguration(key);if(!mapIdmanufracturer.isEmpty()){System.Debug('manufracturer ' + mapIdmanufracturer.size());upsert mapIdmanufracturer.Values() Manufacturer_ID__c;}System.Debug('manufracturer inserted');Map<String, Model__c> mapExternalIDModel = new Map<String, Model__c>();if(!models.isEmpty()){for(Model mod : models){Id manufacturerId = null;Manufacturer__c manufacturerRec = mapIdmanufracturer.get(mod.manufacturedId);if(manufacturerRec != null)manufacturerId = mapIdmanufracturer.get(mod.manufacturedId).Id;mapExternalIDModel.put(mod.modelId, new Model__c(name = mod.Name, Model_ID__c = mod.modelId, Manufacturer__c = manufacturerId));}System.Debug('models ' + models.size());System.Debug('mapExternalIDModel ' + mapExternalIDModel.size());upsert mapExternalIDModel.values() Model_ID__c;}System.Debug('Model inserted');if(!listConfiguration.isEmpty()){System.Debug('listConfiguration Complete Size' + listConfiguration.size());//List<Manufacturer__c> listManufacturer = [select Manufacturer_ID__c from Manufacturer__c];Map<String, ID> mapManufacturerExternalIdInternalId = new Map<String, ID>();for(Manufacturer__c man : mapIdmanufracturer.values()){mapManufacturerExternalIdInternalId.put(man.Manufacturer_ID__c, man.Id);}//List<Model__c> listModels = [select Model_ID__c from Model__c];Map<String, ID> mapModelExternalIdInternalId = new Map<String, ID>();for(Model__c man : mapExternalIDModel.values()){mapModelExternalIdInternalId.put(man.Model_ID__c, man.Id);}List<Account> listAccount = new List<Account>([select id, OrganizationId__c from Account]);Map<String, String> mapExternalIdAccountId = new Map<String, String>();for(Account ac : listAccount){mapExternalIdAccountId.put(ac.OrganizationId__c, ac.Id);}System.Debug('mapExternalIdAccountId ' + mapExternalIdAccountId.size());List<Asset> listAsset = new List<Asset>();List<String> itGlueAssetList = new List<String>();List<Asset> lstAsset = [select Contact.AccountId,Configuration_Id__c,Name,SerialNumber,Asset_Tag_ID__c,Type__c,Status,Manufacturer__c,Model__c,AccountId from Asset];Map<String, Asset> mapSalesforceIdAsset = new Map<String, Asset>(lstAsset);for(Asset ast : lstAsset){mapSalesforceIdAsset.put(ast.Configuration_Id__c, ast);}for(Configuration conRecord : listConfiguration){if(mapExternalIdAccountId.get(conRecord.orgId) != null ){Asset ast1 = new Asset(Configuration_ID__c = conRecord.externalId,Name = conRecord.name,SerialNumber = conRecord.serialNumber,Asset_Tag_ID__c = conRecord.assetTag,Type__c = conRecord.configurationTypeName,Status = conRecord.configurationStatusName,Manufacturer__c = mapManufacturerExternalIdInternalId.get(conRecord.manufracturerId),Model__c = mapModelExternalIdInternalId.get(conRecord.modelId),AccountId = mapExternalIdAccountId.get(conRecord.orgId));Asset sfAsset = mapSalesforceIdAsset.get(conRecord.externalId);if(sfAsset == null){listAsset.add(ast1);}else{if(sfAsset.Name == ast1.Name&& sfAsset.SerialNumber == ast1.SerialNumber&& sfAsset.Asset_Tag_ID__c == ast1.Asset_Tag_ID__c&& sfAsset.Type__c == ast1.Type__c&& sfAsset.Status == ast1.Status&& sfAsset.Manufacturer__c == ast1.Manufacturer__c&& sfAsset.Model__c == ast1.Model__c&& sfAsset.AccountId == ast1.AccountId){//Do nothing.}else{listAsset.add(ast1);}}itGlueAssetList.add(conRecord.externalId);}}System.Debug('listAsset ' + listAsset.size());if(!listAsset.isEmpty()){List<Asset> assetToBeDelted = new List<Asset>();//List<Asset> lstAsset = [select Configuration_Id__c from Asset];for(Asset localAsset : lstAsset){if(!itGlueAssetList.contains(localAsset.Configuration_Id__c)){assetToBeDelted.add(localAsset);}}System.Debug('assetToBeDelted ' + assetToBeDelted);System.Debug('listAsset ' + listAsset.size());delete assetToBeDelted;//upsert listAsset Configuration_ID__c;String errorBody = '';Database.UpsertResult[] res = Database.upsert(listAsset, Asset.Fields.Configuration_ID__c, false);for (Integer i = 0; i < listAsset.size(); i++) {Database.UpsertResult s = res[i];Asset origRecord = listAsset[i];if (!s.isSuccess()) {for (Database.Error exd : s.getErrors()){String solution = '';if(String.ValueOf(exd.getFields()).contains('Type__c') && exd.getMessage().contains('restricted picklist field:')){solution = '<b>Solution - Please add Asset Type "' + exd.getMessage().substringAfterLast('field: ') + '" in the Type field.</b>';}else if(exd.getMessage().contains('Value does not exist or does not match filter criteria.') &&mapSalesforceIdAsset.get(origRecord.Configuration_ID__c) != null &&mapSalesforceIdAsset.get(origRecord.Configuration_ID__c).Contact != null &&mapSalesforceIdAsset.get(origRecord.Configuration_ID__c).Contact.AccountId != null &&mapSalesforceIdAsset.get(origRecord.Configuration_ID__c).Contact.AccountId != origRecord.AccountId){solution = '<b>Solution - Contact\'s account is not same to the IT Glue organization on this asset.</b>';}errorBody += '<b>The Error field is </b> '+exd.getFields()+'<br/>The Error Message is '+exd.getMessage()+'<br/>Asset Record to be Inserted/Updated '+origRecord+'<br/>The Status of Error is '+exd.getStatusCode() +'<br/>'+solution +'<br/><br/>';}}}//Process ModelList<Model__c> modelToBeDeleted = new List<Model__c>();Set<String> modelIds = mapModelExternalIdInternalId.keySet();for(Model__c existingModel : [select Model_Id__c from Model__c]){if(!modelIds.contains(existingModel.Model_Id__c)){modelToBeDeleted.add(existingModel);}}System.Debug('modelToBeDeleted ' + modelToBeDeleted);delete modelToBeDeleted;
//Process ManufacturerList<Manufacturer__c> manufacturerToBeDeleted = new List<Manufacturer__c>();Set<String> manuFacturerIds = mapManufacturerExternalIdInternalId.keySet();for(Manufacturer__c existingManufacturer : [select Manufacturer_ID__c from Manufacturer__c]){if(!manuFacturerIds.contains(existingManufacturer.Manufacturer_ID__c)){manufacturerToBeDeleted.add(existingManufacturer);}}System.Debug('manufacturerToBeDeleted ' + manufacturerToBeDeleted);delete manufacturerToBeDeleted;
if(errorBody != ''){sendEmail('Error in syncing data from IT Glue', errorBody);}}}KeyBindings.triggerDisable = false;}public static Map<String, Manufacturer__c> fetchManufacturer(String key){Map<String, Manufacturer__c> mapIdManufracturer = new Map<String, Manufacturer__c>();Integer pageNumber = 1;while(pageNumber != 0){pageNumber = nextPage(key, mapIdManufracturer, null, null, 'manufacturers', pageNumber);}return mapIdManufracturer;}public static List<Model> fetchModel(String key){List<Model> models = new List<Model>();Integer pageNumber = 1;while(pageNumber != 0){pageNumber = nextPage(key, null, models, null, 'models', pageNumber);}return models;}
public static List<Configuration> fetchConfiguration(String key){List<Configuration> listConfiguration = new List<Configuration>();Integer pageNumber = 1;while(pageNumber != 0){pageNumber = nextPage(key, null, null, listConfiguration, 'configurations', pageNumber);}return listConfiguration;}
private static Integer nextPage(String key, Map<String, Manufacturer__c> mapIdmanufacturers, List<Model> models,List<Configuration> listConfiguration, String endPoint, Integer pageNumber){System.Debug('nextPage invoked');HttpRequest req = new HttpRequest();req.setEndpoint('https://api.itglue.com/' + endPoint + '?page[size]=1000&page[number]=' + pageNumber);req.setMethod('GET');req.setHeader('x-api-key', 'ITG.'+key);Http http = new Http();HTTPResponse res = http.send(req);if(res.getStatus() == 'OK'){System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status ' + res.toString());Map<String, Object> deserializedBody = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());System.Debug(' deserializedBody ' + deserializedBody);List<Object> dataNode = (List<Object>)deserializedBody.get('data');for(Object obj : dataNode){String str = JSON.serialize(obj);Map<String, Object> map3 = (Map<String, Object>)JSON.deserializeUntyped(str);String externalId = String.ValueOf(map3.get('id'));Object obj1 = map3.get('attributes');String str1 = JSON.serialize(obj1);Map<String, Object> map4 = (Map<String, Object>)JSON.deserializeUntyped(str1);String name = String.valueof(map4.get('name'));if(mapIdmanufacturers != null){mapIdmanufacturers.put(externalId, new Manufacturer__c(Name = name, Manufacturer_ID__c = externalId ));}else if (models != null){models.add(new Model(name, externalId, String.valueof(map4.get('manufacturer-id')) ) );// models.add(new Model(Name = name, Model_ID__c = externalId,// Manufacturer_ID__c = String.valueof(map4.get('manufacturer-id')) ) );}else if(listConfiguration != null){listConfiguration.add(new Configuration(externalId,name,String.valueof(map4.get('serial-number')),String.valueof(map4.get('asset-tag')),String.valueof(map4.get('configuration-type-name')),String.valueof(map4.get('configuration-status-name')),String.valueof(map4.get('manufacturer-id')),String.valueof(map4.get('model-id')),String.valueof(map4.get('organization-id'))));}}System.Debug('For Loop Completed - Data Processing');Map<String, Object> meta = (Map<String, Object>)deserializedBody.get('meta');if(meta.get('next-page') == null){return 0;}else{System.Debug('Next Page ' + meta.get('next-page'));return Integer.valueOf(meta.get('next-page'));}}else{System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status String' + res.toString());}return 0;}
public static void sendEmail(String emailSubject, String emailBody){System.Debug('emailBody ' + emailBody);Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();mail.setTargetObjectId( UserInfo.getUserId() );mail.setSaveAsActivity( false );mail.setSubject(emailSubject);mail.setHtmlBody(emailBody);Messaging.SendEmailResult[] results = Messaging.sendEmail( new Messaging.SingleEmailMessage[] { mail } );if (results[0].success){System.debug('The email was sent successfully.' + results);} else{System.debug('results ' + results);}}}
At this point, we will see the management of the Asset records. We will manage the assets record vice-versa. For Example if the asset record is created in the salesforce then this asset record will be created on the ITGlue organization and if the asset record is created on the ITGlue organization then this record is created in the salesforce also. We will cover the update operation also. So let 's dive into it.
To manage the assets, we need to create the apex class named AssetService then copy and paste with the below code snippet:
public class AssetService{public static void createConfiguration(Id assetId, String organizationId, Map<String, String> configMap){System.Debug('createConfiguration invoked');String jsonString = AssetWrapper.createAsset(configMap);HttpRequest req = new HttpRequest();String key = [select Key__c from Access_Key__c limit 1].key__c;req.setBody(jsonString);req.setEndpoint('https://api.itglue.com/organizations/'+ organizationId + '/relationships/configurations');req.setMethod('POST');req.setHeader('x-api-key', 'ITG.'+ key);req.setHeader('Content-Type', 'application/vnd.api+json');req.setTimeout(60000);Http http = new Http();HTTPResponse res = http.send(req);//Configuration has been created.if(res.getStatus() == 'Created'){System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status ' + res.getStatusCode());System.Debug(' Status ' + res.toString());Map<String, Object> deserializedBody = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());List<Object> listData = (List<Object>)deserializedBody.get('data');String str = JSON.serialize(listData[0]);Map<String, Object> map1 = (Map<String, Object>)JSON.deserializeUntyped(str);String externalId = String.ValueOf(map1.get('id'));Asset ast = new Asset(Id = assetid);ast.Configuration_ID__c = externalId;update ast;}else{System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status Code' + res.getStatusCode());System.Debug(' Status String' + res.toString());String errorLog = 'Configuration Not Created. Body:'+ res.getBody() +' Status:'+res.getStatus() + ' Status Code:'+ res.getStatusCode()+ ' Request:' + req + 'Request Body:' + req.getBody();throw new APICallException(errorLog);}}
@future(callout = true)public static void updateConfiguration(Set<Id> assetIds){try{System.Debug('updateConfiguration invoked');String key = [select Key__c from Access_Key__c limit 1].key__c;List<Asset> updateConfiguration = [select Id, Name, SerialNumber, Asset_Tag_ID__c, Type__c, Status, Manufacturer__r.Manufacturer_ID__c, Model__r.Model_id__c, Account.OrganizationId__c, Configuration_ID__c from Asset where Id= :assetIds];if(!updateConfiguration.isEmpty()){String configBody = AssetWrapper.generateConfigurationUpdate(updateConfiguration);
if(configBody != null){String endPoint = 'https://api.itglue.com/configurations';HttpRequest req = new HttpRequest();req.setBody(configBody);req.setEndpoint(endPoint);req.setMethod('PATCH');req.setHeader('x-api-key', 'ITG.' + key);req.setHeader('Content-Type', 'application/vnd.api+json');req.setTimeout(60000);Http http = new Http();HTTPResponse res = http.send(req);//Updated return 200if(res.getStatusCode() == 200){Map<String, Object> deserializedBody = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());List<Object> listData = (List<Object>)deserializedBody.get('data');System.Debug('Total Updated' + listData.size());System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status ' + res.getStatusCode());System.Debug(' Status ' + res.toString());}else{System.debug('Success Response ' + res.getBody());System.Debug(' Status ' + res.getStatus());System.Debug(' Status Code' + res.getStatusCode());System.Debug(' Status String' + res.toString());String errorLog = '<b>Configuration Not Updated. Body:</b>'+ res.getBody() +' <b>Status:</b>'+res.getStatus() + ' <b>Status Code:</b>'+ res.getStatusCode()+ ' Request:' + req + 'Request Body:' + req.getBody();sendEmail('Failed - Configuration not Updated', errorLog);}}}}catch(Exception ex){String emailBody = '<b>Message:</b>' + ex.getMessage() + ' <b>Cause:</b>' + ex.getCause() + ' <b>Stacktrace:</b>' + ex.getStackTraceString() + '<br/>' ;sendEmail('Failed - Configuration not Updated', emailBody);}}
public static void sendEmail(String emailSubject, String emailBody){Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();mail.setTargetObjectId( UserInfo.getUserId() );mail.setSaveAsActivity( false );mail.setSubject(emailSubject);mail.setHtmlBody(emailBody);Messaging.SendEmailResult[] results = Messaging.sendEmail( new Messaging.SingleEmailMessage[] { mail } );if (results[0].success){System.debug('The email was sent successfully.' + results);} else{System.debug('results ' + results);}}}
To achieve the ITGlue-Salesforce integration, businesses can explore various integration solutions available in the market. These solutions provide configuration options to define synchronization rules, map data fields, and establish secure connections between the two platforms.
I hope this blog helped you!