Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


HTML
<style>
.release-box {
	height: 30px; 
	width: 100px; 
	padding-top: 8px;
	text-align: center; 
	border-radius: 5px; 
	font-weight: bold; 
	background-color: #8efeb3;  
	border-color: #FCE28A;
}

.release-box:hover {
  	cursor: hand;
    cursor: pointer;
    opacity: .9; 
}
</style>
<meta name="robots" content="noindex">

<div class="release-box">
<a href="https://docs.perspectium.com/display/krypton" style="text-decoration: none; color: #FFFFFF; display: block;">
Krypton
</a>
</div>




After following the steps to configure your DataSync application for Salesforce

integration

, you can then configure the

Perspectium

application to share data out of your Salesforce

Org.

org. The DataSync application has the following tabs to give you access to its features. Contact support@perspectium.com with any questions.


Panel
titlePerspectium application tabs in Salesforce
Table of Contents
maxLevel1


Shares

The Shares tab contains the different options to share data out of your Salesforce org:

Image Added


Dynamic Share

dynamic share allows for real-time sharing of Salesforce records as they are created, updated, and/or deleted. In other words, dynamic shares are caused by some triggering event (such as when cases are created, updated, or deleted). The data is shared to a subscriber, which can be the DataSync Agent, or any number of the other applications that Perspectium can integrate with.

When selecting the Dynamic Share option you are presented with the following options:

Image Added

Create New Dynamic Share so you can create a new dynamic share to share out records real time for a selected table (SObject).

View Dynamic Shares to see the dynamic shares you previously created and so you can update and delete them.


When creating or editing a dynamic share, do the following to ensure the dynamic share is set up correctly:

  1. Click Save to first save the dynamic share configuration. After you save, the dynamic share show a preview of the Apex trigger that will be created to capture real time changes.
  2. Click Save Trigger to save the Apex trigger. Repeat these steps anytime you make changes to the dynamic share.

If you prefer, you can modify the trigger directly by doing the following:

UI Expand
titleModify Salesforce Apex triggers

Monitoring

Receipts are automatically generated in your Salesforce org for your integration. Receipts indicate the delivery status for records that have been shared from your ServiceNow instance to your Salesforce org, allowing you to quickly identify successfully synced records as well as any records that have not yet been synced. Receipt delivery statuses include:

  • Success Your records were synced successfully

  • Pending Your Salesforce org is still processing the records shared out from your ServiceNow instance

  • Error Your records were not synced successfully

To view the receipts generated in your Salesforce org for data being shared out by ServiceNow, follow these steps:

Log into your Salesforce organization and click the Image Removed icon in the upper left-hand corner of the screen. Then, click the Perspectium Replicator app.
  • In the navigation bar near the top of the screen, click Receipts. Then, on the resulting page, click into the receipt that you want to view. Note that the receipt's delivery status will be listed as the value in the Batch Type field for the receipt.

    (info) NOTE: Keep in mind that receipts generated within Salesforce are receipts for data coming into Salesforce (inbound data). To view information for receipts for data coming out of ServiceNow (outbound data), see ServiceNow messages & receipts.

  • UI Expand
    titleView receipts of your integration
    Divbox
    stylebackground: white
    UI Expand
    titleChange Salesforce receipt default size


    Divbox
    stylebackground: white

    By default, Replicator SettingsSalesforce receipts will be generated for every 1,000 ServiceNow messages. However, you can change this default value within the  Apex triggers for your Salesforce org.

    Log into your sandbox Salesforce organization and click the Image Removed icon in the top right-hand corner of the screen. Then, click Setup.
    In the Quick Find window on the left side of the screen, type and then click Custom Settings (under Custom Code).
    Locate the ReplicatorSettings label from the list of Custom Settings. Then, under the Action column, click Manage for ReplicatorSettings.
    On the resulting ReplicatorSettings page, click Edit. Then, modify the values for the Batch Ack Size and Batch Error Size fields to be the number of messages (as a batch) that will trigger the generation of a receipt within Salesforce for inbound data.
  • Click Save.
  • Dynamic Share

    ui Salesforce

    service integration indicate the conditions that will trigger your Salesforce dynamic share. Update the Apex triggers for your Salesforce dynamic shares to filter out data that is sent from Salesforce to another app. The conditions for the SOQL query that runs as part of a dynamic share's Apex trigger can be manually configured on the Apex Triggers page. To modify the default Apex triggers created for your Salesforce service integration, you will need to create a Base64 encoded condition and specify the fields you want to include in the dynamic share's outbound messages. 

    First, make sure you have successfully installed DataSync. Also, for your Salesforce dynamic shares, make sure that the Active, Create, Update, and Include Attachment boxes are checked.

    WARNING! If you plan to make additional changes to your Apex triggers after manually modifying them, follow the procedure via SOQL query (rather than modifying your Apex triggers in the dynamic share form) to ensure that the manual modifications to your triggers are not overridden.

    ui
    -expand
    titleModify
    Apex triggers via SOQL queries


    Divbox
    stylebackground: white

    Salesforce Apex triggers for your Salesforce service integration indicate the conditions that will trigger your Salesforce dynamic share. Update the Apex triggers for your Salesforce dynamic shares to filter out data that is sent from Salesforce to another app. The conditions for the SOQL query that runs as part of a dynamic share's Apex trigger can be manually configured on the Apex Triggers page. To modify the default Apex triggers created for your Salesforce service integration, you will need to create a Base64 encoded condition and specify the fields you want to include in the dynamic share's outbound messages. 

    First, make sure you have successfully installed DataSync. Also, for your Salesforce dynamic shares, make sure that the Active, Create, Update, and Include Attachment boxes are checked.

    WARNING! If you plan to make additional changes to your Apex triggers after manually modifying them, follow the procedure via SOQL query (rather than modifying your Apex triggers in the dynamic share form


    1. Log into your Salesforce organization and click the Image Addedicon in the upper left-hand corner of the screen. Then, click the Perspectium DataSync app.

    2. In the navigation bar near the top of the screen, click Dynamic Shares. Then, click into the dynamic share that you want to modify Apex triggers for.

    3. To modify the SOQL query in your parent SObject's Apex trigger, create a query using the dropdowns next to Filter Field (choose a field to filter on, an operator, and type a value in the textbox). Then, click Add Filter to see how the triggerWhere clause in your Apex trigger will be updated. To save your parent SObject Apex trigger, scroll down to the bottom of the form and click Save. The Parent Apex Trigger Preview window will then update its triggerWhere clause to include the filter you just created. Finally, click Save Trigger to save the changes you made to your dynamic share.

    4. To modify the SOQL query in the Apex triggers for child SObjects associated with the parent SObject you are dynamic sharing, scroll down to the Child Settings section. Choose any child records you want to include in your dynamic share by using the arrows to move available child records from the list on the left to the list on the right next to Include Child Records. Click to highlight the child record that you want to modify the Apex trigger for. Then, create a query using the dropdowns next to Child
    ) to ensure that the manual modifications to your triggers are not overridden.
    Log into your Salesforce organization and click the Image Removedicon in the upper left-hand corner of the screen. Then, click the Perspectium Replicator app.
    In the Quick Find window on the left side of the screen, type and then click Apex Triggers (under Custom Code).
    Locate the SObject's Apex trigger that you want to modify. Apex triggers will be named in the following convention: PSP_<dynamic share name>_<child SObject name>_<parent SObject name>. Then, under the Action column, click Edit for the Apex trigger you want to modify.
    Replace the triggerWhere value with a Base64 encoded Apex trigger condition. For information on Apex trigger condition syntax, see Apex triggers. To Base64 encode your Apex trigger condition, you can use Base64encode.org.
    Image Removed
    Optionally, you can also modify the fields to be included in the Salesforce dynamic share's outbound message. To do this, locate the persp.PSPUtil.createPspOutMessage function and modify the third parameter for this function by including any table fields that you want to include in the outbound message when your Salesforce dynamic share triggers. Then, click Save near the top of the form to save your changes.
    Image Removed
  • Using Steps #3-5 as a guide, modify the Apex triggers for any Child SObjects included with your Salesforce dynamic share.
  • UI Expand
    titleModify Apex triggers via SOQL queries
    Divbox
    stylebackground: white
    1. Log into your Salesforce organization and click the Image Removedicon in the upper left-hand corner of the screen. Then, click the Perspectium Replicator app.
      In the navigation bar near the top of the screen, click Dynamic Shares. Then, click into the dynamic share that you want to modify Apex triggers for.
      To modify the SOQL query in your parent SObject's Apex trigger, create a query using the dropdowns next to  Filter Field (choose a field to filter on, an operator, and type a value in the textbox). Then, click Add Filter to see how the triggerWhere clause in your child Apex trigger will be updated. To save your parent child SObject Apex trigger, scroll down to the bottom of the form and click Save . The Parent Apex Trigger Preview window will then update its triggerWhere clause to include the filter you just created. Finally, click Save Trigger to Child Trigger. Finally, click Save and then Save Trigger to save the changes you made to your dynamic share.
    2. To modify the SOQL query in the Apex triggers for child SObjects associated with the parent SObject you are dynamic sharing, scroll down to the Child Settings section. Choose any child records you want to include in your dynamic share by using the arrows to move available child records from the list on the left to the list on the right next to Include Child Records. Click to highlight the child record that you want to modify the Apex trigger for. Then, create a query using the dropdowns next to Child Filter Field (choose a field to filter on, an operator, and type a value in the textbox). Then, click Add Filter to see how the triggerWhere clause in your child Apex trigger will be updated. To save your child SObject Apex trigger, click Save Child Trigger. Finally, click Save and then Save Trigger to save the changes you made to your dynamic share.
    UI Expand
    titleModify Apex triggers manually
    Divbox
    stylebackground: white



    UI Expand
    titleModify Apex triggers manually


    Divbox
    stylebackground: white
    1. Log into your Salesforce organization and click the Image Addedicon in the upper left-hand corner of the screen. Then, click the Perspectium DataSync app.

    2. In the Quick Find window on the left side of the screen, type and then click Apex Triggers (under Custom Code).

    3. Locate the SObject's Apex trigger that you want to modify. Apex triggers will be named in the following convention: PSP_<dynamic share name>_<child SObject name>_<parent SObject name>. Then, under the Action column, click Edit for the Apex trigger you want to modify.

    4. Replace the triggerWhere value with a Base64 encoded Apex trigger condition. For information on Apex trigger condition syntax, see Apex triggers. To Base64 encode your Apex trigger condition, you can use Base64encode.org.

      Image Added

    5. Optionally, you can also modify the fields to be included in the Salesforce dynamic share's outbound message. To do this, locate the persp.PSPUtil.createPspOutMessage function and modify the parameter for this function by including any table fields that you want to include in the outbound message when your Salesforce dynamic share triggers. Then, click Save near the top of the form to save your changes.

      Image Added

    6. Using Steps #3-5 as a guide, modify the Apex triggers for any Child SObjects included with your Salesforce dynamic share.




    Since Apex triggers are considered code that requires test coverage, you will need to have a test class for your Apex trigger to deploy it into production. See the following for an example Apex trigger test class.

    UI Expand
    titleSalesforce Apex Trigger Test
    UI Expand
    titleSalesforce Apex Trigger Test Class


    Divbox
    stylebackground: white

    Before deploying Apex triggers from sandbox to production, each trigger will require a test class to cover at least 75% of the trigger code.

    A test class will need to be written to test object for the trigger code as follows:

    • Trigger Actions - If the dynamic share has insert, update and/or delete selected. The test class will need to do the respective action selected (i.e. insert the object).
    • Trigger Conditions - An object matching the dynamic share conditions will need to have matching action(s) (such as an insert).
    • Apex Object Requirements - Mandatory fields required to do the action(s) above. For example, if the dynamic share is on the Contract object which requires the AccountId field be populated in order to insert a new Contract object. The AccountId field is a reference field to the Account object and requires an Account be created first.
    • Extra Trigger Options - Any other additional related triggers (such as Attachment and ContentDocumentLink triggers created when selecting the Include Attachments option) created with the dynamic share to share out those related records that will also need to be tested for trigger code coverage.

    See below test class for an example of testing a dynamic share Apex trigger created on the Contract object:

    • Trigger Actions - The insert and update actions are selected on the dynamic share so the test class inserts and updates Contract objects.
    • Trigger Conditions - The dynamic share is set to only trigger and executed when the Contract object's Status != 'Draft'. Contract objects are inserted with the Status = 'Draft' and then updated to 'In Progress'.
    • Apex Object Requirements - The Contract object requires the AccountId, Contract__Type__c, StartDate, EndDate, Preferred_Complement_Date__c fields to be populated. These fields are populated when created test Contract objects. Since AccountId is a reference field to the Account object, test Account objects are created first to use for this field.
    • Extra Trigger Options - The dynamic share has the Include Attachments option selected to trigger and share out attachments when they are added. Test Attachment and ContractDocumentLink objects are created to test these triggers and share out those objects. 
    Code Block
    languagejava
    titlePSPContractTriggerTest
    @isTest(SeeAllData=true)
    global class PSPContractTriggerTest {
        private static testmethod void  TestPSPContractTrigger() {
            List<persp__psp_replicate_conf__c> shares = [select Id,persp__create__c,persp__update__c,persp__delete__c,persp__table__c from persp__psp_replicate_conf__c where persp__table__c='Contract'];
            System.debug('Found Share: ' + shares.size());
            for(persp__psp_replicate_conf__c share : shares){
                System.debug('processing table: ' + share.persp__table__c);
                SObject shareObj = Schema.getGlobalDescribe().get(share.persp__table__c).newSObject() ;
    
    			//Account object is required to create a Contract
                Account testAccount = new Account(name='PSP_Test Account');
                insert testAccount;
                String testName = 'PSP_Test';
                List<Contract> contractList = new List<Contract>();
                for(Integer i = 0; i <= 200; i++){  
                    Contract testContract = new Contract(  
                        AccountId = testAccount.id,
                        Name = testName + i,
                        Short_Description__c = testName,
                        StartDate = System.today() + 1,
                        EndDate = System.today() + 3,
                        Preferred_Completion_Date__c = System.today() + 2,
                        Status = 'Draft',
                        Contract_Type__c = 'Other'
                    );
                        
                    contractList.add(testContract);
                }
                    
                insert contractList;
                    
                if(share.persp__update__c){
                    String q = 'select Id, Status from ' + share.persp__table__c + '  WHERE Short_Description__c =: testName LIMIT 1';
                    List<Contract> sobjList = Database.query(q);
                    if (sobjList.size() == 0)
                        continue;
                     
                    System.debug('returned: ' + sobjList.size());
                    System.assertEquals(sobjList.size(), 1);
                    for(Contract o : sobjList){
                        o.Status = 'In Progress';
                        update o;
                        
                  		
                        String body1='x';
                        Blob b = Blob.valueOf(body1);
                        Attachment attach1= new Attachment();
                        attach1.Name = 'Test Attachment';
                        attach1.ParentId = o.Id;
                        attach1.Body = b;
                        insert attach1; 
                
                        attach1.Name = 'Updates Test Attachment';
                        update attach1;
                        System.assertEquals(attach1.Name, 'Updates Test Attachment');
                        delete attach1;
                        
                        
                     
                        //ContentDocumentLink Test                    
                        ContentVersion contentVersion = new ContentVersion(
                          Title = 'Test',
                          PathOnClient = 'Test',
                          VersionData = Blob.valueOf('Test Content'),
                          IsMajorVersion = true
                        );
                        insert contentVersion;    
                        List<ContentDocument> documents = [SELECT Id, Title, LatestPublishedVersionId FROM ContentDocument];
                        
                        //create ContentDocumentLink  record 
                        ContentDocumentLink cdl = New ContentDocumentLink();
                        cdl.LinkedEntityId = o.id;
                        cdl.ContentDocumentId = documents[0].Id;
                        cdl.shareType = 'V';
                        insert cdl;
                        cdl.shareType = 'I';
                        update cdl;
    
    					try {
     						Delete cdl;
    					} catch (Exception e) {
        					System.debug('Error deleting ContentDocumentLink');
    					}
    
                    } // end for(Contract o : sobjList){
                } // end if(share.persp__update__c){
            } // end for(persp__psp_replicate_conf__c share : shares)
         } // end testmethod()
    }  
    






    UI Expand
    titleBypass usersInclude child records


    Divbox
    stylebackground: white

    This feature allows you to limit unnecessary users from triggering a dynamic share. This is especially useful for Salesforce users that are loading large records via Data Loader and subsequently do not want the records to be dynamically shared.

    This feature is located within the Dynamic Share Trigger Builder Properties page.

    To use the trigger bypass, enter the email of the user you want to exclude in the Bypass Users field. Once the properties page is saved, it will take effect immediately and all Dynamic Shares will be bypasses for the users specified.

    UI Expand
    titleInclude child records
    Divbox
    stylebackground: white

    The Include Child Records option provides a way to share out child records of a parent record. This is done by creating Apex triggers so as to capture events on those child tables, and filtering to only share out child records related to the parent record.

    After selecting the parent table on a dynamic share form, the Include Child Records option will populate with child tables that support Apex triggers. Select those tables where you want to share child records from.

    For example, if you select the Case table for the dynamic share and want to share out comments on Case records, select the CaseComment table in the Include Child Records option:

    Image Removed

    Like attachments, this option currently only supports sharing out all fields of the child tables.

    As is the case with the Apex trigger created for the parent table specified in the share, any triggers created for the child tables will be set to blank when the dynamic share is set as inactive and/or you remove a child table from the selected list (i.e. if you first select the CaseComment table in the Include Child Records option, and create a trigger for it, and then later you decide to remove the CaseComment table from the selected list). This is done to be consistent with the approach of not deleting Apex Triggers, since Apex triggers can only be created in sub-prod orgs and moved over to prod orgs. (i.e. once you delete an Apex trigger in production you can't recreate it without going through the process of doing it in a sub-prod).

    Apex triggers on the child tables can be deleted but when the Apex trigger is deleted on the parent table, notably when the dynamic share itself is deleted.

    Bulk Share

    UI Expand
    titleCreate a scheduled Salesforce bulk share
    Divbox
    stylebackground: white

    You can use this feature to schedule one or more bulk shares to occur at specific times or In a repeated time interval.

    Log into your Salesforce organization and click the Image Removed icon in the upper left-hand corner of the screen. Then, click the Perspectium Replicator app.
    In the navigation bar near the top of the screen, click Scheduled Bulk Shares. In the upper left-hand corner of the resulting page, click New Scheduled Bulk Share.
    Select a date and time in the Scheduled Date Time field for when to start bulk sharing records, and the Days and Hours to repeat the process in the Repeat Interval field. 
    In the Available Bulk Shares, select which bulk shares you want to schedule and click Image Removed. Check the Active box to activate the scheduled bulk share. 
  • Click Save.
  • UI Expand
    titlePreview a Salesforce bulk share
    Divbox
    stylebackground: white

    Before executing a Salesforce bulk share, you can preview the bulk share to see how many records will be shared out.

    Log into your Salesforce organization and click the Image Removedicon in the upper left-hand corner of the screen. Then, click the Perspectium Replicator app.
    In the navigation bar near the top of the screen, click Bulk Shares. In the upper left-hand corner of the resulting page, click to the bulk share you want to preview.
  • Click Preview.
  • UI Expand
    titleClone a Salesforce bulk share
    Divbox
    stylebackground: white

    After executing a Salesforce bulk share, you can clone the bulk share with the following steps: 

    Log into your Salesforce organization and click the Image Removedicon in the upper left-hand corner of the screen. Then, click the Perspectium Replicator app.
    In the navigation bar near the top of the screen, click Bulk Shares. In the upper left-hand corner of the resulting page, click to the bulk share you want to clone.
  • Click Clone.
  • Queues

    Messages

    Migrating a Salesforce Sandbox to Production

    UI Expand
    titleSalesforce sandbox to production
    Divbox
    stylebackground: white

    Salesforce sandboxes are used to develop and test changes for your organization in an environment that doesn't affect any real data or applications. When development and testing is done, you can migrate these changes from the sandbox to the production org using change sets.

    This is especially useful for deploying Apex triggers in production orgs. Dynamic shares in the Perspectium Salesforce Package use Apex triggers, similar to how business rules capture changes in ServiceNow. However, unlike ServiceNow where you can create business rules in a production ServiceNow instance, Salesforce requires you deploy Apex triggers by creating them in a sandbox org and then moving them over to your production org using change sets

    Apex triggers use Apex code to execute the Perspectium application's code to share records out of Salesforce. To deploy anything containing Apex code (such as Apex triggers) in production, you must have 75% test coverage of all Apex code. By default, the Perspectium Package comes with a test class that covers the basic components of Perspectium's Apex code including the dynamic share Apex triggers. However you may need to add an additional test class to your change set that tests your trigger's Apex code (especially if there are any customizations) to ensure this 75% coverage of all Apex code. An example of a test class that tests the dynamic share Apex trigger code can be found here.

    (info) NOTE: Your Apex trigger trigger should reference a queue that has an alias. When migrating your Apex trigger from sandbox to production using change sets, the Apex trigger code cannot be changed. So using the same alias name when creating a queue in sandbox and creating a queue in production allows you to specify different queues in your sandbox and production orgs that can use the same Apex trigger.

    Prerequisites:

    (warning) You will need to have two Salesforce orgs:

    • A sandbox org sending an outbound change set
    • A production org receiving an inbound change set 
    • The Perspectium Package is installed and configured in both orgs before the migration process begins
    Procedure:
    UI Expand
    titleSandbox Salesforce Org Sending Outbound Change Set
    Divbox
    stylebackground: white

    Create Apex test classes for your dynamic share Apex triggers to ensure 75% test coverage of all Apex code. An example of a test class that tests the dynamic share Apex trigger code can be found here.

    (info) NOTEYou do not need test classes for triggers created on the Account, Case, CaseComment, Task and Attachment objects as the Perspectium Package's included test classes covers these objects as part of test coverage for the application's main components.
    Log into your Salesforce sandbox org and click theImage Removedicon in the top right-hand corner of the screen. Then, click Setup.
    In the Quick Find window on the left side of the screen, type Apex Test Execution and then click choose the Apex Test Execution option under Custom Code.
    Image Removed

    The Include Child Records option provides a way to share out child records of a parent record. This is done by creating Apex triggers so as to capture events on those child tables, and filtering to only share out child records related to the parent record.

    After selecting the parent table on a dynamic share form, the Include Child Records option will populate with child tables that support Apex triggers. Select those tables where you want to share child records from.

    For example, if you select the Case table for the dynamic share and want to share out comments on Case records, select the CaseComment table in the Include Child Records option:

    Image Added

    Like attachments, this option currently only supports sharing out all fields of the child tables.

    As is the case with the Apex trigger created for the parent table specified in the share, any triggers created for the child tables will be set to blank when the dynamic share is set as inactive and/or you remove a child table from the selected list (i.e. if you first select the CaseComment table in the Include Child Records option, and create a trigger for it, and then later you decide to remove the CaseComment table from the selected list). This is done to be consistent with the approach of not deleting Apex Triggers, since Apex triggers can only be created in sub-prod orgs and moved over to prod orgs. (i.e. once you delete an Apex trigger in production you can't recreate it without going through the process of doing it in a sub-prod).

    Apex triggers on the child tables can be deleted but when the Apex trigger is deleted on the parent table, notably when the dynamic share itself is deleted.




    Bulk Share

    bulk share is a job that sends out bulk records from your Salesforce org as a pre-filtered range of data, at a point in time all at once. The data is shared to a subscriber, which can be the DataSync Agent, or any number of the other applications that Perspectium can integrate with.

    When selecting the Bulk Share option you are presented with the following options:

    Image Added

    Create New Bulk Share to create a new bulk share to share out records at a point in time for a selected table (SObject).

    View Bulk Shares allows you to see the bulk shares you previously created and so you can re-execute them.


    When creating a bulk share, you can Save the bulk share to save the bulk share or click Execute Now to save and execute the bulk share. Once a bulk has been executed, the bulk share's configurations cannot be changed but it can be executed again by clicking the Execute Now option again.

    Some notable features for bulk shares:

    Image Added

    Preview - The Preview button will allow you to get a preview of how records the bulk share will share out when executed.

    Clone - To create a copy of this bulk share. This is useful if you have a current bulk share that's been executed and you want to use it with changes to some of the configurations without having to create a brand new bulk share and reconfigure from scratch.

    Anchor
    bulk_share_enable_confirmation
    bulk_share_enable_confirmation

    Enable Confirmation - To have the DataSync Agent validate that it has received all the records shared out as part of this bulk share execution. The bulk share will send out compare messages that the Agent will use to validate records were received. If the Agent finds that a record is missing (by verifying the record exists when querying for it by the record's Id), it will send back a reshare message telling the Perspectium application in Salesforce to reshare those records. The application will create a new reshare bulk share (named Reshare <Bulk Share Name> Datetime i.e. Reshare AccountShare 2024-02-07 19:29:03) to share out the missing records and another compare message so the Agent can confirm its receive these records. This will repeat until the Agent has confirmed the records are all received.

    Share Updates Since Then - To share records only since the last time this bulk share was executed. After the first run (in which all records will be shared based on any filter conditions you enter), the bulk share will then only share any records that were updated since the last time the bulk share executed (using the bulk share's Started time as the last time it executed). This is useful if you set up the bulk share in a scheduled bulk share to share out only changes on a scheduled basis.

    Table Map - To specify a table map for transforming how records will be shared out.

    (info) NOTEThe Table Map and Fields to Share options are not compatible with each other.


    Scheduled Bulk Share

    Schedule one or more bulk shares to run at a scheduled interval you choose. After creating a bulk share, you can add the created bulk configuration as a child record to be run under the schedule specified within your scheduled bulk configuration.

    When selecting the Scheduled Bulk Share option you are presented with the following options:

    Image Added

    Create New Scheduled Bulk Share to create a new scheduled bulk share and select which bulk shares to be run and at what intervals.

    View Scheduled Bulk Shares allows you to see the scheduled bulk shares you previously created and modify their configurations


    When creating a new scheduled bulk share (or modifying a current one), you can do the following:

    1. Select a date and time in the Scheduled Date Time field for when to start bulk sharing records, and the Days and Hours to repeat the process in the Repeat Interval field. 
    2. In the Available Bulk Shares, select which bulk shares you want to schedule.
    3. Check the Active box to activate the scheduled bulk share. 
    4. Click Save to save your changes.


    Queues

    The Queues tab contain the queues in the Perspectium Integration Mesh you use to share out data from your Salesforce org and to subscribe to data into org.

    Image Added

    For sharing data out of your Salesforce org, you specify a Shared Queue where data will be saved into in the Perspectium Integration Mesh to be consumed by a target (such as the DataSync Agent consuming messages to save records into a target database).

    For subscribing to data into your org (i.e. you want to consume messages from the Integration Mesh that was shared by a different source system), you specify a Subscribed Queue in the Integration Mesh you will be consuming messages from.

    (info) NOTETo work with the Enable Confirmation bulk share feature, you will need to create a subscribed queue in the format of psp.out.salesforce.<instance>.<organization_name> in lower case and replacing spaces with _ so the Agent can send back messages for any missing records. The Instance and Organization Name can be found in Company Information

    Image Added

    For example, in the above screenshot where the Organization Name is PSP DS and the Instance is NA244, you would create a subscribed queue named psp.out.salesforce.na244.psp_ds.


    Some notable features when creating a new queue (or editing a current queue): 

    Direction - The direction of the queue, if its for sharing data out of your org (Share) or to subscribe to data into your org (Subscribe).

    Alias - A name as a reference to the queue. Alias are used to give a "name" to a queue so your dynamic share Apex trigger created in your sandbox org can be deployed in your production org. When migrating your Apex trigger from sandbox to production using change sets, the Apex trigger code cannot be changed. So using the same alias name when creating a queue in sandbox and creating a queue in production allows you to specify different queues in your sandbox and production orgs that can use the same Apex trigger.

    Queue Encryption Key - (Optional) Enter an encryption key for any shares/subscribes that use this queue. If not entered, the default key entered in Properties will be used. To ensure compatibility with all encryption methods, you will have to enter an encryption key of at least 32 characters.

    (info) NOTEBecause of how Salesforce encrypts sensitive information fields, the Queue Password and Queue Encryption Key will not be populated when you edit an existing queue. You do not have to re-enter these values when editing a queue unless you want to change their values. Leaving them blank when editing a queue and clicking Save will retain the current values.


    Once you've created a queue and saved it for the first time, you can come back to the Queue's form and the following options will be available:

    Image Added

    Get Queue Status - To check how many messages are currently in the queue in the Perspectium Integration Mesh. This will allow you to verify if your queue credentials are valid.

    Show Encryption Key - To see the encryption key set for this queue. If an encryption was not entered, the message No encryption key set for this queue will be shown (in which case the default encryption key will be used).


    Tools

    Click here to learn more about the different tools available for the Perspectium application.


    Messages

    The Messages tab contain the messages being sent to and received from the Perspectium Integration Mesh.

    Image Added

    Outbound Messages contains records that are queued to be sent to the Perspectium Integration Mesh. Once the messages have been sent their status will update to Sent

    (info) NOTE: If the Status is at "Ready", the Time Processed field will be blank. Once the status is "Sent", you will be able to see how long it took for the outbound message to be sent.  

    In the list view of Outbound Messages you will see the following options:

    Image AddedDelete All - To delete all messages in Outbound Messages. 

    Delete replicator messages - To delete all messages in Outbound Messages with a topic of replicator.

    Delete non-replicator messages - To delete all messages in Outbound Messages that do not have a topic of replicator.

    (info) NOTE: The above delete options only delete messages in the Outbound Messages table in the Perspectium application in Salesforce to help quickly clean up data in this table. This does not affect the messages in the queues in the Integration Mesh.


    Inbound Messages contains records that were shared to this Salesforce instance by other sources. The data flowing into this table will insert or update their respective tables and record once they are processed. 

    When clicking on a message (both inbound and outbound), you will see a Decrypt Value option. This option will decrypt the message's value field (using the encryption key from the queue or the default key if a key wasn't set in the queue) so you can see the encrypted content that was sent/received from the Integration Mesh.




    Dashboard

    The Dashboard tab contain an overview of your data exchanges with the Perspectium application in your Salesforce org.

    Image Added

    The Dashboard shows the following information:

    Queues - A list of the queues you have currently configured. You can toggle between seeing all queues, shared queues and subscribed queues.

    Messages - A list of outbound messages. You can toggle between seeing all messages, those that have a status of Error (to troubleshoot issues further), those that have a status of Ready (messages ready to be sent to the Integration Mesh) and Sent (messages that have already been sent to the Integration Mesh).

    Bulk Share History chart - A bar chart showing how much data you've bulk shared by date. If you have not executed any bulk shares, the chart will show the message No bulk share execution history found. Run some bulk shares to show history here. (info) NOTESalesforce's charting capabilities will reflect an empty chart if you share a similar amount of data for all days (since it will appear as a line at the bottom of the chart). Once your bulk sharing levels start to differentiate, then the chart will show bars properly.

    Bulk Shares - A list of the bulk shares you have currently configured.

    Dynamic Shares - A list of the dynamic shares you have currently configured.

    In the upper left-hand corner of the Apex Test Execution form, click Select Tests...
    Image Removed
    Check the box next to any custom Apex trigger test classes you created and then click the Run button. Verify all tests selected are able to complete without failing.
    Image Removed
    In the Quick Find window on the left side of the screen, type change sets and then click Outbound Change Sets (under Environments > Change Sets).
    Image Removed
    At the top of the Change Sets list, click New.
    Image Removed
    Type in a name for the change set. Then, click Save.
    Image Removed
    Click on Add under Change Set Components.
    Image RemovedClick the dropdown in the Component Type field, select Apex Trigger from the component type dropdown and checkmark the dynamic share Apex Triggers you want deploy in production. Select any test Apex Class you created if necessary.
    Image Removed
    Click Add To Change Set when you're done. 
    After selecting all the components, the browser will lead you back to the Change Set page. Click Upload.
    Image Removed
  • Choose the org that will receive the change set. Then, click Upload
  • Now that you've created a change set from your sandbox org and have sent it outbound to your production org, you can go to your production org to receive the change set inbound and deploy your dynamic share Apex triggers in production. See the next section for how to receive this change set.

    UI Expand
    titleProduction Salesforce Org Receiving Inbound Change Set
    Divbox
    stylebackground: white
    Log into your Salesforce production org and click theImage Removedicon in the top right-hand corner of the screen. Then, click Setup.
    In the Quick Find window on the left side of the screen, type and then click Inbound Change Sets (under Environments > Change Sets).
    Image Removed
    Under Change Set Awaiting Deployment, find the change set you previously sent outbound from your sandbox org and click Validate
    Image Removed
    Select one of the listed methods to test. Then, click Validate.
    Image Removed

    Back to the Inbound Change Sets, under Change Set Awaiting Deployment, find the change set you previously validated and click Deploy.

    Once you are in Deploy Change Set, choose Run local tests or Run all tests as the Test Option and click Deploy.
    Image Removed

    If the change set succeeds, the change set will be deployed. To see all migrated Apex triggers, go to Setup.

    If failed, update the selected test or make appropriate changes to the change set.

    The following is a successful deployment: 
    UI Expand
    titleSuccessful Deployment
    Divbox
    stylebackground: white

    Image Removed

    Image Removed

    Image Removed

    Image Removed

    Create a Salesforce shared queue
    NOTE: So as to allow the dynamic share Apex trigger to share records out to a queue, create a shared queue in your production org using the same queue alias as you created and used for this dynamic share in your sandbox org. 
  • Create a Perspectium job for Salesforce
  • Other

    UI Expand
    titleSalesforce attachments into ServiceNow
    Divbox
    stylebackground: white

    To read Salesforce attachments into ServiceNow, the u_sfdc_attachment_import import set table is provided as part of the Perspectium Salesforce Update Set for ServiceNow.

    The update set comes with a subscribe configuration for u_sfdc_attachment_import so records can be read into the import set table. A script action will then run on records being inserted to properly add and delete attachments.

    The Perspectium message that is shared out of Salesforce for an attachment will come with a ParentTable field that has the name of the Salesforce table that you can then use to determine which table this should map to in ServiceNow.

    The Set parent table to attach to business rule on the u_sfdc_attachment_import table is provided so you can modify the corresponding field in the import set table (u_parenttable) to the appropriate ServiceNow table based on how you are subscribing Salesforce records into ServiceNow.

    For example, if you are subscribing Salesforce Case records into ServiceNow Incident records, you can use the following business rule to update the field:

    Code Block
    if (current.u_parenttable == 'Case')
        current.u_parenttable = 'Incident';
    UI Expand
    titleServiceNow attachments into Salesforce
    Divbox
    stylebackground: white

    Table maps

    The SFDC Attachment table is included by default, therefore the table should already be set. Below is what it should look like:

    Image Removed

    Image Removed

    Source scripts

    Below are the source script for required fields above.

    attributes:

    Code Block
    answer= {"type":"Attachment"};

    To configure table map to receive File sObjects from ServiceNow, add the following instead:

    Code Block
    answer= {"type":"File"}; 

    body:

    Code Block
    var sysEncodedAttachment = new GlideSysAttachment();  
    var binData = sysEncodedAttachment.getBytes(current);  
    var StringUtil = (typeof GlideStringUtil != 'undefined') ? new GlideStringUtil() : new Packages.com.glide.util.StringUtil();
    answer = StringUtil.base64Encode(binData);

    @ExternalIdValue:

    Code Block
    var gr = new GlideRecord(current.table_name);
    gr.addQuery("sys_id", current.table_sys_id);
    gr.query();
    if (gr.next()){
    	answer = String(gr.number);
    }

    table_sys_id to ParentId:

    Code Block
    var gr = new GlideRecord(current.table_name);
    gr.addQuery("sys_id", current.table_sys_id);
    gr.query();
    if (gr.next()){
    	answer = String(gr.correlation_id);
    }

    Dynamic share

    After configuring the dynamic share from the ServiceNow and Salesforce Configuration page, the related list is necessary when sharing attachments. It may be added in the same dynamic share. Follow the images below to properly configure the related list for sharing attachments if it is not shown on the form.

    Image Removed

    Image Removed

    Image Removed

    After configuring the PSP Share Table Map table to be visible on dynamic share, proceed to the bottom and select the respective tab. Click New and add the following table and table map as shown below.

    Image Removed

    Image Removed

    UI Expand
    titleCoalesce on an External ID field
    Divbox
    stylebackground: white

    By default, records subscribed into Salesforce will coalesce on the ID field to determine if we should insert a new record or update a current record. So in most cases, you will want to create JSON messages to be consumed into Salesforce with the record's ID as found in Salesforce.

    For example, if you are replicating records between ServiceNow and Salesforce, you can use the table map feature of the Perspectium application to map out a field that holds the record's Salesforce Id. This Id field will generally be saved as the correlation_id field in ServiceNow tables. That way when the record is subscribed into Salesforce, it can use this Id field to find the record and update or insert as appropriate.

    However there may be cases where you want records in Salesforce to coalesce on an External ID field (such as when you want Salesforce to coalesce on the replicated record's ServiceNow sys_id) since records may generally be created on another platform like ServiceNow versus starting in Salesforce. Another reason is you may prefer to have more control in the ServiceNow app and have it be your central location for all data transformation and thus want to control coalescing there as well.

    Here's how:

    Create a new custom field in Salesforce on the table where you want to coalesce on an External ID field. Make sure to select the Text field option and check the box next to External ID labelled Set this field as the unique record identified from an external system.
    In the Perspectium application, navigate to your outbound messages to salesforce. Add ExternalIDField and ExternalIDValue attributes, so that when the message is received in Salesforce, it knows what the name of the external ID field is and what value to query for.
    Attribute NameDescriptionExternalIDFieldThe name of the External ID field in Salesforce as created in step 1ExternalIDValueA record's external ID value that we will use to query for in Salesforce in the External ID field
  • Create a field map in ServiceNow to target each of the above attributes, since it supports creating attributes in the outbound message.
  • Here's an example to Illustrate:

    Image Removed

    Using the above example, when the message is subscribed into Salesforce, the app will query the Case table and look for a record with ExternalID__c = 'f4e2e6104f120300b6a444b18110c726' and if it finds a record as such, use that record to update.

    Here's how the table field map would look for the ExternalIDField attribute:

    Image Removed

    In this example, the ExternalIdField is scripted to always use the same value since the custom External ID field in Salesforce will always be the same field name while the record's sys_id is used for the External ID field's value.

    Info

    The Salesforce app will automatically query for the specified External ID field and value if both attributes exist - otherwise, it will coalesce by the Id field with its normal default behavior.

    UI Expand
    titleChange Salesforce Job Intervals
    Divbox
    stylebackground: white

    You can schedule the MultiOutput Processing (share) and Replicator Subscriber (subscribe) jobs to run at predefined intervals, so that Salesforce data is effectively shared out. When you create a new Perspectium job for Salesforce (or edit an existing one), you can choose from a defined set of Job Intervals - the default settings include 30 seconds, 1 minute, 5 minutes, 15 minutes, 30 minutes, and 60 minutes. You may want to set your intervals to a custom time duration that isn't included in the default settings. Here's how:

    In your Salesforce organization, go to Settings (cog icon) > Setup
    Using the Quick Find window at the left, type and select Custom Settings (under Custom Code).
    From the list of Custom Settings, click the one labelled ReplicatorJobSettings.
    Under Custom Setting Definition Detail, click Manage.
    Click New (located towards the bottom of the page)
    Complete the fields on the Replicator JobSettings Edit form:
  • Use the Share job and Subscribe job fields to enter your desired interval(s), in seconds. For example, if you want to add an interval of 20 minutes, you would type 1,200.
  • (Optional) You can also modify the value for Max Apex Jobs.
  • Select and type a location/user.
  • Click Save.
  • UI Expand
    titleSubscribe to case comments
    Divbox
    stylebackground: white

    Salesforce stores comments in a separate table, so when you share out a Case's comments, you would share out the CaseComment table and then subscribe these records into an import set table that targets the sys_journal_field table.

    However, to get these comments to refresh properly in the incident's activity log as well as fire notifications, the best way to save these comments is using an onBefore transform map script in the import set table you create that targets the sys_journal_field table. Doing this will ensure that the activity log refreshes properly and any notifications set for incident comments also fire as expected. 

    Based on a) the incoming CaseComment JSON containing a reference to the Case record as stored in the ParentId field (which is mapped to u_parentid when read into the import set table) and b) this Case record ID stored in the correlation_id field in the incident table in ServiceNow, this script will find the incident record to add the comment through the incident:

    Code Block
    var incsysid='';
    var inc = new GlideRecord('incident');
    inc.addQuery('correlation_id',source.u_parentid);
    inc.query();
    if (inc.next()){
        incsysid = inc.sys_id;  //find sysid of incident from parentid in JSON
    }
    
    var gr = new GlideRecord('sys_journal_field');
    gr.addQuery('name', 'incident');
    gr.addQuery('element_id', incsysid);
    gr.addQuery('value', source.u_commentbody);
    gr.query();
    if (gr.getRowCount() > 0) {
        ignore = true; // found comment already previously don't need to re-add
    }
    else {
        var igr = new GlideRecord('incident');
        if (igr.get(incsysid)) {
            igr.comments.setJournalEntry(source.u_commentbody);
            igr.update();
            ignore = true;
        }
    }
    UI Expand
    titleSalesforce messages
    Divbox
    stylebackground: white

    Within the Perspectium application in your Salesforce instance, the top navigation menu includes tabs for Inbound Messages and Outbound Messages

    The Outbound Messages tab contains records that are queued to be sent to the Perspectium server. On this tab, you can view all messages, edit or delete an existing message, and create a new message.

    (info) NOTE: If the Status is at "Ready", the Time Processed field will be blank. Once the status is "Sent", you will be able to see how long it took for the outbound message to be sent.  

    The Inbound Messages tab contains records that were shared to this Salesforce instance by other sources, such as ServiceNow. The data flowing into this table will insert or update their respective tables and record once they are processed. On this tab, you can view all messages, edit or delete an existing message, and create a new message.

    UI Expand
    titleServiceNow to Salesforce comment configuration
    Divbox
    stylebackground: white

    Table maps

    Sending to the CaseComment table is also supported. Unlike Incident to Case, the target for this table is CaseComment and the source table is Journal Entry [sys_journal_field]. Below are attached images for examples:

    Image Removed

    Image Removed

    Source scripts

    Below are the source scrips for required fields above:

    attributes:

    Code Block
    answer = {"type":"CaseComment"};

    isPublished:

    Code Block
    if (current.element.contains("comment"))
    	answer = "true";

    ParentId:

    Code Block
    var gr = new GlideRecord('incident');
    gr.addQuery("sys_id", current.element_id.toString());
    gr.query();
    if (gr.next())
    	answer = gr.correlation_id.toString();

    @RecordId:

    Code Block
    var gr = new GlideRecord('incident');
    gr.get(current.element_id.toString());
    answer = gr.sys_id.toString();

    CommentBody:

    Code Block
    var pspUtil = new PerspectiumUtil();
    var gr = new GlideRecord('incident');
    gr.addQuery("sys_id", current.element_id.toString());
    gr.query();
    gr.next();
    
    var elementId = gr.sys_id;
    var tgr = new GlideRecord("sys_journal_field");
    tgr.addQuery("element_id", elementId);
    tgr.orderByDesc("sys_created_on");
    tgr.query();
    if (tgr.next())
    	pspUtil.addTag(tgr, "msp_client_incident_sent");
    
    answer = current.value;

    Transform maps

    Receiving into the CaseComment table is also supported. The source for this table is CaseComment and the target table is Journal Entry [sys_journal_field]. Below are attached images for examples:

    Image Removed

    Image Removed

    Source scripts:

    Below are the source scripts for the required fields above:

    element_id:

    Code Block
    var gr = new GlideRecord("incident");
    gr.addQuery("correlation_id", source.u_parentid);
    gr.query();
    gr.next();
    return gr.sys_id; // return the value to be put into the target field

    element:

    Code Block
    return "comments"; // return the value to be put into the target field

    name:

    Code Block
    return "incident"; // return the value to be put into the target field

    Once the field mappings are created, an onBefore transform script is necessary for insertion. Refer to the image and script below for an example.

    Image Removed

    Code Block
    var gr = new GlideRecord("incident");
    gr.addQuery("correlation_id",source.u_parentid);
    gr.query();
    gr.next();
    
    var elementId = gr.sys_id;
    var tgr = new GlideRecord("sys_journal_field");
    tgr.addQuery("element_id", elementId);
    tgr.addQuery("value", source.u_commentbody);
    tgr.orderByDesc("sys_created_on");
    tgr.query();
    if (tgr.next() && pspUtil.recordHasTag(tgr, "msp_client_incident_sent")) {
    	ignore = true;
    	return;
    }
    
    pspUtil.addTag(tgr, "msp_client_incident_sent");
    
    gr.comments.setJournalEntry(source.u_commentbody);
    gr.setForceUpdate(true);
    gr.update();

    Dynamic share

    After setting the table maps, dynamic share will be able to reference them properly. The following images are an example for configuring the ServiceNow Journal Entry (sys_journal_field) table to share out to Salesforce CaseComment object. Here is also a guide for how to set up a dynamic share.
    Info

    Keep in mind that from comments made in the Incident table are then created in the Journal Entry table. From there, the comments are then sent to CaseComment onto Salesforce.

    Image Removed

    Image Removed

    Image Removed

    Image Removed

    Be sure to include the “before share script” provided below. This will defer comments that do not have a correlation id and will put it on stand by.

    Code Blockvar gr = new GlideRecord("incident"); gr.addQuery("sys_id", current.element_id); gr.query(); gr.next(); if ((psp_action == 'update' || psp_action == 'insert') && gr.correlation_id == ''){ psp_action = 'deferred'; }