$npx -y skills add opendatahub-io/ai-helpers --skill google-workspaceFetch and query data from Google Workspace using the gws CLI — Gmail, Calendar, Docs, Sheets, Slides, and Drive. Use this skill whenever the user mentions email, inbox, messages, calendar, meetings, schedule, agenda, Google Docs, spreadsheets, presentations, or Drive files. Trigg
| 1 | # Google Workspace |
| 2 | |
| 3 | Access Google Workspace data via the `gws` CLI. Fetches content |
| 4 | and presents it as markdown context inside the current session. |
| 5 | |
| 6 | ## Prerequisites |
| 7 | |
| 8 | - `gws` binary must be on `$PATH` |
| 9 | - Authenticated: run `gws auth login` if not already logged in |
| 10 | |
| 11 | If `gws` is not installed, not on PATH, or authentication fails with a 401/403, |
| 12 | read `references/setup.md` for the full first-time setup walkthrough. |
| 13 | |
| 14 | ## Command Patterns |
| 15 | |
| 16 | `gws` has two ways to call any service: |
| 17 | |
| 18 | 1. **Shortcut commands** (prefixed with `+`) — concise, opinionated, cover common |
| 19 | tasks. Prefer these when they fit. |
| 20 | 2. **Raw API calls** — full access to any Google API method via |
| 21 | `gws <service> <resource> <method> --params '<JSON>'`. Use when shortcuts |
| 22 | don't expose the parameter you need. |
| 23 | |
| 24 | Try the shortcut first. Fall back to the raw API when you need filters, field |
| 25 | selection, pagination control, or parameters the shortcut doesn't expose. |
| 26 | |
| 27 | ## Extracting IDs from Google URLs |
| 28 | |
| 29 | Many requests include a Google URL. Extract the document ID before calling `gws`: |
| 30 | |
| 31 | | Service | URL pattern | ID location | |
| 32 | |---------|------------|-------------| |
| 33 | | Docs | `docs.google.com/document/d/<ID>/...` | between `/d/` and next `/` | |
| 34 | | Sheets | `docs.google.com/spreadsheets/d/<ID>/...` | between `/d/` and next `/` | |
| 35 | | Slides | `docs.google.com/presentation/d/<ID>/...` | between `/d/` and next `/` | |
| 36 | | Drive file | `drive.google.com/file/d/<ID>/...` | between `/d/` and next `/` | |
| 37 | | Drive folder | `drive.google.com/drive/folders/<ID>` | after `/folders/` | |
| 38 | |
| 39 | Extract the ID with `sed` (works on both macOS and Linux): |
| 40 | |
| 41 | ```bash |
| 42 | URL="https://docs.google.com/document/d/1aBcDeFgHiJkLmNoPqRsTuVwXyZ/edit" |
| 43 | DOC_ID=$(echo "$URL" | sed -E 's|.*/d/([A-Za-z0-9_-]+).*|\1|') |
| 44 | ``` |
| 45 | |
| 46 | ## Shell Tips |
| 47 | |
| 48 | - **zsh `!` expansion**: Sheet ranges like `Sheet1!A1` trigger history expansion |
| 49 | in zsh. Use double quotes: `--range "Sheet1!A1:D10"` |
| 50 | - **JSON flags**: Wrap `--params` and `--json` in single quotes so the shell |
| 51 | preserves inner double quotes: `--params '{"pageSize": 5}'` |
| 52 | |
| 53 | ## Gmail |
| 54 | |
| 55 | ### Triage unread messages |
| 56 | |
| 57 | ```bash |
| 58 | gws gmail +triage |
| 59 | gws gmail +triage --max 10 |
| 60 | gws gmail +triage --labels |
| 61 | ``` |
| 62 | |
| 63 | ### List messages matching a query |
| 64 | |
| 65 | Gmail search syntax works with `--query`. Common patterns: |
| 66 | |
| 67 | ```bash |
| 68 | # Messages in a label |
| 69 | gws gmail +triage --query 'label:my-label' --max 5 |
| 70 | |
| 71 | # Messages from a sender |
| 72 | gws gmail +triage --query 'from:alice@example.com' --max 10 |
| 73 | |
| 74 | # Unread messages in a label |
| 75 | gws gmail +triage --query 'label:updates is:unread' |
| 76 | |
| 77 | # Recent messages with a subject keyword |
| 78 | gws gmail +triage --query 'subject:quarterly-report newer_than:7d' |
| 79 | ``` |
| 80 | |
| 81 | ### Read a specific message |
| 82 | |
| 83 | `+triage` output includes message IDs. Use the ID to fetch the full body: |
| 84 | |
| 85 | ```bash |
| 86 | gws gmail +read --id <MESSAGE_ID> |
| 87 | gws gmail +read --id <MESSAGE_ID> --headers |
| 88 | ``` |
| 89 | |
| 90 | ### Typical workflow: "show me the latest email in label X" |
| 91 | |
| 92 | ```bash |
| 93 | # Step 1: find the message |
| 94 | gws gmail +triage --query 'label:X' --max 1 --format json |
| 95 | |
| 96 | # Step 2: extract the ID from the JSON output, then read it |
| 97 | gws gmail +read --id <ID> --headers |
| 98 | ``` |
| 99 | |
| 100 | ### Search with the raw API |
| 101 | |
| 102 | For queries that need parameters beyond what `+triage` exposes: |
| 103 | |
| 104 | ```bash |
| 105 | gws gmail users messages list --params '{"q": "has:attachment larger:5M", "maxResults": 5}' |
| 106 | ``` |
| 107 | |
| 108 | ## Calendar |
| 109 | |
| 110 | ### View upcoming events |
| 111 | |
| 112 | ```bash |
| 113 | gws calendar +agenda # next few upcoming events |
| 114 | gws calendar +agenda --today # today only |
| 115 | gws calendar +agenda --tomorrow # tomorrow only |
| 116 | gws calendar +agenda --week # this week |
| 117 | gws calendar +agenda --days 3 # next 3 days |
| 118 | gws calendar +agenda --calendar 'Work' # specific calendar |
| 119 | gws calendar +agenda --today --format table # table output |
| 120 | ``` |
| 121 | |
| 122 | Time-aware commands like `+agenda` automatically use your Google account |
| 123 | timezone. Override with `--timezone America/New_York`. |
| 124 | |
| 125 | ### List events via the API (custom time range or filters) |
| 126 | |
| 127 | ```bash |
| 128 | # Events in the next 7 days on a specific calendar |
| 129 | gws calendar events list \ |
| 130 | --params '{"calendarId": "primary", "timeMin": "2026-04-24T00:00:00Z", "timeMax": "2026-05-01T00:00:00Z", "singleEvents": true, "orderBy": "startTime"}' |
| 131 | ``` |
| 132 | |
| 133 | ### Typical workflow: "show my last N calendar entries titled X" |
| 134 | |
| 135 | ```bash |
| 136 | # Use +agenda with a calendar filter, then grep or parse for matching titles |
| 137 | gws calendar +agenda --days 30 --calendar 'Work' --format json |
| 138 | ``` |
| 139 | |
| 140 | Filter the JSON output for events matching |