Google Workspace
為 Hermes 提供 Gmail、日曆、雲端硬盤、聯繫人、表格和文檔的集成。使用由 Hermes 管理的 OAuth2 設置,在可用時優先使用 Google Workspace CLI (gws) 以獲得更廣泛的 API 覆蓋範圍,否則回退到 Python 客戶端庫。
技能元數據
| 來源 | 捆綁(默認安裝) |
| 路徑 | skills/productivity/google-workspace |
| 版本 | 1.0.0 |
| 作者 | Nous Research |
| 許可證 | MIT |
| 標籤 | Google, Gmail, Calendar, Drive, Sheets, Docs, Contacts, Email, OAuth |
| 相關技能 | himalaya |
參考:完整 SKILL.md
以下是 Hermes 在觸發此技能時加載的完整技能定義。這是技能激活時代理所看到的指令。
Google Workspace
通過 Hermes 管理的 OAuth 和一個輕量級 CLI 封裝器,訪問 Gmail、日曆、雲端硬盤、聯繫人、表格和文檔。當安裝了 gws 時,該技能將其用作執行後端,以提供更廣泛的 Google Workspace 覆蓋範圍;否則回退到捆綁的 Python 客戶端實現。
參考資料
references/gmail-search-syntax.md— Gmail 搜索運算符(is:unread, from:, newer_than: 等)
腳本
scripts/setup.py— OAuth2 設置(運行一次以進行授權)scripts/google_api.py— 兼容性封裝器 CLI。它在可用時優先使用gws進行操作,同時保留 Hermes 現有的 JSON 輸出契約。
首次設置
設置過程完全非交互式——您可以逐步驅動它,使其適用於 CLI、Telegram、Discord 或任何平臺。
首先定義一個簡寫:
GSETUP="python ${HERMES_HOME:-$HOME/.hermes}/skills/productivity/google-workspace/scripts/setup.py"
步驟 0:檢查是否已設置
$GSETUP --check
如果打印出 AUTHENTICATED,請跳至“用法”部分——設置已完成。
步驟 1:分類——詢問用戶需求
在開始 OAuth 設置之前,向用戶提出兩個問題:
問題 1:“您需要哪些 Google 服務?僅電子郵件,還是也需要日曆/雲端硬盤/表格/文檔?”
-
僅電子郵件 → 他們根本不需要此技能。改用
himalaya技能——它配合 Gmail 應用專用密碼(設置 → 安全性 → 應用專用密碼)使用,只需 2 分鐘即可設置完成。無需 Google Cloud 項目。加載 himalaya 技能並按照其設置說明操作。 -
電子郵件 + 日曆 → 繼續使用此技能,但在授權期間使用
--services email,calendar,以便同意屏幕僅請求他們實際需要的範圍。 -
僅日曆/雲端硬盤/表格/文檔 → 繼續使用此技能,並使用更窄的
--services集合,如calendar,drive,sheets,docs。 -
完整 Workspace 訪問權限 → 繼續使用此技能,並使用默認的
all服務集合。
問題 2:“您的 Google 賬戶是否使用了高級保護功能(登錄需要硬件安全密鑰)?如果您不確定,可能沒有——這是您需要明確註冊的功能。”
- 否 / 不確定 → 正常設置。繼續以下步驟。
- 是 → 他們的 Workspace 管理員必須將 OAuth 客戶端 ID 添加到組織的允許應用列表中,步驟 4 才能生效。請提前告知他們。
步驟 2:創建 OAuth 憑據(一次性,約 5 分鐘)
告訴用戶:
您需要一個 Google Cloud OAuth 客戶端。這是一次性設置:
- 創建或選擇項目: https://console.cloud.google.com/projectselector2/home/dashboard
- 從 API 庫中啟用所需的 API: https://console.cloud.google.com/apis/library 啟用:Gmail API、Google Calendar API、Google Drive API、 Google Sheets API、Google Docs API、People API
- 在此處創建 OAuth 客戶端: https://console.cloud.google.com/apis/credentials 憑據 → 創建憑據 → OAuth 2.0 客戶端 ID
- 應用類型:“桌面應用” → 創建
- 如果應用仍處於測試階段,請在此處將用戶的 Google 賬戶添加為測試用戶: https://console.cloud.google.com/auth/audience 受眾 → 測試用戶 → 添加用戶
- 下載 JSON 文件並告訴我文件路徑
重要的 Hermes CLI 注意事項:如果文件路徑以
/開頭,請勿在 CLI 中僅將裸路徑作為單獨的消息發送,因為它可能被誤認為是斜槓命令。請將其包含在句子中發送,例如:The JSON file path is: /home/user/Downloads/client_secret_....json
一旦他們提供了路徑:
$GSETUP --client-secret /path/to/client_secret.json
如果他們粘貼的是原始客戶端 ID / 客戶端秘密值而不是文件路徑,請為他們編寫一個有效的桌面 OAuth JSON 文件,將其保存到明確的位置(例如 ~/Downloads/hermes-google-client-secret.json),然後針對該文件運行 --client-secret。
步驟 3:獲取授權 URL
使用在步驟 1 中選擇的服務集合。示例:
$GSETUP --auth-url --services email,calendar --format json
$GSETUP --auth-url --services calendar,drive,sheets,docs --format json
$GSETUP --auth-url --services all --format json
這將返回包含 auth_url 字段的 JSON,並將確切的 URL 保存到 ~/.hermes/google_oauth_last_url.txt。
此步驟的代理規則:
- 提取
auth_url字段,並將該確切 URL 作為單行發送給用戶。 - 告知用戶,在授權後,瀏覽器很可能會在
http://localhost:1上失敗,這是預期行為。 - 告知他們從瀏覽器地址欄複製整個重定向後的 URL。
- 如果用戶收到
Error 403: access_denied,直接引導他們前往https://console.cloud.google.com/auth/audience將自己添加為測試用戶。
第 4 步:交換代碼
用戶將粘貼回類似 http://localhost:1/?code=4/0A...&scope=... 的 URL,
或者僅粘貼代碼字符串。兩者均可。--auth-url 步驟會在本地存儲一個臨時的
待處理 OAuth 會話,以便 --auth-code 稍後完成 PKCE 交換,
即使在無頭系統上也是如此:
$GSETUP --auth-code "THE_URL_OR_CODE_THE_USER_PASTED" --format json
如果 --auth-code 因代碼過期、已被使用或來自較舊的瀏覽器標籤頁而失敗,
它現在會返回一個新的 fresh_auth_url。在這種情況下,
立即將新 URL 發送給用戶,並讓他們僅使用最新的瀏覽器重定向進行重試。
第 5 步:驗證
$GSETUP --check
應打印 AUTHENTICATED。設置完成——從現在起令牌將自動刷新。
注意事項
- 令牌存儲在
~/.hermes/google_token.json中並自動刷新。 - 待處理的 OAuth 會話狀態/驗證器臨時存儲在
~/.hermes/google_oauth_pending.json中,直到交換完成。 - 如果安裝了
gws,google_api.py會將其指向相同的~/.hermes/google_token.json憑據文件。用戶無需運行單獨的gws auth login流程。 - 要撤銷訪問權限:
$GSETUP --revoke
用法
所有命令都通過 API 腳本執行。設置 GAPI 作為簡寫:
GAPI="python ${HERMES_HOME:-$HOME/.hermes}/skills/productivity/google-workspace/scripts/google_api.py"
Gmail
# Search (returns JSON array with id, from, subject, date, snippet)
$GAPI gmail search "is:unread" --max 10
$GAPI gmail search "from:boss@company.com newer_than:1d"
$GAPI gmail search "has:attachment filename:pdf newer_than:7d"
# Read full message (returns JSON with body text)
$GAPI gmail get MESSAGE_ID
# Send
$GAPI gmail send --to user@example.com --subject "Hello" --body "Message text"
$GAPI gmail send --to user@example.com --subject "Report" --body "<h1>Q4</h1><p>Details...</p>" --html
$GAPI gmail send --to user@example.com --subject "Hello" --from '"Research Agent" <user@example.com>' --body "Message text"
# Reply (automatically threads and sets In-Reply-To)
$GAPI gmail reply MESSAGE_ID --body "Thanks, that works for me."
$GAPI gmail reply MESSAGE_ID --from '"Support Bot" <user@example.com>' --body "Thanks"
# Labels
$GAPI gmail labels
$GAPI gmail modify MESSAGE_ID --add-labels LABEL_ID
$GAPI gmail modify MESSAGE_ID --remove-labels UNREAD
Calendar(日曆)
# List events (defaults to next 7 days)
$GAPI calendar list
$GAPI calendar list --start 2026-03-01T00:00:00Z --end 2026-03-07T23:59:59Z
# Create event (ISO 8601 with timezone required)
$GAPI calendar create --summary "Team Standup" --start 2026-03-01T10:00:00-06:00 --end 2026-03-01T10:30:00-06:00
$GAPI calendar create --summary "Lunch" --start 2026-03-01T12:00:00Z --end 2026-03-01T13:00:00Z --location "Cafe"
$GAPI calendar create --summary "Review" --start 2026-03-01T14:00:00Z --end 2026-03-01T15:00:00Z --attendees "alice@co.com,bob@co.com"
# Delete event
$GAPI calendar delete EVENT_ID
Drive(雲端硬盤)
$GAPI drive search "quarterly report" --max 10
$GAPI drive search "mimeType='application/pdf'" --raw-query --max 5
Contacts(聯繫人)
$GAPI contacts list --max 20
Sheets(表格)
# Read
$GAPI sheets get SHEET_ID "Sheet1!A1:D10"
# Write
$GAPI sheets update SHEET_ID "Sheet1!A1:B2" --values '[["Name","Score"],["Alice","95"]]'
# Append rows
$GAPI sheets append SHEET_ID "Sheet1!A:C" --values '[["new","row","data"]]'
Docs(文檔)
$GAPI docs get DOC_ID
輸出格式
所有命令均返回 JSON。使用 jq 解析或直接讀取。關鍵字段:
- Gmail 搜索:
[{id, threadId, from, to, subject, date, snippet, labels}] - Gmail 獲取:
{id, threadId, from, to, subject, date, labels, body} - Gmail 發送/回覆:
{status: "sent", id, threadId} - 日曆列表:
[{id, summary, start, end, location, description, htmlLink}] - 日曆創建:
{status: "created", id, summary, htmlLink} - 雲端硬盤搜索:
[{id, name, mimeType, modifiedTime, webViewLink}] - 聯繫人列表:
[{name, emails: [...], phones: [...]}] - 表格獲取:
[[cell, cell, ...], ...]
規則
- 在未首先與用戶確認的情況下,切勿發送電子郵件或創建/刪除事件。 顯示草稿內容並請求批准。
- 首次使用前檢查身份驗證 —— 運行
setup.py --check。如果失敗,指導用戶完成設置。 - 對於複雜查詢,使用 Gmail 搜索語法參考 —— 通過
skill_view("google-workspace", file_path="references/gmail-search-syntax.md")加載它。 - 日曆時間必須包含時區 —— 始終使用帶偏移量的 ISO 8601 格式(例如
2026-03-01T10:00:00-06:00)或 UTC(Z)。 - 遵守速率限制 —— 避免快速連續調用 API。儘可能批量讀取。
故障排除
| 問題 | 修復方法 |
|---|---|
NOT_AUTHENTICATED | 運行上述設置步驟 2-5 |
REFRESH_FAILED | 令牌已被撤銷或過期 —— 重做步驟 3-5 |
HttpError 403: Insufficient Permission | 缺少 API 範圍 —— $GSETUP --revoke 然後重做步驟 3-5 |
HttpError 403: Access Not Configured | API 未啟用 —— 用戶需要在 Google Cloud Console 中啟用它 |
ModuleNotFoundError | 運行 $GSETUP --install-deps |
| Advanced Protection 阻止身份驗證 | Workspace 管理員必須將 OAuth 客戶端 ID 加入白名單 |
撤銷訪問權限
$GSETUP --revoke