Skip to main content
Salesforce Objects:
  • wegive__Communication_List__c (custom object - Lists)
  • wegive__Communication_Preference__c (custom object - Preferences/Subscriptions)
WeGive Models:
  • CommunicationList
  • CommunicationListDonor (pivot/junction table)

Overview

This document describes how communication list and preference data syncs between WeGive and Salesforce:
  • Communication Lists define the list itself (e.g., “Monthly Newsletter”). Lists are pushed from WeGive to Salesforce only.
  • Communication Preferences track which donors are subscribed to which lists. Preferences sync both ways.
These features require the WeGive managed package to be installed in Salesforce, which includes the custom communication objects.

Part 1: Communication Lists

Salesforce Object: wegive__Communication_List__c
WeGive Model: CommunicationList

Direction and Mapping

  • Export to Salesforce only. There is no import of Communication Lists from Salesforce. Lists created or edited in Salesforce are not reflected in WeGive.
  • All list fields are Hard-coded; there are no mapping rules for this object.

Sync Configuration

  • Push communication lists - Enables the export of WeGive communication lists

Sync Triggers - Lists

A list is exported when it is created or updated in WeGive, and also automatically whenever a preference is pushed for a list that does not yet have a salesforce_id.

Field Mappings - Lists

Important Notes - Lists

  • Truncation: Salesforce caps Name at 80 characters and the description field at 255; WeGive values are truncated on export. The full values remain in WeGive.
  • Deletion: Deleting a list in WeGive does not delete the Salesforce record; the deleted timestamps are stamped instead.
  • Multi-entity orgs: wegive__WeGive_Entity__c is stamped on the list when the communication list domain is entity-scoped.
  • Matching: If the list has a salesforce_id it is UPDATED; otherwise a new record is CREATED. Lists are matched only by Salesforce ID.

Part 2: Communication Preferences (Subscriptions)

Salesforce Object: wegive__Communication_Preference__c
WeGive Model: CommunicationListDonor

Direction and Mapping

  • Both Ways. WeGive pushes preferences and pulls changes made in Salesforce.
  • All fields are Hard-coded; there are no mapping rules for this object.

Sync Configuration

  • Push communication list donors - Enables the export of subscriptions
  • Pull communication list donors - Enables the scheduled import of subscriptions
  • pull_deleted_communication_list_donors - When enabled, preferences deleted in Salesforce are removed in WeGive

Sync Triggers - Preferences

From WeGive to Salesforce (Export)

A preference is exported when a donor subscribes to a list in WeGive or a subscription changes. Before pushing, the integration ensures:
  1. The donor has a salesforce_id (individual, Contact) or salesforce_account_id (company, Account); if not, the donor is pushed first
  2. The list has a salesforce_id; if not, the list is pushed first

From Salesforce to WeGive (Import)

WeGive periodically polls for preference records whose LastModifiedDate falls in the window since the last sync. When pull_deleted_communication_list_donors is enabled, records with IsDeleted = true are also queried and the matching WeGive subscriptions are deleted.

Field Mappings - Preferences

On import the integration reads Id, wegive__Contact__c, wegive__Account__c, wegive__Communication_List__c, wegive__Subscribed__c, and wegive__WeGive_ID__c, and writes only the list link, donor link, salesforce_id, and subscribed on the WeGive side.

Important Notes - Preferences

Contact or Account

Exactly one of wegive__Contact__c or wegive__Account__c is populated, chosen by donor type. On import, a wegive__Contact__c value is matched against individual donors’ salesforce_id; a wegive__Account__c value is matched against company donors’ salesforce_account_id.

Subscription Status

wegive__Subscribed__c is the field that syncs in both directions. Changing it in either system updates the other on the next sync.

Double Opt-In

wegive__Double_Opt_In__c records whether the subscription required confirmation. It is export-only; editing it in Salesforce has no effect in WeGive.

Deletion Handling

  • WeGive to Salesforce: the Salesforce record is not deleted; wegive__Deleted_DateTime__c is stamped.
  • Salesforce to WeGive: with pull_deleted_communication_list_donors enabled, deleted preference records cause the matching WeGive subscription to be deleted.

Multi-Entity Orgs

Pulled preferences are scoped by the parent list’s wegive__WeGive_Entity__c when the communication list domain is entity-scoped.

Communication Preference Matching & Create/Update Logic

When WeGive Exports a Preference to Salesforce

  1. Ensure the donor and list exist in Salesforce (pushing them if needed)
  2. If the WeGive subscription has a salesforce_id: UPDATE the record
  3. Otherwise: CREATE a new record and store its ID (a lock prevents concurrent duplicate creation)

When Salesforce Exports a Preference to WeGive

  1. Find related records. Resolve the donor from wegive__Contact__c or wegive__Account__c, and the list from wegive__Communication_List__c. If either is not found in WeGive, the record is skipped with an error.
  2. Find or create the subscription, in order: by salesforce_id; by wegive__WeGive_ID__c; by donor + list; otherwise create new.
  3. Update the list link, donor link, salesforce_id, and subscribed, then save.

Integration with Contact Fields

Subscriptions can also be represented as fields on the Contact record for push purposes. This is driven entirely by Contact mapping rules:
  • Each WeGive communication list has an API name of the form CL_[list_id]_[list_slug] (CommunicationList::getApiNameAttribute()).
  • On Contact export, each list’s API name is exposed to Contact mapping rules with the donor’s subscribed value (true/false) — confirmed in compileDonorPayload(), which iterates $donor->communicationLists and sets $wegiveData[$cl->api_name] = $cl->pivot->subscribed. A field is written to Salesforce only if a Contact mapping rule maps that API name to a Salesforce field.
This mechanism is push-only, not bidirectional as previously described. There is no code path anywhere in the Salesforce integration that reads a CL_-prefixed key back off an imported Contact record. The only custom-field import path, fillCustomFieldsValues() (app/Traits/HasCustomFields.php), matches keys against the regex ^CF_(\d+)(?:_.*)?$ — CL_ (Communication List) keys never match, and any such value arriving via a Contact mapping rule is silently dropped, not converted into a subscription. If you need bidirectional subscription sync via Contact fields, request it from support/engineering rather than assuming the mapping-rule workflow already provides it — only the dedicated Preference object sync (Part 2 above) is genuinely bidirectional.
Without a Contact mapping rule referencing the list’s API name, no Contact field is written on export. The preference object sync described above works independently of this mechanism and remains the only bidirectional path. Example: List ID 123 with slug monthly_newsletter has API name CL_123_monthly_newsletter. A Contact mapping rule from CL_123_monthly_newsletter to a checkbox field on Contact keeps that checkbox in step with the subscription.

Required Fields

Communication Lists (WeGive to Salesforce): Name Communication Preferences (WeGive to Salesforce): wegive__Contact__c or wegive__Account__c, wegive__Communication_List__c, wegive__Subscribed__c Communication Preferences (Salesforce to WeGive): Id, a Contact or Account that already exists in WeGive, a Communication List that already exists in WeGive, wegive__Subscribed__c

Troubleshooting

Communication list not syncing:
  • Verify the managed package is installed and the Push communication lists toggle is enabled
  • Remember that lists are push-only; edits made in Salesforce do not flow back
Preference not syncing:
  • Verify the donor has a Salesforce ID (Contact or Account) and the list has a salesforce_id
  • On import, the donor and list must already exist in WeGive or the record is skipped
Subscription status not updating:
  • Confirm wegive__Subscribed__c is the field being changed; other fields are export-only
Deleted preferences reappearing in WeGive:
  • Enable pull_deleted_communication_list_donors
Contact field showing the wrong subscription value:
  • Confirm a Contact mapping rule references the list’s CL_[id]_[slug] API name
  • Remember this direction is push-only — editing the mapped field in Salesforce never updates the WeGive subscription; only the dedicated Preference object sync is bidirectional

Verified against the integration source, September 2026.