---
name: google-workspace
description: "Access Google Docs, Sheets, Drive, Calendar, Gmail, Analytics (GA4), and Indexing API. Use when asked to read/write Google Docs, query Sheets, manage Drive files, check Calendar, send Gmail, or pull GA4 analytics data."
---

# Google Workspace Skill

Access Google Docs, Sheets, Drive, Calendar, Gmail, Analytics (GA4), and Indexing API for your owner.

## 首次使用：引导 Owner 授权

当 owner 第一次要求使用 Google 相关功能（读文档、查 Drive、看日历等），先检查 token 是否存在：

```bash
python3 SKILL_DIR/scripts/google-oauth.py token 2>/dev/null
```

**如果报错（没有 token）**，用以下流程引导 owner：

### Step 1: 生成授权链接
```bash
python3 SKILL_DIR/scripts/google-oauth.py auth
```

### Step 2: 发给 owner 的消息模板（直接用这个）

> 🔗 **首次连接 Google 账号**
>
> 我需要你授权一下 Google 账号，之后就可以帮你操作 Docs / Sheets / Drive 了。只需要做一次！
>
> **操作步骤：**
> 1. 点击下面的链接
> 2. 用你的 `@myshell.ai` 邮箱登录
> 3. 点「允许」授权
> 4. 授权后页面会跳转到一个**打不开的页面**（显示"无法访问此网站"），这是**正常的**！
> 5. 把浏览器**地址栏里的完整网址**复制发给我（以 `http://localhost/?...` 开头的那一串）
>
> 授权链接：{这里放生成的链接}

### Step 3: 收到 owner 发回的 URL 后，提取 code 并交换 token

从 URL 中提取 `code=` 和 `&` 之间的值（注意 URL decode），然后：
```bash
python3 SKILL_DIR/scripts/google-oauth.py exchange '<提取到的code>'
```

### Step 4: 验证
```bash
TOKEN=$(python3 SKILL_DIR/scripts/google-oauth.py token)
curl -s "https://www.googleapis.com/drive/v3/files?pageSize=3&fields=files(id,name,mimeType)" -H "Authorization: Bearer $TOKEN"
```

成功后告诉 owner：「✅ Google 账号连接成功！以后可以直接帮你操作 Google 文档了。」

---

## 日常使用

### 获取 Token
```bash
TOKEN=$(python3 SKILL_DIR/scripts/google-oauth.py token)
```
Token 有效期 1 小时，过期自动用 refresh token 刷新，owner 不需要再操作。

### Google Drive
```bash
# 列出最近文件
curl -s "https://www.googleapis.com/drive/v3/files?pageSize=10&fields=files(id,name,mimeType,modifiedTime)&orderBy=modifiedTime desc" -H "Authorization: Bearer $TOKEN"

# 搜索文件
curl -s "https://www.googleapis.com/drive/v3/files?q=name+contains+'关键词'&fields=files(id,name,mimeType)" -H "Authorization: Bearer $TOKEN"

# 导出 Google Doc 为纯文本
curl -s "https://www.googleapis.com/drive/v3/files/{fileId}/export?mimeType=text/plain" -H "Authorization: Bearer $TOKEN"

# 导出 Google Sheet 为 CSV
curl -s "https://www.googleapis.com/drive/v3/files/{fileId}/export?mimeType=text/csv" -H "Authorization: Bearer $TOKEN"
```

### Google Docs
```bash
# 读取文档
curl -s "https://docs.googleapis.com/v1/documents/{documentId}" -H "Authorization: Bearer $TOKEN"

# 创建文档
curl -s -X POST "https://docs.googleapis.com/v1/documents" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"title": "文档标题"}'

# 插入文本
curl -s -X POST "https://docs.googleapis.com/v1/documents/{documentId}:batchUpdate" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"requests":[{"insertText":{"location":{"index":1},"text":"内容"}}]}'
```

### Google Sheets
```bash
# 读取范围
curl -s "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}" -H "Authorization: Bearer $TOKEN"

# 写入范围
curl -s -X PUT "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}?valueInputOption=USER_ENTERED" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"values":[["a","b"],["c","d"]]}'

# 追加行
curl -s -X POST "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{range}:append?valueInputOption=USER_ENTERED" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"values":[["新行数据1","新行数据2"]]}'

# 获取表格元数据
curl -s "https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}?fields=properties,sheets.properties" -H "Authorization: Bearer $TOKEN"
```

### Google Calendar
```bash
# 查看今天的日程
curl -s "https://www.googleapis.com/calendar/v3/calendars/primary/events?maxResults=10&timeMin=$(date -u +%Y-%m-%dT%H:%M:%SZ)&orderBy=startTime&singleEvents=true" -H "Authorization: Bearer $TOKEN"

# 创建日程
curl -s -X POST "https://www.googleapis.com/calendar/v3/calendars/primary/events" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"summary":"会议标题","start":{"dateTime":"2026-03-01T10:00:00+08:00"},"end":{"dateTime":"2026-03-01T11:00:00+08:00"}}'
```

### Gmail（只读）
```bash
# 列出最近邮件
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10" -H "Authorization: Bearer $TOKEN"

# 读取邮件
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{messageId}?format=full" -H "Authorization: Bearer $TOKEN"

# 搜索邮件
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?q=from:someone@example.com" -H "Authorization: Bearer $TOKEN"
```

### Google Analytics (GA4)
```bash
# 运行报告（需要 Property ID）
# P站: 523717097, Art站: 396284383
curl -s -X POST "https://analyticsdata.googleapis.com/v1beta/properties/{propertyId}:runReport" 
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" 
  -d '{"dateRanges":[{"startDate":"7daysAgo","endDate":"today"}],"metrics":[{"name":"activeUsers"},{"name":"sessions"}]}'

# 带维度的报告（按国家）
curl -s -X POST "https://analyticsdata.googleapis.com/v1beta/properties/{propertyId}:runReport" 
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" 
  -d '{"dateRanges":[{"startDate":"30daysAgo","endDate":"today"}],"dimensions":[{"name":"country"}],"metrics":[{"name":"activeUsers"},{"name":"sessions"}],"orderBys":[{"metric":{"metricName":"activeUsers"},"desc":true}],"limit":10}'

# 实时报告
curl -s -X POST "https://analyticsdata.googleapis.com/v1beta/properties/{propertyId}:runRealtimeReport" 
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" 
  -d '{"metrics":[{"name":"activeUsers"}]}'

# 常用 metrics: activeUsers, sessions, screenPageViews, conversions, totalRevenue
# 常用 dimensions: country, city, deviceCategory, sessionSource, pagePath, date
```

### Google Indexing API
```bash
# 提交 URL 更新（通知 Google 抓取）
curl -s -X POST "https://indexing.googleapis.com/v3/urlNotifications:publish" 
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" 
  -d '{"url":"https://example.com/page","type":"URL_UPDATED"}'

# 通知 URL 已删除
curl -s -X POST "https://indexing.googleapis.com/v3/urlNotifications:publish" 
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" 
  -d '{"url":"https://example.com/page","type":"URL_DELETED"}'

# 查询 URL 索引状态
curl -s "https://indexing.googleapis.com/v3/urlNotifications/metadata?url=https://example.com/page" 
  -H "Authorization: Bearer $TOKEN"
```
⚠️ **Indexing API 要求**：OAuth 授权的 Google 账号必须是 Search Console 中对应站点的 Owner。

## 完整 API 文档
- Drive: https://developers.google.com/drive/api/reference/rest/v3
- Docs: https://developers.google.com/docs/api/reference/rest/v1
- Sheets: https://developers.google.com/sheets/api/reference/rest/v4
- Calendar: https://developers.google.com/calendar/api/v3/reference
- Gmail: https://developers.google.com/gmail/api/reference/rest

## 常见问题

**Q: token 过期了怎么办？**
A: 脚本自动用 refresh token 刷新，owner 不需要操作。

**Q: 授权时看到"此应用未经验证"？**
A: 点"高级" → "继续前往"即可，这是内部应用，安全的。

**Q: owner 发来的 URL 里没有 code？**
A: 让 owner 确认是否点了"允许"，如果拒绝了就没有 code。重新发授权链接。

## 常见错误

| 错误 | 原因 | 处理 |
|------|------|------|
| `401 Unauthorized` | OAuth token 过期 | 引导用户重新授权 |
| `403 Forbidden` | 无权限访问该文件/文档 | 检查文件共享设置 |
| `404 Not Found` | 文件 ID 错误或已删除 | 确认 URL 中的 ID |
| `429 Rate Limit` | API 配额用尽 | 等待 60s 或次日重试 |
| GA4 无数据 | Property ID 错或时间范围无数据 | 确认 GA4 属性和日期 |
| Sheets 写入慢 | 大量数据（>1000行） | 分批写入，每批 500 行 |
