Gmail / Google Workspace Integration Hub

Google Workspace covers Gmail (send/receive/labels/watch), Drive (upload/share/export), and Calendar (events, scheduling, Meet links) for RERI operations. The KB lives at knowledge-base/google-workspace/ (NOT gmail-google-workspace/). Two auth patterns are in use: user OAuth 2.0 for interactive flows and Service Account with domain-wide delegation for server-to-server agent use. The gmail-intake SA (Option B finding) is scoped to gmail.send + gmail.readonly for inbound lead routing. Read this hub before any email automation, document upload, or calendar scheduling work.

NAMING NOTE — KB directory

The KB directory is knowledge-base/google-workspace/ (NOT gmail-google-workspace/). No gmail-google-workspace/ directory exists. All source paths reference google-workspace/. This hub is named gmail-google-workspace.md for integration-hub disambiguation only.

⚠️ SA scope note: gmail-intake vs aurora-api-admin

Two service accounts are in active use for Google APIs:

SAScopesPurpose
gmail-intakegmail.send, gmail.readonlyInbound lead email routing (Option B finding)
aurora-api-admintexttospeech, speech APIsVoice substrate (Google Cloud TTS+STT, smoke-tested 2026-05-03)

Rule: Do NOT use aurora-api-admin SA for Gmail. Do NOT use gmail-intake SA for voice APIs. Scope isolation is intentional per Option B security posture. SA keys stored in 1Password (op://Aurora/google/sa-key for gmail-intake; op://Aurora/google-cloud-voice/sa-key for aurora-api-admin).

Quick reference

FieldValue
VendorGoogle Workspace / Gmail
URLhttps://workspace.google.com
KB docAPI
Auth methodOAuth 2.0 (user) or Service Account (server)
Auth credentialop://Aurora/google/sa-key (gmail-intake SA)
OAuth client credop://Aurora/google/client-id, op://Aurora/google/client-secret
Cred-proxy portn/a (until NemoClaw B1-B6 ratified)
Webhook port:18801 (Gmail Push handler — webhooks/gmail-push-handler.js, manual systemd)
Webhook handlergmail-push-handler
Webhook dedup tableprocessed_webhook_events (24h TTL)
Tunnel path/webhook/gmail (register in FUNNEL-REGISTRY.md if not present)
Outbound API basehttps://gmail.googleapis.com/gmail/v1/users/me/
Drive basehttps://www.googleapis.com/drive/v3/
Calendar basehttps://www.googleapis.com/calendar/v3/
Rate limitsGmail: 250 quota units/user/100s; Drive: 1000 req/100s/user; Calendar: 500 req/100s/user
Rate-limit action429 / 403 rateLimitExceeded → exp backoff with jitter (max 5 retries); Discord ops alert
CostFree API calls; Google Workspace Business Starter $6/user/month
Gmail daily send limit2,000 messages/day (Workspace)
Backup/recoveryGoogle-owned; Drive content in Google cloud storage; manual export quarterly
Discord alert channelops
Drift cadenceon-API-change
Statusproduction

Components

  • workspace/knowledge-base/google-workspace/API.md — Full API reference: Gmail (send, list, get, labels, watch), Drive (list, upload, download, permissions), Calendar (events, create, free/busy)
  • workspace/knowledge-base/google-workspace/examples/ — Code examples directory
  • workspace/webhooks/gmail-push-handler.js — Inbound Gmail Push (Pub/Sub) handler on port :18801
  • _summary — Primary agent for email intake routing and outbound email composition
  • _summary — Drive uploads for dispo documents and TC reports

How it’s used

  • Gmail send: Aurora composes and sends emails (lead responses, deal notifications) via gmail-intake SA; base64url-encoded RFC 2822 MIME format required
  • Gmail watch: POST /gmail/v1/users/me/watch with Cloud Pub/Sub topic; handler at :18801 receives push notifications for new INBOX messages; watch() must be renewed every 7 days
  • Drive upload: betterfiles agent uploads TC documents (PDFs, inspection reports) to Google Drive; permissions set to reader for sharing with clients
  • Calendar: Atlas or betterfiles agent creates showing events with Google Meet links (conferenceDataVersion=1); sendUpdates=all notifies attendees
  • Agents involved: aurora (email), betterfiles (Drive + Calendar), atlas (Calendar reporting)
  • Failure mode: OAuth refresh token expiry → 401 on all calls; service account key rotation in 1Password → redeploy
  • Failure mode 2: Gmail watch expiry (7 days) → Pub/Sub notifications stop; no inbound emails processed
  • Success criteria: messages.send returns {id, threadId, labelIds}; Drive upload returns webViewLink; Calendar event has hangoutLink

Key API patterns

Gmail send (MIME format)

// Email must be RFC 2822 MIME, base64url encoded
const raw = Buffer.from(mimeString).toString('base64')
  .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
await gmail.users.messages.send({ userId: 'me', requestBody: { raw } });

Gmail watch renewal (every 7 days)

await gmail.users.watch({
  userId: 'me',
  requestBody: {
    topicName: 'projects/PROJECT_ID/topics/PUBSUB_TOPIC',
    labelIds: ['INBOX'],
    labelFilterBehavior: 'INCLUDE'
  }
});

Service Account auth pattern

const auth = new google.auth.GoogleAuth({
  keyFile: '/path/to/service-account.json',  // or via 1Password CLI
  scopes: ['https://www.googleapis.com/auth/gmail.send'],
  clientOptions: { subject: 'intake@reri.co' }  // domain-wide delegation
});

Drive upload with share

const file = await drive.files.create({
  requestBody: { name: 'report.pdf', parents: ['FOLDER_ID'] },
  media: { mimeType: 'application/pdf', body: fs.createReadStream('./report.pdf') },
  fields: 'id, webViewLink'
});
// Then share:
await drive.permissions.create({
  fileId: file.data.id,
  requestBody: { type: 'user', role: 'reader', emailAddress: recipientEmail }
});

Gmail Push handler (port :18801)

The Gmail Push handler receives Pub/Sub notifications when new emails arrive in INBOX. Systemd unit runs manually (not auto-started). FUNNEL-REGISTRY.md must have /webhook/gmail registered. Handler must:

  1. Verify Pub/Sub message authenticity
  2. Write to webhook_audit_log
  3. Dedup via processed_webhook_events
  4. Route to aurora agent for lead classification

Note: Port :18801 listed in CLAUDE.md port map as “Gmail Push | manual” — confirm current systemd unit status before relying on live events.

Agents that touch this

  • _summary — email intake routing, outbound email composition, Gmail label management
  • _summary — Drive uploads (TC documents, dispo PDFs); Calendar event creation for showings
  • _summary — Calendar free/busy checks for scheduling; Drive report generation

Skills that invoke this

Plans that govern this

Feedback rules

KB / source docs

  • API — Gmail, Drive, Calendar API reference (last verified 2026-03-04)

System maps

All credentials stored in 1Password vault Aurora. See 1password for op:// CLI access pattern. Two distinct SA keys:

  • gmail-intake SA: op://Aurora/google/sa-key — Gmail scopes only
  • aurora-api-admin SA: op://Aurora/google-cloud-voice/sa-key — voice APIs only

Do NOT cross-use SAs between Gmail and voice scopes. OAuth refresh tokens for user flows: op://Aurora/google/refresh-token.

Gmail Push uses Cloud Pub/Sub push subscription → HTTP POST to :18801. This is an inbound webhook path. Register in FUNNEL-REGISTRY.md as /webhook/gmail if not already present. Handler must verify Pub/Sub authenticity + write webhook_audit_log. See cloudflare for tunnel governance.

  • slack — secondary comms channel; Gmail vs Slack routing decision is agent-level
  • hubspot — Gmail threads for deal-related emails may be logged to HubSpot Communications object via HubSpot-Gmail integration; bidirectional link for lead emails

Open issues / TODOs

  • Confirm Gmail watch is actively renewing every 7 days (add to cron / Atlas monitoring)
  • Confirm :18801 gmail-push-handler.js systemd unit is actually running — listed as “(manual)” in CLAUDE.md port map
  • Register /webhook/gmail in FUNNEL-REGISTRY.md if not present; verify signature/auth on Pub/Sub messages
  • Confirm gmail-intake SA has domain-wide delegation enabled in Google Admin Console for intake@reri.co
  • aurora-api-admin SA (voice APIs) — EC2 Mac Ultra instance is impaired since 2026-05-02; resume next session per AWS Console reboot before relying on voice TTS/STT
  • Drive: confirm REPORTS_FOLDER_ID env var is set for Atlas report uploads; add to master.env if missing

Recent activity

  • 2026-05-04: hub created (W3-S5, Wave 3) — SA scope note + gmail-intake vs aurora-api-admin distinction documented; TLS watch renewal gap flagged
  • 2026-05-03: aurora-api-admin SA provisioned for voice APIs (texttospeech + speech); smoke-tested successfully
  • 2026-03-04: API.md verified (Gmail, Drive, Calendar — status: COMPLETE)