Google OAuth Skill
Authenticate with Google services (Gmail, Calendar, Drive, Sheets) via OAuth2. Designed for chat-based agents with minion.do integration.
Capabilities
auth [chat_id] [services...] - Get OAuth URL for user to connect
- Services: gmail, calendar, drive, sheets, docs (default: all)
- Returns:
{ "auth_url": "...", "state": "...", "expires_in": 300 }
- Example:
./index.js auth 123456789 gmail calendar
status [chat_id] - Check if user is connected
- Returns:
{ "connected": true, "email": "user@gmail.com", "services": [...] }
- Example:
./index.js status 123456789
gmail [chat_id] [action] - Gmail operations (list, send, search)
- Actions: list [max], send [to] [subject] [body], search [query]
- Returns: JSON with messages or confirmation
- Example:
./index.js gmail 123456789 list 10
calendar [chat_id] [action] - Calendar operations
- Actions: list [days], create [title] [start] [end], free [date] [duration]
- Returns: JSON with events or confirmation
- Example:
./index.js calendar 123456789 list 7
drive [chat_id] [action] - Drive operations
- Actions: list [max], upload [path], download [fileId]
- Returns: JSON with files or confirmation
- Example:
./index.js drive 123456789 list 10
disconnect [chat_id] - Remove all tokens for user
- Returns:
{ "disconnected": true }
- Example:
./index.js disconnect 123456789
Setup
- Ensure you have a minion.do account or OAuth callback service
- Configure environment variables (see below)
- When user says "Connect my Google account", call:
./index.js auth <chat_id> gmail calendar drive
- Send the
auth_url to user
- Poll status:
./index.js status <chat_id> until connected
Environment Variables
| Variable |
Required |
Default |
Description |
MINION_BASE_URL |
Yes |
https://minion.do |
OAuth callback service URL |
MINION_API_KEY |
No |
- |
API key for minion.do |
OPENCLAW_INSTANCE_ID |
No |
openclaw-local |
Instance identifier |
GOOGLE_TOKEN_DIR |
No |
~/.openclaw/google-tokens |
Where tokens are stored |
Token Storage
Tokens are stored securely per chat:
~/.openclaw/google-tokens/
├── combined-{hash}.json # All services
├── gmail-{hash}.json # Gmail only
├── calendar-{hash}.json # Calendar only
└── drive-{hash}.json # Drive only
Files have 0600 permissions (user read/write only).
OAuth Flow
1. Agent: ./index.js auth 123456789 gmail
2. Skill: Returns auth URL
3. Agent: Send URL to user in chat
4. User: Clicks URL, authorizes with Google
5. Google: Redirects to minion.do with code
6. Skill: Polls and exchanges code for tokens
7. Agent: "✅ Connected as user@gmail.com"
Examples
# Check status
./index.js status 123456789
# Get Gmail messages
./index.js gmail 123456789 list 10
# Search Gmail
./index.js gmail 123456789 search "from:boss@company.com"
# List calendar events
./index.js calendar 123456789 list 7
# Find free slots
./index.js calendar 123456789 free 2026-02-15 60
# List Drive files
./index.js drive 123456789 list 20
# Disconnect
./index.js disconnect 123456789
Dependencies
- Node.js >= 14
- Python 3 (for Google API scripts)
google-auth-client.py and google_services.py in scripts/
Security
- ✅ Tokens never logged to console
- ✅ 0600 file permissions
- ✅ 5-minute OAuth session timeout
- ✅ SHA-256 hashed chat IDs in filenames
- ✅ Auto-refresh expired tokens
See Also
1---2name: google-oauth-23description: Google OAuth2 for Gmail, Calendar, Drive, Sheets4---56# Google OAuth Skill78Authenticate with Google services (Gmail, Calendar, Drive, Sheets) via OAuth2. Designed for chat-based agents with minion.do integration.910## Capabilities1112- `auth [chat_id] [services...]` - Get OAuth URL for user to connect13 - Services: gmail, calendar, drive, sheets, docs (default: all)14 - Returns: `{ "auth_url": "...", "state": "...", "expires_in": 300 }`15 - Example: `./index.js auth 123456789 gmail calendar`1617- `status [chat_id]` - Check if user is connected18 - Returns: `{ "connected": true, "email": "user@gmail.com", "services": [...] }`19 - Example: `./index.js status 123456789`2021- `gmail [chat_id] [action]` - Gmail operations (list, send, search)22 - Actions: list [max], send [to] [subject] [body], search [query]23 - Returns: JSON with messages or confirmation24 - Example: `./index.js gmail 123456789 list 10`2526- `calendar [chat_id] [action]` - Calendar operations27 - Actions: list [days], create [title] [start] [end], free [date] [duration]28 - Returns: JSON with events or confirmation29 - Example: `./index.js calendar 123456789 list 7`3031- `drive [chat_id] [action]` - Drive operations32 - Actions: list [max], upload [path], download [fileId]33 - Returns: JSON with files or confirmation34 - Example: `./index.js drive 123456789 list 10`3536- `disconnect [chat_id]` - Remove all tokens for user37 - Returns: `{ "disconnected": true }`38 - Example: `./index.js disconnect 123456789`3940## Setup41421. Ensure you have a minion.do account or OAuth callback service432. Configure environment variables (see below)443. When user says "Connect my Google account", call: `./index.js auth <chat_id> gmail calendar drive`454. Send the `auth_url` to user465. Poll status: `./index.js status <chat_id>` until connected4748## Environment Variables4950| Variable | Required | Default | Description |51|----------|----------|---------|-------------|52| `MINION_BASE_URL` | Yes | `https://minion.do` | OAuth callback service URL |53| `MINION_API_KEY` | No | - | API key for minion.do |54| `OPENCLAW_INSTANCE_ID` | No | `openclaw-local` | Instance identifier |55| `GOOGLE_TOKEN_DIR` | No | `~/.openclaw/google-tokens` | Where tokens are stored |5657## Token Storage5859Tokens are stored securely per chat:60```61~/.openclaw/google-tokens/62├── combined-{hash}.json # All services63├── gmail-{hash}.json # Gmail only64├── calendar-{hash}.json # Calendar only65└── drive-{hash}.json # Drive only66```6768Files have 0600 permissions (user read/write only).6970## OAuth Flow7172```731. Agent: ./index.js auth 123456789 gmail742. Skill: Returns auth URL753. Agent: Send URL to user in chat764. User: Clicks URL, authorizes with Google775. Google: Redirects to minion.do with code786. Skill: Polls and exchanges code for tokens797. Agent: "✅ Connected as user@gmail.com"80```8182## Examples8384```bash85# Check status86./index.js status 1234567898788# Get Gmail messages89./index.js gmail 123456789 list 109091# Search Gmail92./index.js gmail 123456789 search "from:boss@company.com"9394# List calendar events95./index.js calendar 123456789 list 79697# Find free slots98./index.js calendar 123456789 free 2026-02-15 6099100# List Drive files101./index.js drive 123456789 list 20102103# Disconnect104./index.js disconnect 123456789105```106107## Dependencies108109- Node.js >= 14110- Python 3 (for Google API scripts)111- `google-auth-client.py` and `google_services.py` in `scripts/`112113## Security114115- ✅ Tokens never logged to console116- ✅ 0600 file permissions117- ✅ 5-minute OAuth session timeout118- ✅ SHA-256 hashed chat IDs in filenames119- ✅ Auto-refresh expired tokens120121## See Also122123- [Google OAuth Scopes](https://developers.google.com/identity/protocols/oauth2/scopes)124- [Gmail API](https://developers.google.com/gmail/api/reference/rest)125- [Calendar API](https://developers.google.com/calendar/api/v3/reference)