GO

google-docs-skill

Manipulates Google Docs documents via programatic API access.

Install

mkdir -p .claude/skills/google-docs-skill && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/11148" && unzip -o skill.zip -d .claude/skills/google-docs-skill && rm skill.zip

Installs to .claude/skills/google-docs-skill

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Direct access to the Google Docs API using OAuth 2.0. Create documents, insert and format text, and manage document content.
124 chars · catalog descriptionno explicit “when” trigger
Intermediate

Key capabilities

  • Create documents
  • Insert and format text
  • Manage document content
  • Batch update documents

How it works

It interacts with the Google Docs API using OAuth 2.0 tokens to perform programmatic document operations.

Inputs & outputs

You give it
Document content
You get back
Document ID

When to use google-docs-skill

  • Automated document generation
  • Formatting doc content
  • Managing document data

About this skill

Google Docs API Integration

Direct access to the Google Docs API using OAuth 2.0. Create documents, insert and format text, and manage document content.

Prerequisites

  1. Google Cloud Project Setup

    • Go to Google Cloud Console
    • Create a new project or select existing one
    • Enable the Google Docs API
    • Create OAuth 2.0 credentials (Desktop app or Web application)
    • Download the credentials JSON file
  2. Environment Setup

    export GOOGLE_CLIENT_ID="your-client-id"
    export GOOGLE_CLIENT_SECRET="your-client-secret"
    export GOOGLE_REFRESH_TOKEN="your-refresh-token"
    

Authentication

Getting OAuth Tokens

Use the following Python script to obtain your refresh token (one-time setup):

import urllib.request
import urllib.parse
import json
import webbrowser
from http.server import HTTPServer, BaseHTTPRequestHandler
import os

# OAuth configuration
CLIENT_ID = os.environ.get('GOOGLE_CLIENT_ID')
CLIENT_SECRET = os.environ.get('GOOGLE_CLIENT_SECRET')
REDIRECT_URI = 'http://localhost:8080'
SCOPES = 'https://www.googleapis.com/auth/documents'

# Step 1: Get authorization code
auth_url = (
    f"https://accounts.google.com/o/oauth2/v2/auth?"
    f"client_id={CLIENT_ID}&"
    f"redirect_uri={REDIRECT_URI}&"
    f"response_type=code&"
    f"scope={urllib.parse.quote(SCOPES)}&"
    f"access_type=offline&"
    f"prompt=consent"
)

print(f"Opening browser for authorization...")
webbrowser.open(auth_url)

# Step 2: Capture authorization code
auth_code = None

class OAuthHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global auth_code
        query = urllib.parse.urlparse(self.path).query
        params = urllib.parse.parse_qs(query)
        auth_code = params.get('code', [None])[0]
        
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b'<html><body><h1>Authorization successful!</h1><p>You can close this window.</p></body></html>')

server = HTTPServer(('localhost', 8080), OAuthHandler)
server.handle_request()

# Step 3: Exchange code for tokens
if auth_code:
    data = urllib.parse.urlencode({
        'code': auth_code,
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'redirect_uri': REDIRECT_URI,
        'grant_type': 'authorization_code'
    }).encode()
    
    req = urllib.request.Request('https://oauth2.googleapis.com/token', data=data)
    response = json.load(urllib.request.urlopen(req))
    
    print(f"\nRefresh Token: {response['refresh_token']}")
    print(f"Access Token: {response['access_token']}")
    print(f"\nSet your refresh token:")
    print(f"export GOOGLE_REFRESH_TOKEN=\"{response['refresh_token']}\"")

Getting Access Token

Before making API calls, get a fresh access token:

import urllib.request
import urllib.parse
import json
import os

def get_access_token():
    """Get a fresh access token using refresh token"""
    data = urllib.parse.urlencode({
        'client_id': os.environ['GOOGLE_CLIENT_ID'],
        'client_secret': os.environ['GOOGLE_CLIENT_SECRET'],
        'refresh_token': os.environ['GOOGLE_REFRESH_TOKEN'],
        'grant_type': 'refresh_token'
    }).encode()
    
    req = urllib.request.Request('https://oauth2.googleapis.com/token', data=data)
    response = json.load(urllib.request.urlopen(req))
    return response['access_token']

# Store for reuse
access_token = get_access_token()
print(f"Access Token: {access_token}")

Base URL

https://docs.googleapis.com/v1

All requests require the access token in the Authorization header:

Authorization: Bearer {access_token}

Quick Start

import urllib.request
import json
import os

# Get access token first (using function from above)
access_token = get_access_token()

# Get document
req = urllib.request.Request('https://docs.googleapis.com/v1/documents/{documentId}')
req.add_header('Authorization', f'Bearer {access_token}')
doc = json.load(urllib.request.urlopen(req))
print(json.dumps(doc, indent=2))

API Reference

Create Document

import urllib.request
import json

access_token = get_access_token()

data = json.dumps({'title': 'My New Document'}).encode()
req = urllib.request.Request(
    'https://docs.googleapis.com/v1/documents',
    data=data,
    method='POST'
)
req.add_header('Authorization', f'Bearer {access_token}')
req.add_header('Content-Type', 'application/json')

response = json.load(urllib.request.urlopen(req))
doc_id = response['documentId']
print(f"Created document: {doc_id}")
print(f"URL: https://docs.google.com/document/d/{doc_id}/edit")

Get Document

req = urllib.request.Request(
    f'https://docs.googleapis.com/v1/documents/{doc_id}'
)
req.add_header('Authorization', f'Bearer {access_token}')
doc = json.load(urllib.request.urlopen(req))

Batch Update Document

# Insert text at beginning
updates = {
    'requests': [
        {
            'insertText': {
                'location': {'index': 1},
                'text': 'Hello, World!\n\n'
            }
        }
    ]
}

data = json.dumps(updates).encode()
req = urllib.request.Request(
    f'https://docs.googleapis.com/v1/documents/{doc_id}:batchUpdate',
    data=data,
    method='POST'
)
req.add_header('Authorization', f'Bearer {access_token}')
req.add_header('Content-Type', 'application/json')

response = json.load(urllib.request.urlopen(req))

Common Operations

Insert Text

{
    'requests': [
        {
            'insertText': {
                'location': {'index': 1},
                'text': 'Your text here'
            }
        }
    ]
}

Format Text (Bold, Italic, Font Size)

{
    'requests': [
        {
            'updateTextStyle': {
                'range': {
                    'startIndex': 1,
                    'endIndex': 10
                },
                'textStyle': {
                    'bold': True,
                    'italic': True,
                    'fontSize': {
                        'magnitude': 14,
                        'unit': 'PT'
                    }
                },
                'fields': 'bold,italic,fontSize'
            }
        }
    ]
}

Insert Table

{
    'requests': [
        {
            'insertTable': {
                'location': {'index': 1},
                'rows': 3,
                'columns': 4
            }
        }
    ]
}

Replace Text

{
    'requests': [
        {
            'replaceAllText': {
                'containsText': {
                    'text': '{{placeholder}}',
                    'matchCase': True
                },
                'replaceText': 'Actual value'
            }
        }
    ]
}

Delete Content

{
    'requests': [
        {
            'deleteContentRange': {
                'range': {
                    'startIndex': 1,
                    'endIndex': 50
                }
            }
        }
    ]
}

Insert Page Break

{
    'requests': [
        {
            'insertPageBreak': {
                'location': {'index': 1}
            }
        }
    ]
}

Update Paragraph Style

{
    'requests': [
        {
            'updateParagraphStyle': {
                'range': {
                    'startIndex': 1,
                    'endIndex': 50
                },
                'paragraphStyle': {
                    'namedStyleType': 'HEADING_1',
                    'alignment': 'CENTER'
                },
                'fields': 'namedStyleType,alignment'
            }
        }
    ]
}

Complete Example: Create and Format Document

import urllib.request
import urllib.parse
import json
import os

def get_access_token():
    """Get fresh access token"""
    data = urllib.parse.urlencode({
        'client_id': os.environ['GOOGLE_CLIENT_ID'],
        'client_secret': os.environ['GOOGLE_CLIENT_SECRET'],
        'refresh_token': os.environ['GOOGLE_REFRESH_TOKEN'],
        'grant_type': 'refresh_token'
    }).encode()
    
    req = urllib.request.Request('https://oauth2.googleapis.com/token', data=data)
    response = json.load(urllib.request.urlopen(req))
    return response['access_token']

def create_document(title, access_token):
    """Create a new document"""
    data = json.dumps({'title': title}).encode()
    req = urllib.request.Request(
        'https://docs.googleapis.com/v1/documents',
        data=data,
        method='POST'
    )
    req.add_header('Authorization', f'Bearer {access_token}')
    req.add_header('Content-Type', 'application/json')
    
    response = json.load(urllib.request.urlopen(req))
    return response['documentId']

def batch_update(doc_id, requests, access_token):
    """Apply batch updates to document"""
    data = json.dumps({'requests': requests}).encode()
    req = urllib.request.Request(
        f'https://docs.googleapis.com/v1/documents/{doc_id}:batchUpdate',
        data=data,
        method='POST'
    )
    req.add_header('Authorization', f'Bearer {access_token}')
    req.add_header('Content-Type', 'application/json')
    
    return json.load(urllib.request.urlopen(req))

# Main workflow
access_token = get_access_token()

# Create document
doc_id = create_document('Project Report', access_token)
print(f"Created: https://docs.google.com/document/d/{doc_id}/edit")

# Add content with formatting
requests = [
    # Insert title
    {
        'insertText': {
            'location': {'index': 1},
            'text': 'Project Report\n\n'
        }
    },
    # Format title as heading
    {
        'updateParagraphStyle': {
            'range': {'startIndex': 1, 'endIndex': 15},
            'paragraphStyle': {'namedStyleType': 'HEADING_1'},
            'fields': 'namedStyleType'
        }
    },
    # Add body text
    {
        'insertText': 

---

*Content truncated.*

When not to use it

  • Non-Google Docs environments
  • Tasks without OAuth 2.0 setup

Prerequisites

Google Cloud ProjectOAuth 2.0 credentials

Limitations

  • Requires OAuth 2.0 setup
  • Rate limited by Google API quotas

How it compares

It enables automated document generation and formatting, unlike manual editing.

Compared to similar skills

google-docs-skill side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
google-docs-skill (this skill)02moCautionIntermediate
xhs-note-creator44moReviewBeginner
openai-whisper382moNo flagsBeginner
whisper-transcription12moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

xhs-note-creator

comeonzhj

小红书笔记素材创作技能。当用户需要创建小红书笔记素材时使用这个技能。技能包含:根据用户的需求和提供的资料,撰写小红书笔记内容(标题+正文),生成图片卡片(封面+正文卡片),以及发布小红书笔记。

49

openai-whisper

openclaw

Local speech-to-text with the Whisper CLI (no API key).

38140

whisper-transcription

benchflow-ai

Transcribe audio/video to text with word-level timestamps using OpenAI Whisper. Use when you need speech-to-text with accurate timing information for each word.

15

rfp_contents

yellowCornSalad

공고 카드의 콘텐츠 품질 점검 + LLM 자동 요약. 예산·기간 정확성, 본문 가독성, 키워드 매칭 정확성, 상세보기 가독성 5축 점검 + 카드에 본문+첨부 종합 150자 요약을 ai_summary 컬럼에 저장.

00

business-document-generator

ailabs-393

This skill should be used when the user requests to create professional business documents (proposals, business plans, or budgets) from templates. It provides PDF templates and a Python script for generating filled documents from user data.

316

pr-writing-review

evalstate

Extract and analyze writing improvements from GitHub PR review comments. Use when asked to show review feedback, style changes, or editorial improvements from a GitHub pull request URL. Handles both explicit suggestions and plain text feedback. Produces structured output comparing original phrasing with reviewer suggestions to help refine future writing.

27

Search skills

Search the agent skills registry