New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@bobfrankston/gcards

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bobfrankston/gcards

Google Contacts cleanup and management tool

latest
Source
npmnpm
Version
0.1.46
Version published
Weekly downloads
12
Maintainers
1
Weekly downloads
 
Created
Source

gcards - Google Contacts Management Tool

A CLI tool for syncing, managing, and cleaning up Google Contacts.

Installation

npm install -g @bobfrankston/gcards

Quick Start

# First time - specify your Gmail username
gcards sync --user yourname

# Subsequent runs remember the user
gcards sync
gcards push

Commands

gcards

Main sync and push operations (Google API):

gcards sync [-u user] [-a]    # Download contacts from Google
gcards push [-u user] [-a]    # Push local changes to Google
gcards -a                     # Process all users

gcard

Single-card operations on the local store (use gcards/gfix for bulk):

gcard label <lastname>           # Print Dymo-style mailing label, copy to clipboard
gcard label smith -u alice       # Specify user
gcard label smith -no-clip       # Don't copy to clipboard

gcard add "Jane Doe, jane@x.com, 617-555-1212"   # AI-extract text into a new contact
gcard add -clip                                  # ...read the info from the clipboard
gcard merge "Jane Doe, cell 617-555-9999"        # Merge info into the existing Jane Doe

Matches contacts whose family name contains <lastname> (case-insensitive). Multiple matches list a numbered menu; pick one.

add converts free-form text (or -clip clipboard) into a contact via AI extraction and creates it live on Google. If a contact with the same name, email, or phone already exists, it asks whether to merge or add anew. merge does the same extraction but merges straight into the existing contact (only prompting to disambiguate when several match), creating one if none match. Both need ANTHROPIC_API_KEY set for extraction (same key as gcards add); add -y to skip prompts.

gfix

One-time cleanup operations (local files only):

gfix inspect -u user          # Preview all standard fixes (no changes)
gfix apply -u user            # Apply all standard fixes

gfix names -u user            # Preview name parsing + dup phone/email removal
gfix names -u user --apply    # Parse names, remove dup phones/emails, move email/phone-only to _delete/
gfix problems -u user         # Process edited problems.txt (x=delete, or replace name)

gfix birthday -u user         # Preview birthday extraction
gfix birthday -u user --apply # Extract to CSV and remove

gfix undup -u user            # Find duplicate contacts -> merger.json
gfix merge -u user            # Merge duplicates locally (then use gcards push)

gfix export -u source -to target "pattern"  # Export contacts to another user

Library API

Other apps can import the package for contact lookup and mailing-label formatting (used by @bobfrankston/dymo-print for its -contact option):

import {
    resolveUser, getAccessToken,       // gcards auth (%APPDATA%\gcards; no extra consent)
    searchPeople, matchByName,         // live People API search + name matching
    buildLabel, pickAddress, formatAddress,   // contact → mailing-label text
    promptChoice, promptNumber,        // interactive candidate pickers (CLI use)
    parseVcf,                          // .vcf text → GooglePerson-shaped contacts
} from "@bobfrankston/gcards";

const user = resolveUser("default");           // last-used gcards profile
const token = await getAccessToken(user);
const people = await searchPeople(token, "smith");
const { matches } = matchByName(people, "smith");
console.log(buildLabel(matches[0].contact));   // "Jane Smith\n123 Main St\n..."

parseVcf returns the same GooglePerson shape, so buildLabel and friends work identically on vCard contacts. The CLIs (gcards/gcard/gfix) are unchanged; the library surface lives in api.ts.

Google People API Fields

Identity (Names)

FieldRead/WriteDescription
names[].givenNameWriteFirst name
names[].familyNameWriteLast name
names[].middleNameWriteMiddle name
names[].honorificPrefixWritePrefix (Dr., Prof., etc.)
names[].honorificSuffixWriteSuffix (Jr., III, PhD, etc.)
names[].displayNameRead-onlyFull name (Google generates from above)
names[].displayNameLastFirstRead-onlySorting form "Last, First" (Google generates)
names[].unstructuredNameWriteFree-form name when structured fields not available

Sorting

FieldRead/WriteDescription
fileAses[].valueWriteCustom sort override (e.g., "Home Depot" instead of "The Home Depot")

If blank, Google sorts by familyName automatically.

Contact Information

FieldRead/WriteDescription
emailAddresses[].valueWriteEmail address
emailAddresses[].typeWriteLabel: home, work, other
phoneNumbers[].valueWritePhone number
phoneNumbers[].typeWriteLabel: mobile, work, home, main

Business

FieldRead/WriteDescription
organizations[].nameWriteCompany name
organizations[].titleWriteJob title

Dates

FieldRead/WriteDescription
birthdays[].date.yearWriteBirth year (optional)
birthdays[].date.monthWriteBirth month (1-12)
birthdays[].date.dayWriteBirth day (1-31)

Management (Required for Updates)

FieldRead/WriteDescription
resourceNameRead-onlyUnique contact ID (e.g., people/c12345)
etagRead-onlyVersion key - must match when updating

The etag prevents conflicts: if Google's version changed since you downloaded, your update will fail. Run gcards sync to get the latest version.

Data Directory

  • Windows: %APPDATA%\gcards\ (app directory)
  • Linux/Mac: ~/.config/gcards/ (app directory)
  • Development: ./data/ symlink to app directory's data/ folder

Directory Structure

gcards/                   # App directory (%APPDATA%\gcards or ~/.config/gcards)
  config.json             # Last user, settings
  data/                   # User data directory
    <username>/
      contacts/           # Active contacts (*.json)
      deleted/            # Backup of deleted contact files
      _delete/            # User requests to delete (move files here)
      _add/               # User requests to add new contacts
      fix-logs/           # Logs from gfix operations
      index.json          # Active contact index (hasPhoto, starred flags)
      deleted.json        # Deleted contacts index
      notdeleted.json     # Contacts skipped due to photo/starred
      token.json          # OAuth token (read-only)
      token-write.json    # OAuth token (read-write)
      changes.log         # Log from gfix names
      birthdays.csv       # Extracted birthdays
      merger.json         # Duplicates to merge (from gfix undup)
      merged.json         # Processed merges (history)

Fixes Applied by gfix inspect/apply

  • Remove leading/trailing dashes, quotes, spaces from name fields
  • Extract repeated honorific prefixes (Dr., Prof.) to honorificPrefix
  • Remove duplicate phone numbers (normalized comparison)
  • Remove duplicate email addresses (case-insensitive)

Name Parsing (gfix names)

When a contact has a full name in givenName but no familyName:

  • Parses "First Middle Last" into separate fields
  • Handles suffixes like Ph.D., M.D., P.E., Jr., III
  • Updates displayNameLastFirst to proper "Last, First" format
  • Cleans up fileAses entries (strips junk characters)
  • Fixes repeated words (e.g., "John Smith Smith Smith" → "John Smith")
  • Creates changes.log with all modifications

Contacts with no real name are moved to _delete/:

  • Email-only (no name field)
  • Phone-only (phone number as name)
  • Empty contacts (no name, email, or phone)

Recovery lists saved to emailonly.json and phoneonly.json.

Handling Problem Contacts (gfix problems)

After gfix names, ambiguous contacts are saved to problems.txt. Edit this file to fix:

  • Add x at start of line to mark for deletion
  • Replace the name with corrected "First Last" format
  • Leave unchanged to skip

Then run gfix problems -u user to apply.

Workflow

  • Initial sync: gcards sync -u yourname
  • Review fixes: gfix inspect -u yourname
  • Apply fixes: gfix apply -u yourname
  • Parse names: gfix names -u yourname --apply
  • Push to Google: gcards push -u yourname

Deleting Contacts

Three ways to mark contacts for deletion:

  • In index.json: Add "_delete": true to an entry
  • In contact JSON: Add "_delete": true to the contact file
  • Move to _delete/: Move the contact file to the _delete/ folder

Then run gcards push to apply deletions.

Photo/Starred Protection

Contacts with photos or starred status are not deleted from Google to prevent data loss:

  • Contacts with non-default photos: _delete set to "photo"
  • Starred/favorite contacts: _delete set to "starred"

These remain in Google and index.json with the skip reason. Review notdeleted.json after push.

Backup

All deleted contact files are moved to deleted/ folder as backup (not permanently deleted). Index entries move to deleted.json.

Duplicate Contact Merging

  • Find duplicates: gfix undup -u yourname
    • Creates merger.json with contacts having same name + overlapping email
  • Review: Edit merger.json:
    • Remove entries you don't want to merge
    • Add "_delete": true to delete all contacts in a group instead of merging
  • Merge locally: gfix merge -u yourname
    • Updates target contact files with merged data
    • Marks source contacts with _delete: true
    • Moves processed entries to merged.json
  • Push to Google: gcards push -u yourname
  • Resync: gcards sync -u yourname --full

Example merger.json:

[
  { "name": "John Smith", "emails": ["john@work.com"], "resourceNames": ["people/c1", "people/c2"] },
  { "name": "Spam Contact", "emails": ["spam@x.com"], "resourceNames": ["people/c3", "people/c4"], "_delete": true }
]

ESC Key

Press ESC during sync/push to stop safely after the current operation.

Multiple Users

# Process specific user
gcards sync -u alice

# Process all users
gcards sync -a
gcards push -a

Exporting Contacts Between Users

Transfer contacts from one user's account to another:

gfix export -u bob -to alice "John*"         # Export contacts matching "John*"
gfix export -u bob -to ali "*@example.com"   # Export by email (partial user match)
gfix export -u bob -to alice c1234567890     # Export specific contact by ID

Features:

  • -u source user (partial match supported)
  • -to target user (partial match - "ali" matches "alice" if unique)
  • Pattern supports * (any chars) and ? (single char) wildcards
  • Matches on: displayName, givenName, familyName, "Last, First", email
  • Searches both contacts/ and deleted/ directories
  • Multiple matches prompt for selection: number(s), * for all, q to quit
  • Creates cleaned file in target's _add/ as x<sourceId>.json

After export, run gcards push -u <target> to upload.

Setup

No setup is required for normal use — Google OAuth client credentials are bundled with the package. On first run, gcards opens a browser so you can grant access to your own Google contacts; the resulting access token is stored locally under your user data directory.

AI Error Explanations (Optional)

When API errors occur, gcards can use AI to explain what went wrong and suggest fixes.

  • Create keys.env in your gcards app directory:

    • Windows: %APPDATA%\gcards\keys.env
    • Linux/Mac: ~/.config/gcards/keys.env
  • Add your API key(s):

    ANTHROPIC_API_KEY=sk-ant-api03-...
    

    or

    OPENAI_API_KEY=sk-...
    

Get API keys:

  • Anthropic: https://console.anthropic.com/settings/keys
  • OpenAI: https://platform.openai.com/api-keys

The tool tries Anthropic first, then falls back to OpenAI if available.

License

MIT

Keywords

google

FAQs

Package last updated on 08 Jul 2026

Related posts