Skip to content

Note

This flow is self-documenting and should be viewed within Salesforce (Setup > Process Automations > Flows). This document is to support working through a visual flow. Please note: the flow commentary is produced using AI.

Overview#

Flow name: MoveData_Donation_Contact_Post Label: [MoveData] General: Contact - Post Upsert Type: Auto-Launched Flow Template API version: 60.0 Status: Active

This flow handles post-processing operations after account records are created or updated, including platform key association and account-contact relationship establishment. The flow operates in the context of account processing but creates contact relationships and manages platform key associations.

Purpose#

The flow performs post-upsert operations that:

  • Creates platform key associations linking accounts to external platform identifiers
  • Establishes account-contact relationships with configurable roles
  • Provides configurable platform key processing with disable options
  • Supports business relationship management through AccountContactRelation objects
  • Implements comprehensive error handling for platform key creation failures

Salesforce fields#

This flow interacts with the Salesforce Account, Contact, and AccountContactRelation objects. Below is a mapping of all fields utilised:

Object Field API name Field type Purpose in flow
Account Id ID Primary account record identifier
Contact Id ID Associated contact record identifier
AccountId Lookup to Account Links contact to the account
AccountContactRelation Id ID Relationship record identifier
AccountId Lookup to Account Account side of the relationship
ContactId Lookup to Contact Contact side of the relationship
Roles Picklist Business relationship role classification

Input variables#

Core record data#

Variable Type Required Description
Record Account SObject Yes The Account record that was created/updated
ParentAccount Account SObject No Parent account for relationship establishment
Platform String Yes External platform identifier
PlatformKey String Yes External platform's account identifier

Configuration variables#

Variable Type Default Description
Config_ContactDisablePlatformKey Boolean false Completely disable platform key processing
Config_ContactSetPlatformKey Boolean true Enable platform key creation
Config_AccountRelationshipDefault String "Business User" Default role for account-contact relationships
Config_AnonymousContactId String null The shared anonymous person account; no contact points are written for it
Config_ContactPointWrite Boolean false The contact point writer's one switch
Config_ContactPointAddressName String null Name pattern for ContactPointAddress, which requires a Name
Config_ContactPointAddressType String null Default AddressType — Billing or Shipping
Config_ContactPointPhoneType String null Default PhoneType — Home or Mobile
Config_ContactPointUsageType String null Default UsageType, used only where the platform sent none
Config_ContactPointSmsCapable Boolean false Sets IsSmsCapable on new phone contact points
Config_ContactPointPhoneMinimumDigits Number 8 Phone numbers shorter than this are skipped; 0 writes every number
Config_ContactAddressQualityIndex Number null Minimum address quality, 0.00 to 1.00; shared with the contact mapping flow

Output variables#

Variable Type Description
Errors String Collection Collection of errors from processing
Logs Apex Collection MoveDataLogEntry collection for logging
LogsJSON String JSON serialised version of logs
RecordList String Collection Contact point ids this donation created, matched or updated; merged into the notification's Records section

Flow logic#

1. Parent account validation#

The flow begins by checking if a parent account is provided:

  • Condition: Validates ParentAccount is not null and has a valid ID
  • Path selection: Determines whether to proceed with relationship creation or skip to platform key processing

2. Contact record retrieval#

When a parent account exists:

  • Query: Looks up contact records where AccountId equals the main record ID
  • Purpose: Finds existing contacts associated with the account for relationship establishment
  • Result: Single contact record for relationship processing

3. Account-contact relationship management#

Existing relationship check#

  • Query: Searches for existing AccountContactRelation records
  • Filters:
    • AccountId equals parent account ID
    • ContactId equals found contact ID
  • Purpose: Prevents duplicate relationship creation

Relationship creation#

When no existing relationship exists:

  • Object: Creates new AccountContactRelation record
  • Fields:
    • AccountId: Set to parent account ID
    • ContactId: Set to retrieved contact ID
    • Roles: Set to configured default role value
  • Business rule: Establishes formal business relationship between account and contact

4. Platform key association#

Configuration check#

  • Condition: Verifies Config_ContactDisablePlatformKey is not true and Config_ContactSetPlatformKey is not false
  • Purpose: Allows complete bypassing of platform key processing when disabled

Platform key validation#

  • Conditions:
    • Platform is not null
    • PlatformKey is not null
  • Purpose: Ensures required data exists before attempting platform key creation

Platform key creation#

  • Component: Uses movedata__PlatformKeyCreateComponent Apex action
  • Parameters:
    • ObjectId: The account record ID
    • Platform: External platform identifier
    • PlatformKey: Platform-specific account identifier
    • ErrorIfDifferentObjectId: Set to true for validation
  • Error handling: Captures creation failures and adds to error collection

Processing summary#

  1. Parent account check: Validate parent account availability
  2. Contact retrieval: Find associated contact record
  3. Relationship assessment: Check for existing account-contact relationships
  4. Relationship creation: Create new relationships when needed
  5. Platform key processing: Create platform key associations (if enabled)
  6. Error collection: Capture and report any processing failures

Configuration options#

Platform key control#

  • Complete disable: Config_ContactDisablePlatformKey = true skips all platform key processing
  • Suppress creation: Config_ContactSetPlatformKey = false skips platform key creation while leaving platform key matching in place
  • Relationship role: Config_AccountRelationshipDefault sets the business role for new relationships

Business relationship roles#

The default role "Business User" can be customised to reflect organisational relationship types:

  • Standard business contact relationships
  • Vendor/supplier relationships
  • Partner/alliance relationships
  • Customer/client relationships

Error handling#

Platform key error management#

  • Error collection: Platform key creation failures are captured in Errors collection
  • Fault tolerance: Processing continues even if platform key creation fails
  • Error attribution: Errors include specific details about platform key creation failures

Error handling#

Common error conditions handled:

  • Duplicate platform keys: When platform key already exists for different record
  • Invalid platform configuration: When platform settings are misconfigured
  • Record access issues: When insufficient permissions exist for relationship creation

Customising contact point mapping#

The contact point settings cover the choices most organisations need. When a customer needs logic the settings cannot express — a usage type that depends on the campaign, say, or a contact point they want deleted under some condition — the route is their own flow running after this one, not a modified copy of it.

There is no _EXT extension slot on a post-upsert stage: the mapping stages have one (PIPELINE_DONATION_CONTACT_MAPPING_EXT) and post-upsert does not. What a post stage does have is room for more than one handler. MoveData loads every enabled MoveData_Pipeline__mdt record whose label matches the stage and runs them in Order__c order, so a customer can register their own auto-launched flow against PIPELINE_DONATION_CONTACT_POST with an order after the package's.

Their flow then runs in the same transaction with the same inputs: Record is the Account, the payload values (Email, Phone, the MailingAddress_* fields) are all present, and so is every Config_ value. A Get Records on ContactPointEmail, ContactPointPhone or ContactPointAddress sees what MoveData has just written. Their RecordList, Logs and Errors outputs are read back the same way the package's are, so they can add their records to the notification's Records section, write their own log lines, and raise an error that fails the notification.

A customer who wants the whole job their own way should instead turn Write Contact Points off and do all of it in their flow.

Three things to say before recommending this:

  • A mapping extension flow is the wrong place for it. That runs before the upsert, and on a brand new supporter there is no Account id yet for a contact point to parent to.
  • A second handler on a package stage is supported by the pipeline but is not a documented extension point, so it is not covered by the package's own upgrade testing.
  • Order__c is a single namespace across every stage, so pick a number clear of the package's.

Check Config_ContactPostUpsertAsync too: when it is set, the whole post-upsert stage moves to a future method, and the customer's flow goes with it.

Dependencies#

  • movedata__PlatformKeyCreateComponent (Apex action)
  • movedata__NamePatternParserComponent (Apex action)
  • ContactPointWriteComponent (Apex action) — see Write Contact Points flow component
  • movedata__MoveDataLogEntry (Apex class)
Ask MoveData AI
Ask about setup, configuration, or troubleshooting
How can I help you with MoveData today?