Google Contacts to Dataverse Sync
On a schedule, the flow reads Google Contacts and upserts them into a Dataverse contacts table, deduplicating on email, normalizing names/phones, and flagging conflicts for review. Brings Google Contacts into the Power Platform data layer for apps and reporting.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
This flow brings Google Contacts into the Power Platform data layer. On a daily schedule it reads every contact from the connected Google account, normalizes names and phone numbers, and upserts each one into a dedicated Dataverse Sync Contact table, deduplicating on email. When an incoming Google name differs from the stored Dataverse name, the row is flagged Conflict instead of being silently overwritten, and a summary is posted to Teams for review.
Why it matters: Contact data trapped in Google is invisible to Dataverse apps and reporting. A normalized, deduped sync produces one trusted contact list, and the conflict-flagging step keeps a human in the loop for ambiguous matches.
Status: Built as an unmanaged FlowLibs demo solution. Flow ships Off. Going live requires only authorizing the three connections and setting two environment variable values.
Use Case
Operations and Sales teams that maintain contacts in Google need them available, clean, and deduplicated inside Dataverse for model-driven apps, Power BI reporting, and downstream automation — without manual re-entry, and without blindly overwriting records when names disagree.
Flow Architecture
Recurrence Daily Contact Sync
Recurrence (Day/1)Runs the sync once per day. Google Contacts has no trigger, so a Recurrence + read is used.
Initialize variables
Initialize VariableTeams group id, channel id, conflict-alert header text, and four run counters (created / updated / conflict / skipped).
Get My Google Contacts
Google Contacts — PeopleApiListContactsV4Reads all contacts (People API v4). Returns body/connections[].
Apply to each Google Contact
Foreach (sequential, concurrency 1)Processes each contact deterministically so the counters stay accurate.
Set Normalized Email
ComposeLowercases + trims the primary email — the dedup key.
Set Full Name
ComposeClean display name, falling back to given + family name.
Set Normalized Phone
ComposeStrips spaces, dashes, and parentheses from the primary phone.
Check Contact Has Email
ConditionOnly emailed contacts are upserted; emailless ones increment the skipped counter.
List Matching Dataverse Contacts
Microsoft Dataverse — ListRecords$filter on flowlibs_email (the dedup lookup), $top 1.
Check If Contact Exists
ConditionBranches update vs create.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_TeamsGroupId | String | <your-team-id> | Teams Team (group) ID for the conflict alert. |
| flowlibs_TeamsChannelId | String | <your-channel-id> | Teams channel ID for the conflict alert. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Google Contacts | shared_googlecontacts | PeopleApiListContactsV4 |
| Microsoft Dataverse | shared_commondataserviceforapps | ListRecords CreateRecord UpdateRecord |
| Microsoft Teams | shared_teams | PostMessageToConversation |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Sync cadence
- Change the Recurrence frequency/interval (e.g. every 6 hours) for fresher data.
- Two-way sync
- Add a reverse flow that pushes Dataverse edits back via Google Contacts create (note: the connector is read/create only — no update/delete op).
- Group filter
- Filter body/connections[] to a specific contact group before upserting.
- Conflict resolution
- Replace the Teams alert with an Approval, or auto-resolve by trusting the most recently modified source.
- Enrichment
- Append company/firmographic data before the upsert.
- Idempotent key
- Switch the dedup key from email to flowlibs_googleresource (the stable Google People resourceName) for contacts that change email.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Normalized email (dedup key)
Lowercased, trimmed primary email used as the dedup key.
EXPR.02Full name w/ fallback
Display name with given + family fallback.
EXPR.03Normalized phone
Strips formatting characters from the primary phone.
EXPR.04Existence check
True when a matching Dataverse row exists.
EXPR.05Update record id
Id of the matched row to update.
EXPR.06Name conflict
True when stored and incoming names differ.
Customize & download
Generate a ready-to-import copy of this solution with your environment-variable values baked in — available on Base, Pro, or Team.
Upgrade to customize
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.