Find the people in your contacts who never made it to the CRM

By General Input

Open one console to see who is in your address book but not your CRM, which records disagree, and push only the people you pick.

Integrations

  • Google Contacts
  • HubSpot
  • Apollo

Type

App

Categories

  • Sales
  • Operations

Build me a reconciliation console that shows the gap between my Google Contacts address book and our HubSpot CRM. The people I actually email and store in my phone are often nowhere in the CRM, and the records we do have go stale. I want to open this app, work through the backlog, and choose every write myself. Nothing here should run on a schedule or fire automatically.

Building the comparison: read my address book with Google Contacts List Contacts and List Other Contacts, requesting the emailAddresses, names, phoneNumbers, organizations and memberships person fields so I get company, title and label membership for every person. Other contacts are the people I have emailed but never saved, and they matter most here, though they often carry an email address only. Then match against HubSpot on email address using HubSpot Batch Read Contacts with email as the unique identity property, chunked at 100 records per request, falling back to HubSpot Search Contacts for lookups Batch Read cannot resolve. Cache the assembled comparison so the app opens fast, and give me a refresh control that rebuilds it on demand.

The app opens on a reconciliation view with three tabs. Missing from CRM lists the people from my address book whose email addresses return no match from HubSpot, showing their company and title so I can judge who is worth adding. Stale in CRM compares the records that exist in both systems and flags where the phone number, job title or company differs, pulling the CRM side with HubSpot Get Contact and showing both values side by side so I choose which system is right. Recently added is a log of everything I have pushed through the app, newest first, with what was written, to which system, and when.

Pushing into the CRM: let me select any number of rows across the first two tabs and push them in one action using HubSpot Batch Upsert Contacts matched on the email property, which is what makes bulk push safe against duplicates. Batch Upsert caps at 100 records per request, so chunk larger selections and report per row whether each one was created, updated or failed. Single row fixes should use HubSpot Update Contact for a record that already exists and HubSpot Create Contact for one that does not. Every push appends to the Recently added log.

Pulling the other direction: when the CRM holds the better value, let me write a corrected phone number back into my address book with Google Contacts Update Contact, and support a multi row version with Google Contacts Batch Update Contacts. Google requires the current etag on every update, so re-fetch the person immediately before writing rather than reusing an etag from the cached comparison, and send mutations for the same user sequentially rather than in parallel. If an etag conflict comes back, re-read and retry that row once, then surface it as a failed row rather than silently dropping it.

Every row gets a Research and file button that kicks off a background agent for that person. The agent enriches them with Apollo People Enrichment to fill in employer, job title and any missing contact detail, looks up that employer with HubSpot Search Companies to see whether we already track the account, creates it with HubSpot Create Company if we do not, files the contact against the company with HubSpot Create Association, picks an owner from HubSpot List Owners and assigns it, then writes a short plain language summary of what it found and what it changed back into the app so the row shows the outcome without me opening HubSpot. Show the row as queued, running, then done or failed, and keep the summary readable on the row afterwards.

Scoping and dismissing: personal contacts like family should be easy to exclude. Load my labels with Google Contacts List Contact Groups and let me filter the whole console by label, saving my chosen scope so it persists between visits. Let me also permanently dismiss any individual row, and keep dismissed rows as app owned state so they stay hidden across refreshes of the comparison, with a way to view and undismiss them. Dismissing must never write anything to Google or HubSpot.

A few things to get right. Match on email case insensitively and handle people with several email addresses, treating a match on any one of them as a match. Do not flag a difference as stale when one side is simply empty; that is a fill, not a conflict, and should be labelled differently. Show me counts on each tab so I can see the size of the backlog. This app works an existing backlog in both directions with user selected writes, so do not build any automatic one way mirroring on top of it.

Related prompts

Explore more prompts
Turn Mailjet email clicks into ranked HubSpot follow-upsiMessage campaign console with pre-flight checks and delivery boardA searchable RFP answer library your bid team drafts fromSee which target accounts just started advertising on LinkedInAccount health board that puts product usage next to your CRMLook up a customer's full chat history mid conversationLusha prospecting workbench with credit-safe revealsWhich companies your LinkedIn ads reach, matched to your CRMLead response desk with a running clock on every new leadApprove Lusha enrichment field by field before HubSpot saves it