zagran-google-docs-skill

TotalClaw 作者 totalclaw

通过 OAuth 2.0 集成 Google Docs API,支持创建文档、插入格式化文本及批量更新文档内容。

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:totalclaw~zagran-google-docs-skill
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~zagran-google-docs-skill/file -o zagran-google-docs-skill.md
## 概述(中文)

通过 OAuth 2.0 集成 Google Docs API,支持创建文档、插入格式化文本及批量更新文档内容。

## 技能正文

# Google Docs API 集成

通过 OAuth 2.0 直接访问 Google Docs API。创建文档、插入和格式化文本,并管理文档内容。

## 前提条件

1. **Google Cloud 项目设置**
   - 前往 [Google Cloud Console](https://console.cloud.google.com)
   - 创建新项目或选择现有项目
   - 启用 Google Docs API
   - 创建 OAuth 2.0 凭据(桌面应用或 Web 应用)
   - 下载凭据 JSON 文件

2. **环境设置**
   ```bash
   export GOOGLE_CLIENT_ID="your-client-id"
   export GOOGLE_CLIENT_SECRET="your-client-secret"
   export GOOGLE_REFRESH_TOKEN="your-refresh-token"
   ```

## 认证

### 获取 OAuth 令牌

使用以下 Python 脚本获取 refresh token(一次性设置):

```python
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"
Refresh Token: {response['refresh_token']}")
    print(f"Access Token: {response['access_token']}")
    print(f"
Set your refresh token:")
    print(f"export GOOGLE_REFRESH_TOKEN="{response['refresh_token']}"")
```

### 获取 Access Token

在发起 API 调用前,获取新的 access token:

```python
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}")
```

## 基础 URL

```
https://docs.googleapis.com/v1
```

所有请求需在 Authorization 头中携带 access token:

```
Authorization: Bearer {access_token}
```

## 快速开始

```python
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 参考

### 创建文档

```python
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")
```

### 获取文档

```python
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))
```

### 批量更新文档

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

'
            }
        }
    ]
}

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))
```

## 常用操作

### 插入文本

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

### 格式化文本(粗体、斜体、字号)

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

### 插入表格

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

### 替换文本

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

### 删除内容

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

### 插入分页符

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

### 更新段落样式

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

## 完整示例:创建并格式化文档

```python
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)