

How to Bi-directional contact sync with Power Automate
Automatically sync contact updates between Google Sheets and Salesforce in real-time whenever either system changes.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Teams that maintain contact lists in both Sheets and Salesforce and need instant sync without manual copying.
Not ideal for
One-time imports or bulk migrations where Salesforce Data Loader would be faster and more reliable.
Sync type
real-timeUse case type
syncReal-World Example
A 25-person sales team keeps prospect research in Google Sheets while managing deals in Salesforce. When marketing updates contact details in Sheets, sales needs those changes in Salesforce instantly. Before automation, data got stale for days and reps called wrong phone numbers during outreach.
What Will This Cost?
Drag the slider to your expected monthly volume.
Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.





Prices shown for annual billing. Based on published pricing as of April 2026.
Estimated ROI
1000
min saved/mo
$583
labor value/mo
Free
no platform cost
Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.
Implementation
Import this workflow directly into Power Automate
Copy the pre-built Power Automate blueprint and paste it straight into Power Automate. All modules, filters, and field mappings are already configured — you just need to connect your accounts.
Before You Start
Make sure you have everything ready.
Field Mapping
Map these fields between your apps.
| Field | API Name | |
|---|---|---|
| Required | ||
| First Name | FirstName | |
| Last Name | LastName | |
Email | ||
6 optional fields▸ show
| Phone | Phone |
| Company | Account.Name |
| Job Title | Title |
| Lead Source | LeadSource |
| Mailing Street | MailingStreet |
| Mailing City | MailingCity |
Step-by-Step Setup
My flows > New flow > Automated cloud flow
Create Flow for Sheets to Salesforce sync
Go to make.powerautomate.com and click 'New flow' then 'Automated cloud flow'. Name it 'Sheets to Salesforce Contact Sync'. Search for 'Google Sheets' in the connector picker and select 'When a row is added, modified or deleted'. This triggers whenever your contact spreadsheet changes.
- 1Click 'New flow' in the top menu bar
- 2Select 'Automated cloud flow' from the dropdown
- 3Name the flow 'Sheets to Salesforce Contact Sync'
- 4Search 'Google Sheets' in the connector search
- 5Choose 'When a row is added, modified or deleted'
Sheets Trigger > Connection Settings
Configure Google Sheets connection
Sign in to your Google account when prompted. Select your contact spreadsheet from the dropdown and choose the specific worksheet tab. Set 'Change type' to 'Updated' to catch contact edits. Power Automate will create a webhook that Google notifies when rows change.
- 1Click 'Sign in' and authenticate your Google account
- 2Select your contact spreadsheet from the File dropdown
- 3Choose the worksheet tab containing contacts
- 4Set Change type to 'Updated'
- 5Leave Key Column as default (Row number)
New step > Control > Condition
Add condition to filter contact rows
Click 'New step' and search for 'Condition' under Control. This prevents the flow from processing header rows or empty cells. Set the condition to check if the Email column is not empty, since contacts need email addresses in Salesforce.
- 1Click '+ New step' below the Sheets trigger
- 2Search 'Condition' and select it from Control
- 3Click the left value field and select 'Email' from dynamic content
- 4Set operator to 'is not equal to'
- 5Leave right value empty to check for non-empty emails
Yes branch > New step > Salesforce > Get records
Check if contact exists in Salesforce
In the 'Yes' branch, add 'Get records' from Salesforce connector. This searches for existing contacts by email to avoid duplicates. Set Object Type to 'Contact' and Filter Query to 'Email = [Email from Sheets]'. Power Automate will authenticate to Salesforce using OAuth.
- 1Click 'Add an action' in the Yes branch
- 2Search 'Salesforce' and select 'Get records'
- 3Sign in to Salesforce when prompted
- 4Set Object Type to 'Contact'
- 5Set Filter Query to Email eq 'EMAIL_DYNAMIC_CONTENT'
Yes branch > New step > Condition
Add condition for update vs create
Add another Condition after the Salesforce query. Check if the 'Get records' step returned any results using the 'value' array length. If length is greater than 0, update the existing contact. If 0, create a new contact record.
- 1Add Condition after Get records step
- 2Click left value and go to Expression tab
- 3Type: length(outputs('Get_records')?['body/value'])
- 4Set operator to 'is greater than'
- 5Set right value to 0
Inner Yes > Salesforce > Update record
Configure update contact action
In the inner 'Yes' branch, add 'Update record' from Salesforce. Set Object Type to Contact and Item ID to the ID from the Get records result. Map fields from your Google Sheets columns to Salesforce fields like FirstName, LastName, Email, Phone, Company.
- 1Add action in the inner Yes branch
- 2Select Salesforce 'Update record'
- 3Set Object Type to Contact
- 4Set Item ID from Get records dynamic content
- 5Map Google Sheets columns to Salesforce fields
Inner No > Salesforce > Create record
Configure create contact action
In the 'No' branch, add 'Create record' from Salesforce for new contacts. Set Object Type to Contact and map the same fields as the update step. Include at minimum FirstName, LastName, and Email since these are typically required in most Salesforce orgs.
- 1Add action in the inner No branch
- 2Select Salesforce 'Create record'
- 3Set Object Type to Contact
- 4Map FirstName from Sheets to FirstName
- 5Map other required fields like LastName and Email
My flows > New flow > Automated cloud flow
Create reverse flow for Salesforce to Sheets
Create a second automated flow named 'Salesforce to Sheets Contact Sync'. Use the Salesforce trigger 'When a record is created or modified' with Object Type set to Contact. This catches changes made directly in Salesforce that need to sync back to Sheets.
- 1Create new Automated cloud flow
- 2Name it 'Salesforce to Sheets Contact Sync'
- 3Search Salesforce connectors
- 4Select 'When a record is created or modified'
- 5Set Object Type to Contact
Salesforce trigger > Google Sheets > Get rows
Find matching row in Google Sheets
Add 'Get rows' from Google Sheets connector to find the matching contact by email. Use Filter Query with the email from the Salesforce trigger. This identifies which row needs updating in your spreadsheet.
- 1Add Google Sheets 'Get rows' action
- 2Select same spreadsheet and worksheet
- 3Set Filter Query to Email eq 'EMAIL_FROM_SALESFORCE'
- 4Leave other settings default
Condition > Yes/No branches > Sheets actions
Update or insert row in Sheets
Add a Condition to check if the Get rows found a match. If yes, use 'Update row' with the Row number from results. If no match, use 'Add row' to append the new contact. Map Salesforce fields back to your Sheets columns in the appropriate action.
- 1Add Condition checking length of Get rows results
- 2In Yes branch: add 'Update row' with Row number from results
- 3In No branch: add 'Add row' to append new contact
- 4Map Salesforce fields to Sheets columns in both actions
Flow details > Save > Test
Test and enable both flows
Save both flows and test with a sample contact edit in each system. Monitor the run history for errors and check that changes sync correctly without creating duplicates or loops. Enable both flows only after successful testing.
- 1Click Save on both flows
- 2Test by editing a contact in Sheets first
- 3Verify change appears in Salesforce
- 4Test editing same contact in Salesforce
- 5Check both run histories for success
Add this expression in a Compose action to prevent sync loops by checking if the last modification came from Power Automate. Paste this in the Expression editor when configuring your condition logic.
JavaScript — Code Stepif(▸ Show code
if(
equals(
outputs('Get_records')?['body/value']?[0]?['Description'],... expand to see full code
if(
equals(
outputs('Get_records')?['body/value']?[0]?['Description'],
'Updated by PowerAutomate'
),
'skip',
concat(
outputs('Get_records')?['body/value']?[0]?['FirstName'],
' ',
outputs('Get_records')?['body/value']?[0]?['LastName']
)
)Going live
Production Checklist
Before you turn this on for real, confirm each item.
Troubleshooting
Common errors and how to fix them.
Frequently Asked Questions
Common questions about this workflow.
Analysis
Use Power Automate for this if you're already in the Microsoft ecosystem and need simple bidirectional sync without complex transformations. The Salesforce connector is solid and the Google Sheets integration handles webhooks properly. Skip this platform if you need sub-minute sync in both directions - Salesforce polling has a 5-minute minimum that kills true real-time sync.
Costs add up fast. Each contact edit burns 2 runs (check + update), so 500 contact changes monthly hits 1,000 runs. Power Automate Premium costs $15/month for 5,000 runs. Compare that to Make at $9/month for 10,000 operations - Make wins on pure cost.
Make handles the same workflow with better error handling and faster Salesforce sync using webhooks instead of polling. Zapier offers cleaner field mapping UI and built-in deduplication. n8n gives you custom JavaScript for complex contact matching logic that Power Automate's expressions can't handle. Pipedream provides better debugging with full request/response logs when things break. But Power Automate wins if you already have Office 365 licenses and want everything in one Microsoft stack.
You'll hit the Salesforce API governor limits with heavy sync volume - 24 hour limits reset at midnight PST, not rolling windows. Required field errors are cryptic and don't tell you which field failed. The Google Sheets trigger fires multiple times for single row edits, burning extra runs and potentially creating duplicates if you don't add deduplication logic.
Ideas for what to build next
- →Add Account sync — Extend the workflow to sync company records between Sheets and Salesforce Account objects for complete data alignment.
- →Build error dashboard — Create a Power BI dashboard tracking sync failures, duplicate prevention hits, and daily sync volume metrics.
- →Add field validation — Implement data quality checks like email format validation and phone number formatting before syncing to either system.
Related guides
How to Share Notion Meeting Notes to Slack with Pipedream
~15 min setup
How to Share Notion Meeting Notes to Slack with Power Automate
~15 min setup
How to Share Notion Meeting Notes to Slack with n8n
~20 min setup
How to Send Notion Meeting Notes to Slack with Zapier
~8 min setup
How to Share Notion Meeting Notes to Slack with Make
~12 min setup
How to Create Notion Tasks from Slack with Pipedream
~15 min setup