← 返回 Skills 市场
google-sheets-soha
作者
Nguyễn Tiến Phan
· GitHub ↗
· v1.0.2
· MIT-0
96
总下载
0
收藏
0
当前安装
3
版本数
在 OpenClaw 中安装
/install google-sheets-soha
功能描述
Read and analyze data from Google Sheets. Trigger when the user mentions "Google Sheet", "spreadsheet", "sheet", sends a docs.google.com/spreadsheets link, o...
使用说明 (SKILL.md)
\r \r
Google Sheets Skill\r
\r Fetches data from Google Sheets via the Google Sheets API v4, caches it on disk, and answers user questions about the data.\r \r ---\r \r
Session Memory\r
\r Maintain the following context throughout the conversation. Update it as new information is learned:\r \r
SHEET_CONTEXT = {\r
spreadsheetId: null, // Active Sheet ID\r
activeTab: null, // Current tab being worked on\r
tabs: [], // Cached list of tab names\r
headers: {}, // Cached headers per tab: { tabName: [...] }\r
rawData: {}, // Cached rows per tab: { tabName: [[...]] }\r
cacheFile: null, // Path to on-disk cache file\r
}\r
```\r
\r
**Rules:**\r
- Once `spreadsheetId` is known → use it for all subsequent turns, never ask again\r
- Once a cache file exists and is within TTL → skip the API call\r
- Always check session context before asking the user for anything\r
\r
---\r
\r
## Step 1 — Get the Sheet ID\r
\r
Check in this order:\r
1. `SHEET_CONTEXT.spreadsheetId` already set → use it directly\r
2. URL in the message → extract the ID between `/d/` and `/edit`:\r
`https://docs.google.com/spreadsheets/d/**SHEET_ID**/edit`\r
3. User provides the ID directly → save and use it\r
4. Not found anywhere → ask **exactly once**:\r
\r
> "Could you share the Google Sheet link or Sheet ID? I'll remember it for the rest of our conversation 😊"\r
\r
Once received → save to `SHEET_CONTEXT.spreadsheetId` immediately and proceed.\r
\r
---\r
\r
## Step 2 — Fetch Data from Google Sheets API\r
\r
Use **Google Sheets API v4**. Choose the auth method based on the sheet type:\r
\r
### Option A: Public sheet (Anyone with the link)\r
\r
```bash\r
# List tabs\r
curl -s "https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}?key={GOOGLE_API_KEY}&fields=sheets.properties" \\r
| python3 -c "import sys,json; d=json.load(sys.stdin); [print(s['properties']['title']) for s in d['sheets']]"\r
\r
# Fetch tab data\r
curl -s "https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/{TAB_NAME}!A1:Z1000?key={GOOGLE_API_KEY}" \\r
| python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get('values',[])))"\r
```\r
\r
### Option B: Private sheet (Service Account)\r
\r
```python\r
import os, json\r
from google.oauth2 import service_account\r
from googleapiclient.discovery import build\r
\r
creds = service_account.Credentials.from_service_account_file(\r
os.environ["GOOGLE_SERVICE_ACCOUNT_JSON"],\r
scopes=["https://www.googleapis.com/auth/spreadsheets.readonly"]\r
)\r
service = build("sheets", "v4", credentials=creds)\r
\r
# List tabs\r
meta = service.spreadsheets().get(spreadsheetId=SHEET_ID).execute()\r
tabs = [s["properties"]["title"] for s in meta["sheets"]]\r
\r
# Fetch tab data\r
result = service.spreadsheets().values().get(\r
spreadsheetId=SHEET_ID,\r
range=f"{TAB_NAME}!A1:Z1000"\r
).execute()\r
rows = result.get("values", [])\r
```\r
\r
Save results to `SHEET_CONTEXT.headers[tabName]` and `SHEET_CONTEXT.rawData[tabName]`.\r
\r
---\r
\r
## Step 3 — Disk Cache\r
\r
Cache fetched data to avoid redundant API calls across turns.\r
\r
### Cache path\r
```\r
~/.openclaw/workspace/.cache/sheets/{spreadsheetId}/{tabName}.json\r
```\r
\r
### Cache file structure\r
```json\r
{\r
"spreadsheetId": "abc123",\r
"tabName": "Sheet1",\r
"fetchedAt": 1710000000,\r
"ttl": 300,\r
"headers": ["Name", "Status", "Date"],\r
"rows": [\r
["Task A", "Done", "2024-01-01"],\r
["Task B", "Pending", "2024-01-02"]\r
]\r
}\r
```\r
\r
### Cache script (run via exec tool)\r
\r
```python\r
import os, json, time, shutil\r
\r
CACHE_DIR = os.path.expanduser("~/.openclaw/workspace/.cache/sheets")\r
TTL = 300 # 5 minutes — increase to 3600 for rarely-changing data\r
\r
def cache_path(sheet_id, tab):\r
d = os.path.join(CACHE_DIR, sheet_id)\r
os.makedirs(d, exist_ok=True) # auto-creates on first use\r
return os.path.join(d, f"{tab.replace('/', '_')}.json")\r
\r
def load_cache(sheet_id, tab):\r
path = cache_path(sheet_id, tab)\r
if not os.path.exists(path):\r
return None\r
with open(path) as f:\r
c = json.load(f)\r
if time.time() - c.get("fetchedAt", 0) > c.get("ttl", TTL):\r
return None # expired — will re-fetch\r
return c\r
\r
def save_cache(sheet_id, tab, headers, rows):\r
path = cache_path(sheet_id, tab)\r
with open(path, "w") as f:\r
json.dump({\r
"spreadsheetId": sheet_id,\r
"tabName": tab,\r
"fetchedAt": int(time.time()),\r
"ttl": TTL,\r
"headers": headers,\r
"rows": rows\r
}, f, ensure_ascii=False)\r
\r
def clear_cache(sheet_id=None):\r
target = os.path.join(CACHE_DIR, sheet_id) if sheet_id else CACHE_DIR\r
if os.path.exists(target):\r
shutil.rmtree(target)\r
```\r
\r
### Cache flow\r
\r
```python\r
cached = load_cache(SHEET_ID, TAB_NAME)\r
if cached:\r
headers, rows = cached["headers"], cached["rows"]\r
else:\r
# fetch from API...\r
headers, rows = fetched_rows[0], fetched_rows[1:]\r
save_cache(SHEET_ID, TAB_NAME, headers, rows)\r
```\r
\r
### When to clear cache\r
\r
| User says | Action |\r
|---|---|\r
| "refresh", "reload", "get latest data" | `clear_cache(SHEET_ID)` then re-fetch |\r
| "clear cache" | `clear_cache()` — wipes everything |\r
| TTL expired | Automatically re-fetches on next request |\r
| User switches to a new sheet | Keep old cache, create new cache for the new sheet |\r
\r
---\r
\r
## Step 4 — Answer the User\r
\r
- Always state which **sheet/tab** the data is from\r
- Use **markdown tables** when displaying multiple rows\r
- Reply in the **same language as the user**\r
- If data exceeds 500 rows, analyze the first 200 and ask if the user wants to narrow the range\r
\r
---\r
\r
## Configuration in openclaw.json\r
\r
Add under `skills.entries` (top-level, not inside `agents`):\r
\r
### Public sheet\r
```json\r
{\r
"skills": {\r
"entries": {\r
"google-sheets-soha": {\r
"enabled": true,\r
"env": {\r
"GOOGLE_API_KEY": "AIza..."\r
}\r
}\r
}\r
}\r
}\r
```\r
\r
### Private sheet\r
```json\r
{\r
"skills": {\r
"entries": {\r
"google-sheets-soha": {\r
"enabled": true,\r
"env": {\r
"GOOGLE_SERVICE_ACCOUNT_JSON": "/home/node/.openclaw/google-sa.json"\r
}\r
}\r
}\r
}\r
}\r
```\r
\r
---\r
\r
## Error Handling\r
\r
| Situation | Action |\r
|---|---|\r
| Sheet ID not provided | Ask once, save when received |\r
| API returns 403 | Sheet is private → guide user to share with service account email |\r
| API returns 404 | Wrong Sheet ID → ask again |\r
| `GOOGLE_API_KEY` not set | Guide user to add it in `openclaw.json` |\r
| Tab not found | List `SHEET_CONTEXT.tabs` and ask user to pick |\r
| Data too large | Analyze first 200 rows, notify user |\r
| `python3` not found | Run: `apt-get install -y python3` inside container |
安全使用建议
This skill appears to do what it claims, but check the following before enabling: (1) It needs either a Google API key (public sheets) or a Service Account JSON file path (private sheets). Only provide the minimum credential required. (2) The skill caches sheet contents and remembers the active Sheet ID under ~/.openclaw/workspace/.cache/sheets — if that data is sensitive, consider the cache TTL or clear the cache after use. (3) The repository/homepage fields are placeholders (github.com/your-username/...) — verify the source/trustworthiness of the published repo and maintainer before installing. (4) There is a minor metadata parsing glitch (registry shows [object Object]) — confirm the env var configuration in your OpenClaw config matches what the SKILL.md frontmatter declares.
功能分析
Type: OpenClaw Skill
Name: google-sheets-soha
Version: 1.0.2
The skill contains instructions for the agent to execute shell commands and Python scripts using unsanitized user-controlled variables (SHEET_ID, TAB_NAME), which presents a risk for command injection and path traversal within the cache management logic (SKILL.md). Furthermore, the error handling section explicitly directs the agent to perform system-level modifications ('apt-get install -y python3'), and the README.md includes defensive language pre-emptively dismissing security warnings as platform false positives. While these behaviors align with the stated goal of managing Google Sheets data, the lack of input validation and the request for privileged execution meet the criteria for a suspicious classification.
能力评估
Purpose & Capability
Name/description match the actual behavior: fetching Google Sheets via Sheets API v4 using either a public API key or a service account, and using python3/curl for fetches. The declared binaries and primary credential are appropriate for the stated capability.
Instruction Scope
SKILL.md instructs the agent to fetch sheet metadata and values, run local python3 scripts, and cache results on disk under ~/.openclaw/workspace/.cache/sheets. This is within scope for a Sheets-reading skill, but the skill persists spreadsheetId in session context and caches sheet contents locally (TTL default 5 minutes) — users should be aware cached sheet contents and the remembered Sheet ID are stored on disk and used for subsequent turns.
Install Mechanism
Instruction-only skill with no install/spec downloads. No code is pulled from external URLs during install — lowest-risk install mechanism.
Credentials
Only Google-related credentials are requested (GOOGLE_API_KEY for public sheets, GOOGLE_SERVICE_ACCOUNT_JSON for private sheets). That is proportional. Minor inconsistency: the frontmatter marks the env vars as not required while primaryEnv is set to GOOGLE_SERVICE_ACCOUNT_JSON and the registry metadata shows malformed env entries ([object Object]) — likely a metadata parsing issue but worth verifying before enabling.
Persistence & Privilege
always:false and agent-invocation allowed (normal). The skill writes cache files under its own workspace path and stores session context in-memory for the conversation; it does not request system-wide privileges or alter other skills' configuration.
如何使用
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install google-sheets-soha - 安装完成后,直接呼叫该 Skill 的名称或使用
/google-sheets-soha触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.2
- Added detailed metadata: environment variable descriptions, repository link, license, and explicit API host permissions.
- Security section clarifies the read-only data access, purpose of external requests, and local execution of scripts.
- Environment variables for both public (GOOGLE_API_KEY) and private (GOOGLE_SERVICE_ACCOUNT_JSON) sheet access are now documented and optional.
- No code or logic changes—documentation and metadata improvements only.
v1.0.1
Version 1.0.1 of google-sheets-soha makes no file or functional changes.
- No code changes or new features introduced
- All existing logic, behaviors, and API integrations remain the same
v1.0.0
Initial release of google-sheets-soha skill:
- Enables reading and analyzing data from Google Sheets via API, with context retention across a session.
- Automatically caches sheet/tab data on disk to minimize repeated API calls, with auto-refresh and user-driven cache clearing.
- Supports both public and private Google Sheets (API key or service account).
- Activates on typical sheet-related language or when users share Google Sheet links.
- Handles basic errors such as missing sheet IDs, access errors, and large datasets, providing clear user guidance.
元数据
常见问题
google-sheets-soha 是什么?
Read and analyze data from Google Sheets. Trigger when the user mentions "Google Sheet", "spreadsheet", "sheet", sends a docs.google.com/spreadsheets link, o... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 96 次。
如何安装 google-sheets-soha?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install google-sheets-soha」即可一键安装,无需额外配置。
google-sheets-soha 是免费的吗?
是的,google-sheets-soha 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。
google-sheets-soha 支持哪些平台?
google-sheets-soha 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 google-sheets-soha?
由 Nguyễn Tiến Phan(@fuco99)开发并维护,当前版本 v1.0.2。
推荐 Skills