Skip to content

steipete/gogcli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧭 gogcli — Google in your terminal.

Google in your terminal — CLI for Gmail, Calendar, Drive, Docs, Slides, Sheets, Contacts, Tasks, People, Groups (Workspace), and Keep (Workspace-only).

Features

  • Gmail - search threads, send emails, manage labels, drafts, filters, delegation, vacation settings, and watch (Pub/Sub push)
  • Email tracking - track opens for gog gmail send --track with a small Cloudflare Worker backend
  • Calendar - list/create/update events, detect conflicts, manage invitations, check free/busy status, team calendars
  • Drive - list/search/upload/download files, manage permissions, organize folders
  • Contacts - search/create/update contacts, access Workspace directory
  • Tasks - manage tasklists and tasks: create/add/update/done/undo/delete/clear
  • Sheets - read/write/update spreadsheets, create new sheets (and export via Drive)
  • Docs/Slides - export to PDF/DOCX/PPTX via Drive (plus create/copy, docs-to-text)
  • People - access profile information
  • Keep (Workspace only) - list/get/search notes and download attachments (service account + domain-wide delegation)
  • Groups - list groups you belong to, view group members (Google Workspace)
  • Multiple accounts - manage multiple Google accounts simultaneously
  • Secure credential storage using OS keyring or encrypted on-disk keyring (configurable)
  • Auto-refreshing tokens - authenticate once, use indefinitely
  • Least-privilege auth - --readonly and --drive-scope to request fewer scopes
  • Workspace service accounts - domain-wide delegation auth (preferred when configured)
  • Parseable output - JSON mode for scripting and automation

Installation

Homebrew

brew install steipete/tap/gogcli

Build from Source

git clone https://github.com/steipete/gogcli.git
cd gogcli
make

Run:

./bin/gog --help

Help:

  • gog --help shows top-level command groups.
  • Drill down with gog <group> --help (and deeper subcommands).
  • For the full expanded command list: GOG_HELP=full gog --help.
  • Make shortcut: make gog -- --help (or make gog -- gmail --help).
  • make gog-help shows CLI help (note: make gog --help is Make’s own help; use --).

Quick Start

1. Get OAuth2 Credentials

Before adding an account, create OAuth2 credentials from Google Cloud Console:

  1. Open the Google Cloud Console credentials page: https://console.cloud.google.com/apis/credentials
  2. Create a project: https://console.cloud.google.com/projectcreate
  3. Enable the APIs you need:
  4. Configure OAuth consent screen: https://console.cloud.google.com/auth/branding
  5. If your app is in "Testing", add test users: https://console.cloud.google.com/auth/audience
  6. Create OAuth client:

2. Store Credentials

gog auth credentials ~/Downloads/client_secret_....json

3. Authorize Your Account

gog auth add you@gmail.com

This will open a browser window for OAuth authorization. The refresh token is stored securely in your system keychain.

4. Test Authentication

export GOG_ACCOUNT=you@gmail.com
gog gmail labels list

Authentication & Secrets

Accounts and tokens

gog stores your OAuth refresh tokens in a “keyring” backend. Default is auto (best available backend for your OS/environment).

Before you can run gog auth add, you must store OAuth client credentials once via gog auth credentials <credentials.json> (download a Desktop app OAuth client JSON from the Cloud Console).

List accounts:

gog auth list

Verify tokens are usable (helps spot revoked/expired tokens):

gog auth list --check

Accounts can be authorized either via OAuth refresh tokens or Workspace service accounts (domain-wide delegation). If a service account key is configured for an account, it takes precedence over OAuth refresh tokens (see gog auth list).

Show current auth state/services for the active account:

gog auth status

Keyring backend: Keychain vs encrypted file

Backends:

  • auto (default): picks the best backend for the platform.
  • keychain: macOS Keychain (recommended on macOS; avoids password management).
  • file: encrypted on-disk keyring (requires a password).

Set backend via command (writes keyring_backend into config.json):

gog auth keyring file
gog auth keyring keychain
gog auth keyring auto

Show current backend + source (env/config/default) and config path:

gog auth keyring

Non-interactive runs (CI/ssh): file backend requires GOG_KEYRING_PASSWORD.

export GOG_KEYRING_PASSWORD='...'
gog --no-input auth status

Force backend via env (overrides config):

export GOG_KEYRING_BACKEND=file

Precedence: GOG_KEYRING_BACKEND env var overrides config.json.

Configuration

Account Selection

Specify the account using either a flag or environment variable:

# Via flag
gog gmail search 'newer_than:7d' --account you@gmail.com

# Via environment
export GOG_ACCOUNT=you@gmail.com
gog gmail search 'newer_than:7d'

List configured accounts:

gog auth list

Output

  • Default: human-friendly tables on stdout.
  • --plain: stable TSV on stdout (tabs preserved; best for piping to tools that expect \t).
  • --json: JSON on stdout (best for scripting).
  • Human-facing hints/progress go to stderr.
  • Colors are enabled only in rich TTY output and are disabled automatically for --json and --plain.

Service Scopes

By default, gog auth add requests access to the user services (see gog auth services for the current list and scopes).

To request fewer scopes:

gog auth add you@gmail.com --services drive,calendar

To request read-only scopes (write operations will fail with 403 insufficient scopes):

gog auth add you@gmail.com --services drive,calendar --readonly

To control Drive’s scope (default: full):

gog auth add you@gmail.com --services drive --drive-scope full
gog auth add you@gmail.com --services drive --drive-scope readonly
gog auth add you@gmail.com --services drive --drive-scope file

Notes:

  • --drive-scope readonly is enough for listing/downloading/exporting via Drive (write operations will 403).
  • --drive-scope file is write-capable (limited to files created/opened by this app) and can’t be combined with --readonly.

If you need to add services later and Google doesn't return a refresh token, re-run with --force-consent:

gog auth add you@gmail.com --services user --force-consent
# Or add just Sheets
gog auth add you@gmail.com --services sheets --force-consent

--services all is accepted as an alias for user for backwards compatibility.

Docs commands are implemented via the Drive API, and docs requests both Drive and Docs API scopes.

Service scope matrix (auto-generated; run go run scripts/gen-auth-services-md.go):

Service User APIs Scopes Notes
gmail yes Gmail API https://mail.google.com/
https://www.googleapis.com/auth/gmail.settings.basic
calendar yes Calendar API https://www.googleapis.com/auth/calendar
drive yes Drive API https://www.googleapis.com/auth/drive
docs yes Docs API, Drive API https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/documents
Export/copy/create via Drive
contacts yes People API https://www.googleapis.com/auth/contacts
https://www.googleapis.com/auth/contacts.other.readonly
https://www.googleapis.com/auth/directory.readonly
Contacts + other contacts + directory
tasks yes Tasks API https://www.googleapis.com/auth/tasks
sheets yes Sheets API, Drive API https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/spreadsheets
Export via Drive
people yes People API profile OIDC profile scope
groups no Cloud Identity API https://www.googleapis.com/auth/cloud-identity.groups.readonly Workspace only
keep no Keep API https://www.googleapis.com/auth/keep.readonly Workspace only; service account (domain-wide delegation)

Service Accounts (Workspace only)

A service account is a non-human Google identity that belongs to a Google Cloud project. In Google Workspace, a service account can impersonate a user via domain-wide delegation (admin-controlled) and access APIs like Gmail/Calendar/Drive as that user.

In gog, service accounts are an optional auth method that can be configured per account email. If a service account key is configured for an account, it takes precedence over OAuth refresh tokens (see gog auth list).

1) Create a Service Account (Google Cloud)

  1. Create (or pick) a Google Cloud project.
  2. Enable the APIs you’ll use (e.g. Gmail, Calendar, Drive, Sheets, Docs, People, Tasks, Cloud Identity).
  3. Go to IAM & Admin → Service Accounts and create a service account.
  4. In the service account details, enable Domain-wide delegation.
  5. Create a key (Keys → Add key → Create new key → JSON) and download the JSON key file.

2) Allowlist scopes (Google Workspace Admin Console)

Domain-wide delegation is enforced by Workspace admin settings.

  1. Open Admin console → Security → API controls → Domain-wide delegation.
  2. Add a new API client:
    • Client ID: use the service account’s “Client ID” from Google Cloud.
    • OAuth scopes: comma-separated list of scopes you want to allow (copy from gog auth services and/or your gog auth add --services ... usage).

If a scope is missing from the allowlist, service-account token minting can fail (or API calls will 403 with insufficient permissions).

3) Configure gog to use the service account

Store the key for the user you want to impersonate:

gog auth service-account set you@yourdomain.com --key ~/Downloads/service-account.json

Verify gog is preferring the service account for that account:

gog --account you@yourdomain.com auth status
gog auth list

Google Keep (Workspace only)

Keep requires Workspace + domain-wide delegation. You can configure it via the generic service-account command above (recommended), or the legacy Keep helper:

gog auth service-account set you@yourdomain.com --key ~/Downloads/service-account.json
gog keep list --account you@yourdomain.com
gog keep get <noteId> --account you@yourdomain.com

Environment Variables

  • GOG_ACCOUNT - Default account email to use (avoids repeating --account; otherwise uses keyring default or a single stored token)
  • GOG_JSON - Default JSON output
  • GOG_PLAIN - Default plain output
  • GOG_COLOR - Color mode: auto (default), always, or never

Config File (JSON5)

Find the actual config path in gog --help or gog auth keyring.

Typical paths:

  • macOS: ~/Library/Application Support/gogcli/config.json
  • Linux: ~/.config/gogcli/config.json (or $XDG_CONFIG_HOME/gogcli/config.json)
  • Windows: %AppData%\\gogcli\\config.json

Example (JSON5 supports comments and trailing commas):

{
  // Avoid macOS Keychain prompts
  keyring_backend: "file",
}

Security

Credential Storage

OAuth credentials are stored securely in your system's keychain:

  • macOS: Keychain Access
  • Linux: Secret Service (GNOME Keyring, KWallet)
  • Windows: Credential Manager

The CLI uses github.com/99designs/keyring for secure storage.

If no OS keychain backend is available (e.g., Linux/WSL/container), keyring can fall back to an encrypted on-disk store and may prompt for a password; for non-interactive runs set GOG_KEYRING_PASSWORD.

Keychain Prompts (macOS)

macOS Keychain may prompt more than you’d expect when the “app identity” keeps changing (different binary path, go run temp builds, rebuilding to new ./bin/gog, multiple copies). Keychain treats those as different apps, so it asks again.

Options:

  • Default (recommended): keep using Keychain (secure) and run a stable gog binary path to reduce repeat prompts.
  • Force Keychain: GOG_KEYRING_BACKEND=keychain (disables any file-backend fallback).
  • Avoid Keychain prompts entirely: GOG_KEYRING_BACKEND=file (stores encrypted entries on disk under your config dir).
    • To avoid password prompts too (CI/non-interactive): set GOG_KEYRING_PASSWORD=... (tradeoff: secret in env).

Best Practices

  • Never commit OAuth client credentials to version control
  • Store client credentials outside your project directory
  • Use different OAuth clients for development and production
  • Re-authorize with --force-consent if you suspect token compromise
  • Remove unused accounts with gog auth remove <email>

Commands

Flag aliases:

  • --out also accepts --output.
  • --out-dir also accepts --output-dir (Gmail thread attachment downloads).

Authentication

gog auth credentials <path>           # Store OAuth client credentials
gog auth add <email>                  # Authorize and store refresh token
gog auth service-account set <email> --key <path>  # Configure service account impersonation (Workspace only)
gog auth service-account status <email>            # Show service account status
gog auth service-account unset <email>             # Remove service account
gog auth keep <email> --key <path>                 # Legacy alias (Keep)
gog auth keyring [backend]            # Show/set keyring backend (auto|keychain|file)
gog auth status                       # Show current auth state/services
gog auth services                     # List available services and OAuth scopes
gog auth list                         # List stored accounts
gog auth list --check                 # Validate stored refresh tokens
gog auth remove <email>               # Remove a stored refresh token
gog auth manage                       # Open accounts manager in browser
gog auth tokens                       # Manage stored refresh tokens

Keep (Workspace only)

gog keep list --account you@yourdomain.com
gog keep get <noteId> --account you@yourdomain.com
gog keep search <query> --account you@yourdomain.com
gog keep attachment <attachmentName> --account you@yourdomain.com --out ./attachment.bin

Gmail

# Search and read
gog gmail search 'newer_than:7d' --max 10
gog gmail thread get <threadId>
gog gmail thread get <threadId> --download              # Download attachments to current dir
gog gmail thread get <threadId> --download --out-dir ./attachments
gog gmail get <messageId>
gog gmail get <messageId> --format metadata
gog gmail attachment <messageId> <attachmentId>
gog gmail attachment <messageId> <attachmentId> --out ./attachment.bin
gog gmail url <threadId>              # Print Gmail web URL
gog gmail thread modify <threadId> --add STARRED --remove INBOX

# Send and compose
gog gmail send --to a@b.com --subject "Hi" --body "Plain fallback"
gog gmail send --to a@b.com --subject "Hi" --body "Plain fallback" --body-html "<p>Hello</p>"
gog gmail drafts list
gog gmail drafts create --subject "Draft" --body "Body"
gog gmail drafts create --to a@b.com --subject "Draft" --body "Body"
gog gmail drafts update <draftId> --subject "Draft" --body "Body"
gog gmail drafts update <draftId> --to a@b.com --subject "Draft" --body "Body"
gog gmail drafts send <draftId>

# Labels
gog gmail labels list
gog gmail labels get INBOX --json  # Includes message counts
gog gmail labels create "My Label"
gog gmail labels update <labelId> --name "New Name"
gog gmail labels delete <labelId>

# Batch operations
gog gmail batch mark-read --query 'older_than:30d'
gog gmail batch delete --query 'from:spam@example.com'
gog gmail batch label --query 'from:boss@example.com' --add-labels IMPORTANT

# Filters
gog gmail filters list
gog gmail filters create --from 'noreply@example.com' --label 'Notifications'
gog gmail filters delete <filterId>

# Settings
gog gmail autoforward get
gog gmail autoforward enable --email forward@example.com
gog gmail autoforward disable
gog gmail forwarding list
gog gmail forwarding add --email forward@example.com
gog gmail sendas list
gog gmail sendas create --email alias@example.com
gog gmail vacation get
gog gmail vacation enable --subject "Out of office" --message "..."
gog gmail vacation disable

# Delegation (G Suite/Workspace)
gog gmail delegates list
gog gmail delegates add --email delegate@example.com
gog gmail delegates remove --email delegate@example.com

# Watch (Pub/Sub push)
gog gmail watch start --topic projects/<p>/topics/<t> --label INBOX
gog gmail watch serve --bind 127.0.0.1 --token <shared> --hook-url http://127.0.0.1:18789/hooks/agent
gog gmail watch serve --bind 0.0.0.0 --verify-oidc --oidc-email <svc@...> --hook-url <url>
gog gmail history --since <historyId>

Gmail watch (Pub/Sub push):

  • Create Pub/Sub topic + push subscription (OIDC preferred; shared token ok for dev).
  • Full flow + payload details: docs/watch.md.

Email Tracking

Track when recipients open your emails:

# Set up local tracking config (per-account; generates keys; follow printed deploy steps)
gog gmail track setup --worker-url https://gog-email-tracker.<acct>.workers.dev

# Send with tracking
gog gmail send --to recipient@example.com --subject "Hello" --body-html "<p>Hi!</p>" --track

# Check opens
gog gmail track opens <tracking_id>
gog gmail track opens --to recipient@example.com

# View status
gog gmail track status

Docs: docs/email-tracking.md (setup/deploy) + docs/email-tracking-worker.md (internals).

Notes: --track requires exactly 1 recipient (no cc/bcc) and an HTML body (--body-html). Use --track-split to send per-recipient messages with individual tracking ids. The tracking worker stores IP/user-agent + coarse geo by default.

Calendar

# Calendars
gog calendar calendars
gog calendar acl <calendarId>         # List access control rules
gog calendar colors                   # List available event/calendar colors
gog calendar time --timezone America/New_York
gog calendar users                    # List workspace users (use email as calendar ID)

# Events (with timezone-aware time flags)
gog calendar events <calendarId> --today                    # Today's events
gog calendar events <calendarId> --tomorrow                 # Tomorrow's events
gog calendar events <calendarId> --week                     # This week (Mon-Sun by default; use --week-start)
gog calendar events <calendarId> --days 3                   # Next 3 days
gog calendar events <calendarId> --from today --to friday   # Relative dates
gog calendar events <calendarId> --from 2025-01-01T00:00:00Z --to 2025-01-08T00:00:00Z
gog calendar events --all             # Fetch events from all calendars
gog calendar event <calendarId> <eventId>
gog calendar search "meeting" --today
gog calendar search "meeting" --tomorrow
gog calendar search "meeting" --days 365
gog calendar search "meeting" --from 2025-01-01T00:00:00Z --to 2025-01-31T00:00:00Z --max 50

# Search defaults to 30 days ago through 90 days ahead unless you set --from/--to/--today/--week/--days.

# Team calendars (requires Cloud Identity API for Google Workspace)
gog calendar team <group-email> --today           # Show team's events for today
gog calendar team <group-email> --week            # Show team's events for the week (use --week-start)
gog calendar team <group-email> --freebusy        # Show only busy/free blocks (faster)
gog calendar team <group-email> --query "standup" # Filter by event title

# Create and update
gog calendar create <calendarId> \
  --summary "Meeting" \
  --from 2025-01-15T10:00:00Z \
  --to 2025-01-15T11:00:00Z

gog calendar create <calendarId> \
  --summary "Team Sync" \
  --from 2025-01-15T14:00:00Z \
  --to 2025-01-15T15:00:00Z \
  --attendees "alice@example.com,bob@example.com" \
  --location "Zoom"

gog calendar update <calendarId> <eventId> \
  --summary "Updated Meeting" \
  --from 2025-01-15T11:00:00Z \
  --to 2025-01-15T12:00:00Z

# Add attendees without replacing existing attendees/RSVP state
gog calendar update <calendarId> <eventId> \
  --add-attendee "alice@example.com,bob@example.com"

gog calendar delete <calendarId> <eventId>

# Invitations
gog calendar respond <calendarId> <eventId> --status accepted
gog calendar respond <calendarId> <eventId> --status declined
gog calendar respond <calendarId> <eventId> --status tentative

# Availability
gog calendar freebusy --calendars "primary,work@example.com" \
  --from 2025-01-15T00:00:00Z \
  --to 2025-01-16T00:00:00Z

gog calendar conflicts --calendars "primary,work@example.com" \
  --today                             # Today's conflicts

Drive

# List and search
gog drive ls --max 20
gog drive ls --parent <folderId> --max 20
gog drive search "invoice" --max 20
gog drive get <fileId>                # Get file metadata
gog drive url <fileId>                # Print Drive web URL
gog drive copy <fileId> "Copy Name"

# Upload and download
gog drive upload ./path/to/file --parent <folderId>
gog drive download <fileId> --out ./downloaded.bin
gog drive download <fileId> --format pdf --out ./exported.pdf
gog drive download <fileId> --format docx --out ./doc.docx
gog drive download <fileId> --format pptx --out ./slides.pptx

# Organize
gog drive mkdir "New Folder"
gog drive mkdir "New Folder" --parent <parentFolderId>
gog drive rename <fileId> "New Name"
gog drive move <fileId> --parent <destinationFolderId>
gog drive delete <fileId>             # Move to trash

# Permissions
gog drive permissions <fileId>
gog drive share <fileId> --email user@example.com --role reader
gog drive share <fileId> --email user@example.com --role writer
gog drive unshare <fileId> --permission-id <permissionId>

Docs / Slides / Sheets

# Docs
gog docs info <docId>
gog docs cat <docId> --max-bytes 10000
gog docs create "My Doc"
gog docs copy <docId> "My Doc Copy"
gog docs export <docId> --format pdf --out ./doc.pdf

# Slides
gog slides info <presentationId>
gog slides create "My Deck"
gog slides copy <presentationId> "My Deck Copy"
gog slides export <presentationId> --format pdf --out ./deck.pdf

# Sheets
gog sheets copy <spreadsheetId> "My Sheet Copy"
gog sheets export <spreadsheetId> --format pdf --out ./sheet.pdf

Contacts

# Personal contacts
gog contacts list --max 50
gog contacts search "Ada" --max 50
gog contacts get people/<resourceName>
gog contacts get user@example.com     # Get by email

# Other contacts (people you've interacted with)
gog contacts other list --max 50
gog contacts other search "John" --max 50

# Create and update
gog contacts create \
  --given-name "John" \
  --family-name "Doe" \
  --email "john@example.com" \
  --phone "+1234567890"

gog contacts update people/<resourceName> \
  --given-name "Jane" \
  --email "jane@example.com"

gog contacts delete people/<resourceName>

# Workspace directory (requires Google Workspace)
gog contacts directory list --max 50
gog contacts directory search "Jane" --max 50

Tasks

# Task lists
gog tasks lists --max 50
gog tasks lists create <title>

# Tasks in a list
gog tasks list <tasklistId> --max 50
gog tasks add <tasklistId> --title "Task title"
gog tasks update <tasklistId> <taskId> --title "New title"
gog tasks done <tasklistId> <taskId>
gog tasks undo <tasklistId> <taskId>
gog tasks delete <tasklistId> <taskId>
gog tasks clear <tasklistId>

Sheets

# Read
gog sheets metadata <spreadsheetId>
gog sheets get <spreadsheetId> 'Sheet1!A1:B10'

# Export (via Drive)
gog sheets export <spreadsheetId> --format pdf --out ./sheet.pdf
gog sheets export <spreadsheetId> --format xlsx --out ./sheet.xlsx

# Write
gog sheets update <spreadsheetId> 'A1' 'val1|val2,val3|val4'
gog sheets update <spreadsheetId> 'A1' --values-json '[["a","b"],["c","d"]]'
gog sheets update <spreadsheetId> 'Sheet1!A1:C1' 'new|row|data' --copy-validation-from 'Sheet1!A2:C2'
gog sheets append <spreadsheetId> 'Sheet1!A:C' 'new|row|data'
gog sheets append <spreadsheetId> 'Sheet1!A:C' 'new|row|data' --copy-validation-from 'Sheet1!A2:C2'
gog sheets clear <spreadsheetId> 'Sheet1!A1:B10'

# Create
gog sheets create "My New Spreadsheet" --sheets "Sheet1,Sheet2"

People

# Profile
gog people me

Groups (Google Workspace)

# List groups you belong to
gog groups list

# List members of a group
gog groups members engineering@company.com

Note: Groups commands require the Cloud Identity API and the cloud-identity.groups.readonly scope. If you get a permissions error, re-authenticate:

gog auth add your@email.com --services groups --force-consent

Docs

# Export (via Drive)
gog docs export <docId> --format pdf --out ./doc.pdf
gog docs export <docId> --format docx --out ./doc.docx
gog docs export <docId> --format txt --out ./doc.txt

Slides

# Export (via Drive)
gog slides export <presentationId> --format pptx --out ./deck.pptx
gog slides export <presentationId> --format pdf --out ./deck.pdf

Output Formats

Text

Human-readable output with colors (default):

$ gog gmail search 'newer_than:7d' --max 3
THREAD_ID           SUBJECT                           FROM                  DATE
18f1a2b3c4d5e6f7    Meeting notes                     alice@example.com     2025-01-10
17e1d2c3b4a5f6e7    Invoice #12345                    billing@vendor.com    2025-01-09
16d1c2b3a4e5f6d7    Project update                    bob@example.com       2025-01-08

JSON

Machine-readable output for scripting and automation:

$ gog gmail search 'newer_than:7d' --max 3 --json
{
  "threads": [
    {
      "id": "18f1a2b3c4d5e6f7",
      "snippet": "Meeting notes from today...",
      "messages": [...]
    },
    ...
  ]
}

Data goes to stdout, errors and progress to stderr for clean piping:

gog --json drive ls --max 5 | jq '.files[] | select(.mimeType=="application/pdf")'

Useful pattern:

  • gog --json ... | jq .

Examples

Search recent emails and download attachments

# Search for emails from the last week
gog gmail search 'newer_than:7d has:attachment' --max 10

# Get thread details and download attachments
gog gmail thread get <threadId> --download

Modify labels on a thread

# Archive and star a thread
gog gmail thread modify <threadId> --remove INBOX --add STARRED

Create a calendar event with attendees

# Find a free time slot
gog calendar freebusy --calendars "primary" \
  --from 2025-01-15T00:00:00Z \
  --to 2025-01-16T00:00:00Z

# Create the meeting
gog calendar create primary \
  --summary "Team Standup" \
  --from 2025-01-15T10:00:00Z \
  --to 2025-01-15T10:30:00Z \
  --attendees "alice@example.com,bob@example.com"

Find and download files from Drive

# Search for PDFs
gog drive search "invoice filetype:pdf" --max 20 --json | \
  jq -r '.files[] | .id' | \
  while read fileId; do
    gog drive download "$fileId"
  done

Manage multiple accounts

# Check personal Gmail
gog gmail search 'is:unread' --account personal@gmail.com

# Check work Gmail
gog gmail search 'is:unread' --account work@company.com

# Or set default
export GOG_ACCOUNT=work@company.com
gog gmail search 'is:unread'

Update a Google Sheet from a CSV

# Convert CSV to pipe-delimited format and update sheet
cat data.csv | tr ',' '|' | \
  gog sheets update <spreadsheetId> 'Sheet1!A1'

Export Sheets / Docs / Slides

# Sheets
gog sheets export <spreadsheetId> --format pdf

# Docs
gog docs export <docId> --format docx

# Slides
gog slides export <presentationId> --format pptx

Batch process Gmail threads

# Mark all emails from a sender as read
gog gmail batch mark-read --query 'from:noreply@example.com'

# Archive old emails
gog gmail batch archive --query 'older_than:1y'

# Label important emails
gog gmail batch label --query 'from:boss@example.com' --add-labels IMPORTANT

Advanced Features

Verbose Mode

Enable verbose logging for troubleshooting:

gog --verbose gmail search 'newer_than:7d'
# Shows API requests and responses

Global Flags

All commands support these flags:

  • --account <email> - Account to use (overrides GOG_ACCOUNT)
  • --json - Output JSON to stdout (best for scripting)
  • --plain - Output stable, parseable text to stdout (TSV; no colors)
  • --color <mode> - Color mode: auto, always, or never (default: auto)
  • --force - Skip confirmations for destructive commands
  • --no-input - Never prompt; fail instead (useful for CI)
  • --verbose - Enable verbose logging
  • --help - Show help for any command

Shell Completions

Generate shell completions for your preferred shell:

Bash

# macOS (with Homebrew)
gog completion bash > $(brew --prefix)/etc/bash_completion.d/gog

# Linux
gog completion bash > /etc/bash_completion.d/gog

# Or load directly in your current session
source <(gog completion bash)

Zsh

# Generate completion file
gog completion zsh > "${fpath[1]}/_gog"

# Or add to .zshrc for automatic loading
echo 'eval "$(gog completion zsh)"' >> ~/.zshrc

# Enable completions if not already enabled
echo "autoload -U compinit; compinit" >> ~/.zshrc

Fish

gog completion fish > ~/.config/fish/completions/gog.fish

PowerShell

# Load for current session
gog completion powershell | Out-String | Invoke-Expression

# Or add to profile for all sessions
gog completion powershell >> $PROFILE

After installing completions, start a new shell session for changes to take effect.

Development

After cloning, install tools:

make tools

Pinned tools (installed into .tools/):

  • Format: make fmt (goimports + gofumpt)
  • Lint: make lint (golangci-lint)
  • Test: make test

CI runs format checks, tests, and lint on push/PR.

Integration Tests (Live Google APIs)

Opt-in tests that hit real Google APIs using your stored gog credentials/tokens.

# Optional: override which account to use
export GOG_IT_ACCOUNT=you@gmail.com
go test -tags=integration ./...

Tip: if you want to avoid macOS Keychain prompts during these runs, set GOG_KEYRING_BACKEND=file and GOG_KEYRING_PASSWORD=... (uses encrypted on-disk keyring).

Make Shortcut

Build and run:

make gog auth add you@gmail.com

For clean stdout when scripting:

  • Use -- when the first arg is a flag: make gog -- --json gmail search "from:me" | jq .

License

MIT

Links

Credits

This project is inspired by Mario Zechner's original CLIs:

About

Google Suite CLI: Gmail, GCal, GDrive, GContacts.

Topics

Resources

License

Stars

Watchers

Forks

Languages