InCountry logo
mobile-nav
Search
  • Products
    • Platform
      • Overview
      • Compliance and security
      • How it works
      • For SaaS
      • For internal apps
    • Gateways
      • Email
      • HTML
      • Payments
      • Web Forms
  • Solutions
    • Energy
    • Financial services
    • Healthcare
    • Retail
    • Technology
  • Integrations
    • SaaS
      • Cegid
      • Intertrust
      • Mambu
      • PayPal
      • Salesforce
      • Segment
      • ServiceNow
      • Stripe
      • Twilio
      • Veeva Systems
    • IAAS
      • InCountry on Alibaba Cloud
      • InCountry on Yandex.Cloud
  • Resources
    • Country compliance
    • Documentation
    • Library
    • Partners
    • Pricing
  • About
    • Blog
    • Careers
    • Contact Us
    • FAQ
    • Leadership
  • Login
  • Schedule a Demo

›Administrator's guide

Home
  • InCountry Platform
Portal
  • Getting started
  • Documentation
    • Dashboard
    • Managing environments
    • Managing clients and integrations
    • Managing Border configuration
    • Managing serverless scripts
    • Managing file imports
    • Managing profile and organization
    • Managing users
    • Managing secret keys
    • Managing recommendation modules
    • Managing subscription
  • Release notes
Border
  • Documentation
  • Release notes
REST API
  • Documentation
  • How to test CRUD requests through REST API
  • Release notes
Serverless
  • Documentation
Salesforce
  • About
  • Overview
  • Quick start guide for three-model package
  • Quick start guide for legacy package
  • Administrator's guide
    • Managing the package
    • Managing permissions
    • Managing OAuth2 authentication and authorization
    • Managing certificates
    • Registering CSP Trusted Sites
    • Managing InCountry Endpoints
    • Managing REST endpoints
    • Managing InCountry flags
    • Loading the application
    • Managing data regulation policies
    • Managing protected fields
    • Hashing the UserName field
    • Managing custom objects
    • Replacing standard elements
    • Configuring record search
    • Managing components
    • Setting up Salesforce Experience Cloud
    • Managing serverless functions
    • Managing InCountry cache
    • Managing Apex triggers
    • Managing record synchronization
    • Using Email-to-Case feature
    • Debugging
  • Developer’s guide
    • Apex SDK
    • JavaScript API
    • Retrieving record statistics
    • Tracking field history
  • User's guide
    • Working with protected fields
    • Sending compliant email messages
    • Importing data into Salesforce
    • Migrating records
    • Managing audit reports
    • Converting leads
    • Managing reports
    • FAQ
    • Release notes
Payment Vault
  • Documentation
BYOK
  • Documentation
FAQ
  • How to use the InCountry platform
  • Integration options
  • Data regulation models
  • Limits and quotas
  • Video tutorials
Service Status
  • Status

Managing Apex triggers

Hide Heading
note

Management of Apex triggers is required for operation of the legacy replication model only.

If you use the replication data regulation policy within the InCountry Data Residency for Salesforce package, you need to create Apex triggers for each Salesforce object having regulated data.

The following example provides instructions on how to do this for the Lead object. Please use a similar approach for the rest of your Salesforce objects.

Lead trigger example

trigger InCountryLead on Lead (before insert, after insert, before update, after update, after delete, after undelete) {
    SObjectType triggerType = trigger.isDelete ? Trigger.old.getSObjectType() : Trigger.new.getSObjectType();

    if (!InCountryReplicationTriggerHandler.disableTrigger && !InCountryReplicationTriggerHandler.alreadyExecuted(triggerType)) {

        InCountryReplicationTriggerHandler handler = new InCountryReplicationTriggerHandler(triggerType.getDescribe().getName());
        if (Trigger.isBefore && (Trigger.isInsert || Trigger.isUpdate)) {
            // any Before trigger customer logic should be put before
            // handler.handleBeforeInsert(); call
            handler.handleBeforeInsert();
        } else if (Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate)) {
            handler.handleAfterInsert();
            InCountryReplicationTriggerHandler.registerExecution(triggerType);
            // any After trigger customer logic should be put after
            // handler.handleAfterInsert(); call
        } else if (Trigger.isAfter && Trigger.isUndelete) {
            handler.handleAfterUndelete();
        }
    }
    if (Trigger.isDelete && Trigger.isAfter) {
        SObjectType triggerType = trigger.isDelete ? Trigger.old.getSObjectType() : Trigger.new.getSObjectType();
        InCountryReplicationTriggerHandler handler = new InCountryReplicationTriggerHandler(triggerType.getDescribe().getName());
        handler.handleAfterDelete();
    }
}

handler.handleBeforeInsert();

It is required to execute the handler.handleBeforeInsert(); method after initialization of the field that defines a record as regulated and verifies that it is set up correctly.

The call determines whether a record falls under any configured conditions at the time of its execution. This means that before the handleBeforeInsert method is executed the record should have all fields set up properly to identify the record as regulated. Otherwise, such record is ignored.

The handleBeforeInsert method hashes protected field values of the record. This means that any value in the protected field will be replaced with a hashed value. Once the method has been executed, the record will no longer have clear-text values in protected fields for a while. For example:

Before execution of the handler.handleBeforeInsert(); Trigger.new method, there is one Lead record with the Email field storing the john.doe@incountry.com email. The Email field is configured as protected and the used hash function is Fixed Value. We want the fixed value to be like, hidden@hidden.hidden.

Use this program code:

System.debug('1 - Trigger.new: ' + Trigger.new);
LeadTriggerHandler.handler.handleBeforeInsert();
System.debug('2 - Trigger.new: ' + Trigger.new);

The code debugging will output the following:

1 - Trigger.new: (Lead:{Id=null, Email=john.doe@incountry.com, IsDeleted=false, MasterRecordId=null, Salutation=null, Website=null, PhotoUrl=null, ...})

2 - Trigger.new: (Lead:{Id=null, Email=hidden@hidden.hidden, IsDeleted=false, MasterRecordId=null, Salutation=null, Website=null, PhotoUrl=null, ...})

handler.handleAfterInsert();

The handler.handleAfterInsert(); method must be executed right after execution of the insert/update operation. The handleAfterInsert method executes the subsequent method to transfer protected records to the InCountry platform. The handleAfterInsert method makes a call to the InCountry REST endpoint.

Asynchronous update of records with protected values from the InCountry platform

The handler.handleAfterInsert(); executes the asynchronous method that sends protected data values to the InCountry platform. Once a successful response is received the method executes a DML update of records with their non-hashed values in Salesforce.

Before the DML statement, the disableTrigger flag is set as true (this is used to prevent the repeated (two-time) hashing of values).

InCountryReplicationTriggerHandler.disableTrigger = true;

During the trigger execution, the flag is set as true (InCountryReplicationTriggerHandler.disableTrigger == true). This is the only way to identify that non-hashed values are present in the transaction. You can run additional validations or other logic against PII fields when this flag is set as true.

← Managing InCountry cacheManaging record synchronization →
  • Lead trigger example
    • handler.handleBeforeInsert();
    • handler.handleAfterInsert();
  • Asynchronous update of records with protected values from the InCountry platform
InCountry logo blue
© InCountry 2022.
All rights reserved. InCountry, Inc
  • PRIVACY POLICY
  • TERMS OF SERVICE
  • Social share
    • YouTube logo
    • Facebook logo
    • Twitter logo
    • LinkedIn
  • Column 1
    • Products
      • Platform
        • Overview
        • Compliance and security
        • How it works
        • For SaaS
        • For internal apps
      • Gateways & Vaults
        • Email
        • HTML
        • Payments
        • Web Forms
    • Solutions
      • Energy
      • Financial services
      • Healthcare
      • Retail
      • Technology
  • Column 2
    • Integrations
      • SaaS
        • Cegid
        • Intertrust
        • Mambu
        • PayPal
        • Salesforce
        • Segment
        • ServiceNow
        • Stripe
        • Twilio
        • Veeva Systems
      • IAAS
        • InCountry on Alibaba Cloud
        • InCountry on Yandex.Cloud
  • Column 3
    • Resources
      • Country compliance
      • Documentation
      • Library
      • Partners
      • Pricing
    • About
      • Blog
      • Careers
      • Contact Us
      • FAQ
      • Leadership