Skill Details
Back to Skills

/google-workspace

by zaycv

Interact with Google Workspace services - Gmail, Calendar, Contacts, Sheets, and Docs. Send emails, manage calendar events, read/write spreadsheets, create documents, and sync contacts.

View on GitHub

Google Workspace CLI

Setup

1. Install dependencies

pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib

2. Create Google Cloud Project

  1. Go to Google Cloud Console
  2. Create a new project
  3. Enable APIs: Gmail, Calendar, Sheets, Docs, People API
  4. Create OAuth 2.0 credentials (Desktop app)
  5. Download credentials.json to your working directory

3. Authentication helper

Save as google_auth.py:

import os
import pickle
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

SCOPES = [
    'https://www.googleapis.com/auth/gmail.modify',
    'https://www.googleapis.com/auth/calendar',
    'https://www.googleapis.com/auth/contacts',
    'https://www.googleapis.com/auth/spreadsheets',
    'https://www.googleapis.com/auth/documents',
    'https://www.googleapis.com/auth/drive'
]

def get_credentials():
    creds = None
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    return creds

def get_service(api, version):
    return build(api, version, credentials=get_credentials())

First run will open browser for OAuth authorization.


Gmail

List recent emails

python3 -c "
from google_auth import get_service

gmail = get_service('gmail', 'v1')
results = gmail.users().messages().list(userId='me', maxResults=10).execute()
messages = results.get('messages', [])

for msg in messages:
    m = gmail.users().messages().get(userId='me', id=msg['id'], format='metadata').execute()
    headers = {h['name']: h['value'] for h in m['payload']['headers']}
    print(f\"From: {headers.get('From', 'N/A')}\")
    print(f\"Subject: {headers.get('Subject', 'N/A')}\")
    print(f\"Date: {headers.get('Date', 'N/A')}\")
    print('-' * 50)"

Read email by ID

python3 -c "
from google_auth import get_service
import base64

gmail = get_service('gmail', 'v1')
msg = gmail.users().messages().get(userId='me', id='MESSAGE_ID', format='full').execute()

headers = {h['name']: h['value'] for h in msg['payload']['headers']}
print(f\"From: {headers.get('From')}\")
print(f\"Subject: {headers.get('Subject')}\")
print(f\"Date: {headers.get('Date')}\")

if 'data' in msg['payload']['body']:
    body = base64.urlsafe_b64decode(msg['payload']['body']['data']).decode()
    print(f\"\nBody:\n{body}\")"

Send email

python3 -c "
from google_auth import get_service
import base64
from email.mime.text import MIMEText

gmail = get_service('gmail', 'v1')

message = MIMEText('Hello! This is a test email.')
message['to'] = 'recipient@example.com'
message['subject'] = 'Test Email'
raw = base64.urlsafe_b64encode(message.as_bytes()).decode()

result = gmail.users().messages().send(userId='me', body={'raw': raw}).execute()
print(f\"Email sent! ID: {result['id']}\")"

Search emails

python3 -c "
from google_auth import get_service

gmail = get_service('gmail', 'v1')
# Search queries: from:, to:, subject:, after:, before:, has:attachment, is:unread
results = gmail.users().messages().list(userId='me', q='is:unread subject:invoice', maxResults=5).execute()

for msg in results.get('messages', []):
    m = gmail.users().messages().get(userId='me', id=msg['id'], format='metadata').execute()
    headers = {h['name']: h['value'] for h in m['payload']['headers']}
    print(f\"• {headers.get('Subject', 'No subject')}\")"

List labels

python3 -c "
from google_auth import get_service

gmail = get_service('gmail', 'v1')
results = gmail.users().labels().list(userId='me').execute()
for label in results.get('labels', []):
    print(f\"{label['id']}: {label['name']}\")"

Google Calendar

List upcoming events

python3 -c "
from google_auth import get_service
from datetime import datetime, timezone

calendar = get_service('calendar', 'v3')
now = datetime.now(timezone.utc).isoformat()

events = calendar.events().list(
    calendarId='primary',
    timeMin=now,
    maxResults=10,
    singleEvents=True,
    orderBy='startTime'
).execute()

for event in events.get('items', []):
    start = event['start'].get('dateTime', event['start'].get('date'))
    print(f\"{start}: {event['summary']}\")"

Create event

python3 -c "
from google_auth import get_service

calendar = get_service('calendar', 'v3')

event = {
    'summary': 'Meeting with Team',
    'location': 'Conference Room A',
    'description': 'Weekly sync',
    'start': {
        'dateTime': '2025-02-03T10:00:00',
        'timeZone': 'America/New_York',
    },
    'end': {
        'dateTime': '2025-02-03T11:00:00',
        'timeZone': 'America/New_York',
    },
    'attendees': [
        {'email': 'colleague@example.com'},
    ],
    'reminders': {
        'useDefault': False,
        'overrides': [
            {'method': 'email', 'minutes': 24 * 60},
            {'method': 'popup', 'minutes': 10},
        ],
    },
}

result = calendar.events().insert(calendarId='primary', body=event).execute()
print(f\"Event created: {result.get('htmlLink')}\")"

Delete event

python3 -c "
from google_auth import get_service

calendar = get_service('calendar', 'v3')
calendar.events().delete(calendarId='primary', eventId='EVENT_ID').execute()
print('Event deleted')"

List calendars

python3 -c "
from google_auth import get_service

calendar = get_service('calendar', 'v3')
calendars = calendar.calendarList().list().execute()

for cal in calendars.get('items', []):
    print(f\"{cal['id']}: {cal['summary']}\")"

Google Contacts (People API)

List contacts

python3 -c "
from google_auth import get_service

people = get_service('people', 'v1')
results = people.people().connections().list(
    resourceName='people/me',
    pageSize=20,
    personFields='names,emailAddresses,phoneNumbers'
).execute()

for person in results.get('connections', []):
    names = person.get('names', [{}])
    emails = person.get('emailAddresses', [{}])
    phones = person.get('phoneNumbers', [{}])
    print(f\"Name: {names[0].get('displayName', 'N/A')}\")
    print(f\"Email: {emails[0].get('value', 'N/A') if emails else 'N/A'}\")
    print(f\"Phone: {phones[0].get('value', 'N/A') if phones else 'N/A'}\")
    print('-' * 30)"

Create contact

python3 -c "
from google_auth import get_service

people = get_service('people', 'v1')

contact = {
    'names': [{'givenName': 'John', 'familyName': 'Doe'}],
    'emailAddresses': [{'value': 'john.doe@example.com'}],
    'phoneNumbers': [{'value': '+1234567890'}]
}

result = people.people().createContact(body=contact).execute()
print(f\"Contact created: {result['resourceName']}\")"

Search contacts

python3 -c "
from google_auth import get_service

people = get_service('people', 'v1')
results = people.people().searchContacts(
    query='John',
    readMask='names,emailAddresses'
).execute()

for result in results.get('results', []):
    person = result.get('person', {})
    names = person.get('names', [{}])
    print(f\"Found: {names[0].get('displayName', 'N/A')}\")"

Google Sheets

Read spreadsheet

python3 -c "
from google_auth import get_service

sheets = get_service('sheets', 'v4')
SPREADSHEET_ID = 'your-spreadsheet-id'
RANGE = 'Sheet1!A1:D10'

result = sheets.spreadsheets().values().get(
    spreadsheetId=SPREADSHEET_ID,
    range=RANGE
).execute()

for row in result.get('values', []):
    print('\t'.join(row))"

Write to spreadsheet

python3 -c "
from google_auth import get_service

sheets = get_service('sheets', 'v4')
SPREADSHEET_ID = 'your-spreadsheet-id'
RANGE = 'Sheet1!A1'

values = [
    ['Name', 'Email', 'Phone'],
    ['John Doe', 'john@example.com', '+1234567890'],
    ['Jane Smith', 'jane@example.com', '+0987654321']
]

body = {'values': values}
result = sheets.spreadsheets().values().update(
    spreadsheetId=SPREADSHEET_ID,
    range=RANGE,
    valueInputOption='RAW',
    body=body
).execute()

print(f\"Updated {result.get('updatedCells')} cells\")"

Append rows

python3 -c "
from google_auth import get_service

sheets = get_service('sheets', 'v4')
SPREADSHEET_ID = 'your-spreadsheet-id'
RANGE = 'Sheet1!A:D'

values = [['New Entry', 'data1', 'data2', 'data3']]
body = {'values': values}

result = sheets.spreadsheets().values().append(
    spreadsheetId=SPREADSHEET_ID,
    range=RANGE,
    valueInputOption='RAW',
    body=body
).execute()

print(f\"Appended {result.get('updates', {}).get('updatedRows')} row(s)\")"

Create new spreadsheet

python3 -c "
from google_auth import get_service

sheets = get_service('sheets', 'v4')

spreadsheet = {
    'properties': {'title': 'My New Spreadsheet'},
    'sheets': [{'properties': {'title': 'Data'}}]
}

result = sheets.spreadsheets().create(body=spreadsheet).execute()
print(f\"Created: {result['spreadsheetUrl']}\")"

Google Docs

Read document

python3 -c "
from google_auth import get_service

docs = get_service('docs', 'v1')
DOCUMENT_ID = 'your-document-id'

doc = docs.documents().get(documentId=DOCUMENT_ID).execute()
print(f\"Title: {doc.get('title')}\")

content = doc.get('body', {}).get('content', [])
for element in content:
    if 'paragraph' in element:
        for text_run in element['paragraph'].get('elements', []):
            if 'textRun' in text_run:
                print(text_run['textRun']['content'], end='')"

Create document

python3 -c "
from google_auth import get_service

docs = get_service('docs', 'v1')

doc = docs.documents().create(body={'title': 'My New Document'}).execute()
print(f\"Created document: {doc.get('documentId')}\")"

Insert text

python3 -c "
from google_auth import get_service

docs = get_service('docs', 'v1')
DOCUMENT_ID = 'your-document-id'

requests = [
    {
        'insertText': {
            'location': {'index': 1},
            'text': 'Hello, this is inserted text!\n\n'
        }
    }
]

result = docs.documents().batchUpdate(
    documentId=DOCUMENT_ID,
    body={'requests': requests}
).execute()

print('Text inserted')"

Replace text

python3 -c "
from google_auth import get_service

docs = get_service('docs', 'v1')
DOCUMENT_ID = 'your-document-id'

requests = [
    {
        'replaceAllText': {
            'containsText': {'text': '{{PLACEHOLDER}}', 'matchCase': True},
            'replaceText': 'Actual Value'
        }
    }
]

result = docs.documents().batchUpdate(
    documentId=DOCUMENT_ID,
    body={'requests': requests}
).execute()

print(f\"Replaced {result.get('replies', [{}])[0].get('replaceAllText', {}).get('occurrencesChanged', 0)} occurrences\")"

Google Drive (File Operations)

List files

python3 -c "
from google_auth import get_service

drive = get_service('drive', 'v3')
results = drive.files().list(
    pageSize=10,
    fields='files(id, name, mimeType)'
).execute()

for f in results.get('files', []):
    print(f\"{f['name']} ({f['mimeType']})\")"

Upload file

python3 -c "
from google_auth import get_service
from googleapiclient.http import MediaFileUpload

drive = get_service('drive', 'v3')

file_metadata = {'name': 'example.txt'}
media = MediaFileUpload('example.txt', mimetype='text/plain')

file = drive.files().create(
    body=file_metadata,
    media_body=media,
    fields='id'
).execute()

print(f\"Uploaded file ID: {file.get('id')}\")"

Download file

python3 -c "
from google_auth import get_service
import io
from googleapiclient.http import MediaIoBaseDownload

drive = get_service('drive', 'v3')
FILE_ID = 'your-file-id'

request = drive.files().get_media(fileId=FILE_ID)
file = io.BytesIO()
downloader = MediaIoBaseDownload(file, request)

done = False
while not done:
    status, done = downloader.next_chunk()
    print(f\"Download {int(status.progress() * 100)}%\")

with open('downloaded_file', 'wb') as f:
    f.write(file.getvalue())
print('Download complete')"

Common IDs & URLs

Service ID Location
Gmail Message URL: mail.google.com/mail/u/0/#inbox/MESSAGE_ID
Calendar Event From API response event['id']
Spreadsheet URL: docs.google.com/spreadsheets/d/SPREADSHEET_ID/
Document URL: docs.google.com/document/d/DOCUMENT_ID/
Drive File URL: drive.google.com/file/d/FILE_ID/

Notes

  • First run requires browser-based OAuth authorization
  • token.pickle stores credentials for subsequent runs
  • Scopes can be limited based on needed functionality
  • Rate limits apply; implement exponential backoff for production
  • Use service accounts for server-to-server authentication
  • Keep credentials.json secure and never commit to version control