Skip to content

itsFelixH/google-contacts-scripts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

289 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Google Contacts Scripts

A Google Apps Script that audits your Google Contacts and sends you email reports about data quality, upcoming birthdays, duplicates, and more.

Reports are sent to yourself β€” think of it as a personal contacts health check that runs on autopilot.

Reports

Report What it tells you
πŸŽ‚ Upcoming Birthdays Who has a birthday in the next N days, with age countdown
πŸ” Duplicate Contacts Groups of contacts that look like duplicates (by name, email, or phone)
πŸ“Š Contact Overview Stats dashboard β€” completeness, top cities, birthday distribution
🏷️ Label Overview Label distribution, most/least used labels, and unlabeled contacts
πŸ“‹ Missing Info Contacts missing email, phone, city, or birthday
πŸ”§ Data Quality Missing surnames, invalid phones, shared numbers, empty contacts, formatting issues

Actions

Action What it does
🏷️ Auto-Labeling Assign labels based on rules (email domain, city, name patterns, regex)
✏️ Name Formatter Fix capitalization, trim spaces, swap "Last, First" format
πŸ“± Phone Normalizer Convert local numbers to international format with consistent spacing
πŸ“Έ Instagram β†’ Website Convert @handles in notes to clickable website fields
πŸ’¬ Messenger β†’ Website Convert FB/Messenger usernames in notes to m.me website fields

All actions support dryRun mode β€” preview changes without modifying contacts.

πŸ’‘ Looking for automatic birthday calendar events? Check out birthday-calendar-sync.

Setup

1. Create the Apps Script project

2. Enable required services

In the Apps Script editor, go to Services (+ icon) and enable:

  • People API (v1)
  • Gmail API (v1)

3. Configure

Copy src/config.js.template to src/config.js and adjust the settings.

4. Set up schedules

Run setupSchedules() once from the Apps Script editor. It creates a single daily trigger that runs reports and actions on their configured days.

Re-run setupSchedules() any time you change schedules. It cleanly replaces existing triggers.

5. Authorize

The first run will ask for permissions. The script needs access to:

  • Your contacts (read + write for actions)
  • Gmail (to send yourself reports)
  • Drive (to read the script's own name for the sender field)

Configuration

All options live in src/config.js. The config has three sections:

1. General settings

const generalConfig = {
  useLabel: false,                    // only report on contacts with specific labels
  labelFilter: [],                    // e.g. ['Friends', 'Family']
  excludeLabels: [],                  // always exclude from all reports

  sortContactsBy: 'name',            // 'name' | 'name-desc' | 'labels' | 'city'
  maxContactsPerReport: 0,           // 0 = unlimited
  includeEditLinks: true,            // add "edit" links in emails
  includeWhatsAppLinks: false,       // add WhatsApp links next to phone numbers
  birthdayFormat: 'dd.MM.',          // 'dd.MM.' | 'dd/MM' | 'MM/dd' | 'dd MMM' | 'MMM dd'
};

2. Reports

Each report has its own config block with schedule, email subject, and report-specific settings:

const reports = {
  upcomingBirthdays: {
    schedule: 'weekly',               // 'daily' | 'weekly' | 'monthly' | 'off'
    day: 2,                           // 1–7 for weekly (1=Sun, 2=Mon, ..., 7=Sat)
    emailSubject: 'πŸŽ‚ Upcoming Birthdays',
    aheadDays: 14,                    // days to look ahead (1–365)
    showAge: true,
  },

  duplicates: {
    schedule: 'monthly',
    day: 1,                           // 1–28 for monthly (day of month)
    emailSubject: 'πŸ” Duplicate Contacts',
    matchFields: ['name', 'email', 'phone'],
  },

  contactOverview: {
    schedule: 'monthly',
    day: 1,
    emailSubject: 'πŸ“Š Contact Overview',
  },

  labelOverview: {
    schedule: 'monthly',
    day: 1,
    emailSubject: '🏷️ Label Overview',
  },

  missingInfo: {
    schedule: 'monthly',
    day: 1,
    emailSubject: 'πŸ“‹ Missing Info',
    fields: ['email', 'phone', 'birthday', 'city'],
  },

  dataQuality: {
    schedule: 'monthly',
    day: 1,
    emailSubject: 'πŸ”§ Data Quality',
    phoneRegex: /^[+]?[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/,
  },
};

3. Actions

Each action has schedule, dry run, and action-specific settings in one block:

const actions = {
  autoLabeling: {
    schedule: 'monthly',
    day: 1,
    dryRun: false,                    // true = preview only, no changes
    sendReport: true,                 // send summary email
    emailSubject: '🏷️ Auto-Labeling Summary',
    rules: [
      { field: 'email', contains: '@company.com', label: 'Work' },
      { field: 'city',  equals: 'berlin',         label: 'πŸ“ Berlin' },
      { field: 'name',  matches: '\\(swing\\)',   label: 'Swing' },
    ],
  },

  nameFormatter: {
    schedule: 'monthly',
    day: 5,
    dryRun: false,
    sendReport: true,
    emailSubject: '✏️ Name Formatter Summary',
    swapLastFirst: true,              // "Last, First" β†’ "First Last"
  },

  phoneNormalizer: {
    schedule: 'monthly',
    day: 10,
    dryRun: true,                     // preview first!
    sendReport: true,
    emailSubject: 'πŸ“± Phone Normalizer Summary',
    defaultCountryCode: '+49',
    phoneRegex: /^[+]?[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/,
  },

  instagramToWebsite: {
    schedule: 'monthly',
    day: 15,
    dryRun: false,
    sendReport: true,
    emailSubject: 'πŸ“Έ Instagram β†’ Website Summary',
  },

  messengerToWebsite: {
    schedule: 'monthly',
    day: 15,
    dryRun: false,
    sendReport: true,
    emailSubject: 'πŸ’¬ Messenger β†’ Website Summary',
  },
};

Schedule system

A single daily trigger handles all schedules:

  • 'daily' β€” runs every day
  • 'weekly' β€” runs on the configured day (1=Sunday, 2=Monday, ..., 7=Saturday)
  • 'monthly' β€” runs on the configured day (1–28, day of month)
  • 'off' β€” disabled

Actions are spread across different days to avoid API quota limits.

Auto-labeling rules

Rule conditions: contains, equals, startsWith, endsWith, matches (regex). All case-insensitive. Fields: email, phone, city, name.

Running manually

You can run any report or action from the Apps Script editor:

Reports:

  • sendUpcomingBirthdaysReport() β€” or pass days: sendUpcomingBirthdaysReport(14)
  • sendDuplicateContactsReport()
  • sendContactOverviewReport()
  • sendLabelOverviewReport()
  • sendMissingInfoReport()
  • sendDataQualityReport()
  • sendAllReports() β€” runs all enabled reports

Actions:

  • runAutoLabeling()
  • runNameFormatter()
  • runPhoneNormalizer()
  • runInstagramToWebsite()
  • runMessengerToWebsite()

Utility:

  • setupSchedules() β€” create/update triggers
  • removeSchedules() β€” remove all managed triggers
  • validateConfig() β€” check config for errors
  • testContacts() β€” fetch and log all contact names
  • testLabels() β€” fetch and log all labels
  • getHealthStatus() β€” returns contact/label counts and response time

Local development

This project uses clasp for local development and deployment.

# Install dependencies
pnpm install

# Set up clasp
cp .clasp.json.template .clasp.json
# Edit .clasp.json and add your script ID

# Push to Apps Script
pnpm run deploy   # runs tests first, then pushes

# Run tests locally
pnpm test

Project structure

src/
β”œβ”€β”€ _setup.js          # Schedule management (setupSchedules, removeSchedules)
β”œβ”€β”€ actions.js         # Contact actions (auto-label, name format, phone normalize, social β†’ website)
β”œβ”€β”€ config.js          # Your config (not committed)
β”œβ”€β”€ config.js.template # Config template with all options documented
β”œβ”€β”€ contact.js         # Contact class
β”œβ”€β”€ contact_manager.js # Fetching, filtering, and querying contacts
β”œβ”€β”€ email_manager.js   # Email formatting and sending
β”œβ”€β”€ label_manager.js   # Label fetching and lookup
β”œβ”€β”€ main.js            # Report and action entry points + scheduling
└── utils.js           # Config helpers and contact list processing

License

MIT

About

Google Apps Script that audits your Google Contacts and sends email reports about data quality, birthdays, duplicates, and more

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors