google-docs

Google Docs API integration with managed OAuth via Maton. Create documents, read full text, write/append content, search and replace, apply paragraph styles and text formatting (bold/heading), and export to PDF or DOCX. Use this skill when users want to read from or write to Google Docs.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "google-docs" with this command: npx skills add local/google-docs-operator

Google Docs

Access the Google Docs API with managed OAuth authentication. Create documents, read and write content, apply formatting, search & replace, and export files.

Quick Start

# Read a document
python << 'EOF'
import urllib.request, os, json
doc_id = "YOUR_DOCUMENT_ID"
req = urllib.request.Request(f'https://gateway.maton.ai/google-docs/v1/documents/{doc_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
doc = json.load(urllib.request.urlopen(req))
# Extract plain text
text = ''.join(
    pe.get('textRun', {}).get('content', '')
    for elem in doc.get('body', {}).get('content', [])
    for pe in elem.get('paragraph', {}).get('elements', [])
)
print(json.dumps({'title': doc['title'], 'content': text}, ensure_ascii=False, indent=2))
EOF

Base URL

https://gateway.maton.ai/google-docs/{native-api-path}

The gateway proxies requests to docs.googleapis.com and automatically injects your OAuth token.

Authentication

All requests require the Maton API key in the Authorization header:

Authorization: Bearer $MATON_API_KEY

Environment Variable:

export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your Google OAuth connections at https://ctrl.maton.ai.

List Connections

python << 'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=google-docs&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Create Connection

python << 'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'google-docs'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
result = json.load(urllib.request.urlopen(req))
print(json.dumps(result, indent=2))
print('\n👉 Open this URL in a browser to authorize:', result['connection']['url'])
EOF

API Reference

Get Document

GET /google-docs/v1/documents/{documentId}

Returns the full document structure. Extract plain text:

import os, json, urllib.request

def get_doc_text(doc_id):
    req = urllib.request.Request(
        f'https://gateway.maton.ai/google-docs/v1/documents/{doc_id}')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    doc = json.load(urllib.request.urlopen(req))
    text = ''.join(
        pe.get('textRun', {}).get('content', '')
        for elem in doc.get('body', {}).get('content', [])
        for pe in elem.get('paragraph', {}).get('elements', [])
    )
    return {'title': doc['title'], 'content': text, 'documentId': doc['documentId']}

Create Document

POST /google-docs/v1/documents
Content-Type: application/json

{"title": "My New Document"}
import os, json, urllib.request

data = json.dumps({'title': 'My New Document'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/google-docs/v1/documents',
                             data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
doc = json.load(urllib.request.urlopen(req))
print(f"Created: https://docs.google.com/document/d/{doc['documentId']}/edit")

Batch Update (write, format, replace)

All content modifications use batchUpdate:

POST /google-docs/v1/documents/{documentId}:batchUpdate
Content-Type: application/json

{"requests": [...]}

Common batchUpdate Requests

Insert Text (append to end)

import os, json, urllib.request

def append_text(doc_id, text):
    # First, get the document end index
    req = urllib.request.Request(
        f'https://gateway.maton.ai/google-docs/v1/documents/{doc_id}')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    doc = json.load(urllib.request.urlopen(req))
    content = doc.get('body', {}).get('content', [])
    end_index = content[-1].get('endIndex', 1) - 1 if content else 1

    # Insert text at end
    body = json.dumps({'requests': [{'insertText': {
        'location': {'index': end_index},
        'text': text
    }}]}).encode()
    req2 = urllib.request.Request(
        f'https://gateway.maton.ai/google-docs/v1/documents/{doc_id}:batchUpdate',
        data=body, method='POST')
    req2.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    req2.add_header('Content-Type', 'application/json')
    urllib.request.urlopen(req2)
    print(f'Appended {len(text)} chars')

Search & Replace All

{
  "requests": [{
    "replaceAllText": {
      "containsText": {"text": "old text", "matchCase": true},
      "replaceText": "new text"
    }
  }]
}
import os, json, urllib.request

def replace_all(doc_id, find, replace):
    body = json.dumps({'requests': [{'replaceAllText': {
        'containsText': {'text': find, 'matchCase': True},
        'replaceText': replace
    }}]}).encode()
    req = urllib.request.Request(
        f'https://gateway.maton.ai/google-docs/v1/documents/{doc_id}:batchUpdate',
        data=body, method='POST')
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    req.add_header('Content-Type', 'application/json')
    result = json.load(urllib.request.urlopen(req))
    n = result['replies'][0].get('replaceAllText', {}).get('occurrencesChanged', 0)
    print(f'Replaced {n} occurrences')

Apply Paragraph Style (Heading)

Named styles: NORMAL_TEXT | HEADING_1 ~ HEADING_6 | TITLE | SUBTITLE

{
  "requests": [{
    "updateParagraphStyle": {
      "range": {"startIndex": 1, "endIndex": 20},
      "paragraphStyle": {"namedStyleType": "HEADING_1"},
      "fields": "namedStyleType"
    }
  }]
}

Apply Text Formatting (Bold / Italic)

{
  "requests": [{
    "updateTextStyle": {
      "range": {"startIndex": 5, "endIndex": 15},
      "textStyle": {"bold": true, "italic": false},
      "fields": "bold,italic"
    }
  }]
}

Delete Content Range

{
  "requests": [{
    "deleteContentRange": {
      "range": {"startIndex": 1, "endIndex": 100}
    }
  }]
}

Insert Page Break

{
  "requests": [{
    "insertPageBreak": {
      "location": {"index": 50}
    }
  }]
}

Export to PDF / DOCX (via Google Drive API)

Exports go through the Google Drive API (also proxied by Maton):

import os, urllib.request, urllib.parse

def export_doc(doc_id, mime_type, output_path):
    # mime_type examples:
    #   'application/pdf'
    #   'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    #   'text/plain'
    url = (f'https://gateway.maton.ai/google-drive/drive/v3/files/{doc_id}/export'
           f'?mimeType={urllib.parse.quote(mime_type)}')
    req = urllib.request.Request(url)
    req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
    with urllib.request.urlopen(req) as resp:
        with open(output_path, 'wb') as f:
            f.write(resp.read())
    print(f'Exported to {output_path}')

# Export as PDF
export_doc('YOUR_DOC_ID', 'application/pdf', '/tmp/document.pdf')

# Export as Word
export_doc('YOUR_DOC_ID',
           'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
           '/tmp/document.docx')

CLI Convenience Tool

A Python CLI wrapper is included for quick operations:

# Setup
pip install requests

# Set API key
export MATON_API_KEY="your_key"

# Manage connections
python3 gdocs_driver.py connections list
python3 gdocs_driver.py connections create   # Opens auth URL

# Create a document
python3 gdocs_driver.py create --title "My Document"

# Read document content
python3 gdocs_driver.py get --id DOCUMENT_ID_OR_URL

# Append text
python3 gdocs_driver.py append --id DOCUMENT_ID --content "New content here"

# Overwrite entire document
python3 gdocs_driver.py write --id DOCUMENT_ID --content "Fresh content"

# Search and replace
python3 gdocs_driver.py replace --id DOCUMENT_ID --find "old" --replace "new"

# Apply heading style
python3 gdocs_driver.py heading --id DOCUMENT_ID --text "Introduction" --level 1

# Bold specific text
python3 gdocs_driver.py bold --id DOCUMENT_ID --text "important phrase"

# Export to PDF
python3 gdocs_driver.py export --id DOCUMENT_ID --format pdf --output /tmp/doc.pdf

Specifying a Connection

If you have multiple Google accounts connected, specify which one:

python << 'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/google-docs/v1/documents/DOC_ID')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', 'YOUR_CONNECTION_ID')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Document ID

Extract the document ID from a Google Docs URL:

https://docs.google.com/document/d/{DOCUMENT_ID}/edit

The {DOCUMENT_ID} is the string between /d/ and /edit.

Notes

  • batchUpdate requests are processed atomically — all succeed or all fail
  • Index positions in the document are character-based (0-indexed); the document body starts at index 1
  • For replaceAllText, the response includes occurrencesChanged — check this to confirm success
  • Export via Google Drive API requires the same OAuth scope; use google-drive in the Maton gateway path
  • IMPORTANT: When piping curl output, environment variables like $MATON_API_KEY may not expand correctly in some shells. Use Python snippets instead.

Error Handling

StatusMeaning
400Missing Google Docs connection or malformed request
401Invalid or missing Maton API key
403Insufficient permissions on the document
429Rate limited (10 req/sec per account)
4xx/5xxPassthrough error from Google Docs API

Resources

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Wechat Mp Writer

WeChat Official Account (公众号) content writer with article formatting, headline optimization, and engagement tips. Use when you need to write WeChat articles,...

Registry SourceRecently Updated
General

OpenClaw EverMemory Installer

Use this skill when installing, upgrading, verifying, or publishing the EverMemory OpenClaw plugin and its companion skill, including local path install, npm...

Registry SourceRecently Updated
General

Ip Advisor

知识产权顾问。专利、版权、商业秘密、注册流程、保护策略。IP advisor for patents, copyrights, trade secrets. 知识产权、专利、版权。

Registry SourceRecently Updated
1950ckchzh
General

炒股大师模拟器

炒股大师模拟器 | 股市模拟交易练习 | A股/港股/美股投资学习 | 化身文主任/股神老徐/炒股养家/孙宇晨等各位大师学习投资思路 | 多智能体股票讨论群

Registry SourceRecently Updated