Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/gmail-helpers-rollup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@googleworkspace/cli": minor
---

Gmail helpers rollup: mail-builder migration, --attachment flag, +read helper

- Migrate `+send`, `+reply`, `+reply-all`, and `+forward` to the `mail-builder` crate for RFC-compliant MIME construction
- Add `--from` flag to `+send` for send-as alias support
- Add `--attachment` flag to `+send` with MIME type auto-detection, multipart/mixed construction, and path traversal validation
- Add `+read` helper to extract message body and headers (text, HTML, or JSON output)
- RFC 2822 display name quoting is handled natively by `mail-builder`
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ crossterm = "0.29.0"
chrono = "0.4.44"
chrono-tz = "0.10"
iana-time-zone = "0.1"
mail-builder = "0.4"
async-trait = "0.1.89"
serde_yaml = "0.9.34"
percent-encoding = "2.3.2"
Expand Down
1 change: 1 addition & 0 deletions docs/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Shortcut commands for common operations.
| [gws-gmail-reply](../skills/gws-gmail-reply/SKILL.md) | Gmail: Reply to a message (handles threading automatically). |
| [gws-gmail-reply-all](../skills/gws-gmail-reply-all/SKILL.md) | Gmail: Reply-all to a message (handles threading automatically). |
| [gws-gmail-forward](../skills/gws-gmail-forward/SKILL.md) | Gmail: Forward a message to new recipients. |
| [gws-gmail-read](../skills/gws-gmail-read/SKILL.md) | Gmail: Read a message and extract its body or headers. |
| [gws-gmail-watch](../skills/gws-gmail-watch/SKILL.md) | Gmail: Watch for new emails and stream them as NDJSON. |
| [gws-calendar-insert](../skills/gws-calendar-insert/SKILL.md) | Google Calendar: Create a new event. |
| [gws-calendar-agenda](../skills/gws-calendar-agenda/SKILL.md) | Google Calendar: Show upcoming events across all calendars. |
Expand Down
6 changes: 4 additions & 2 deletions skills/gws-gmail-forward/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ gws gmail +forward --message-id <ID> --to <EMAILS>
| `--message-id` | ✓ | — | Gmail message ID to forward |
| `--to` | ✓ | — | Recipient email address(es), comma-separated |
| `--from` | — | — | Sender address (for send-as/alias; omit to use account default) |
| `--body` | — | — | Optional note to include above the forwarded message (plain text, or HTML with --html) |
| `--cc` | — | — | CC email address(es), comma-separated |
| `--bcc` | — | — | BCC email address(es), comma-separated |
| `--body` | — | — | Optional note to include above the forwarded message (plain text, or HTML with --html) |
| `--html` | — | — | Send as HTML (formats forwarded block with Gmail styling; treat --body as HTML) |
| `--html` | — | — | Treat --body as HTML content (default is plain text) |
| `--dry-run` | — | — | Show the request that would be sent without executing it |

## Examples
Expand All @@ -48,6 +48,8 @@ gws gmail +forward --message-id 18f1a2b3c4d --to dave@example.com --body '<p>FYI
## Tips

- Includes the original message with sender, date, subject, and recipients.
- With --html, the forwarded block uses Gmail's gmail_quote CSS classes and preserves HTML formatting. Use fragment tags (<p>, <b>, <a>, etc.) — no <html>/<body> wrapper needed.
- With --html, inline images in the forwarded message (cid: references) will appear broken. Externally hosted images are unaffected.

## See Also

Expand Down
51 changes: 51 additions & 0 deletions skills/gws-gmail-read/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
name: gws-gmail-read
version: 1.0.0
description: "Gmail: Read a message and extract its body or headers."
metadata:
openclaw:
category: "productivity"
requires:
bins: ["gws"]
cliHelp: "gws gmail +read --help"
---

# gmail +read

> **PREREQUISITE:** Read `../gws-shared/SKILL.md` for auth, global flags, and security rules. If missing, run `gws generate-skills` to create it.

Read a message and extract its body or headers

## Usage

```bash
gws gmail +read --id <ID>
```

## Flags

| Flag | Required | Default | Description |
|------|----------|---------|-------------|
| `--id` | ✓ | — | The Gmail message ID to read |
| `--headers` | — | — | Include headers (From, To, Subject, Date) in the output |
| `--format` | — | text | Output format (text, json) |
| `--html` | — | — | Return HTML body instead of plain text |
| `--dry-run` | — | — | Show the request that would be sent without executing it |

## Examples

```bash
gws gmail +read --id 18f1a2b3c4d
gws gmail +read --id 18f1a2b3c4d --headers
gws gmail +read --id 18f1a2b3c4d --format json | jq '.body'
```

## Tips

- Converts HTML-only messages to plain text automatically.
- Handles multipart/alternative and base64 decoding.

## See Also

- [gws-shared](../gws-shared/SKILL.md) — Global flags and auth
- [gws-gmail](../gws-gmail/SKILL.md) — All send, read, and manage email commands
8 changes: 5 additions & 3 deletions skills/gws-gmail-reply-all/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ gws gmail +reply-all --message-id <ID> --body <TEXT>
| `--body` | ✓ | — | Reply body (plain text, or HTML with --html) |
| `--from` | — | — | Sender address (for send-as/alias; omit to use account default) |
| `--to` | — | — | Additional To email address(es), comma-separated |
| `--cc` | — | — | Additional CC email address(es), comma-separated |
| `--cc` | — | — | CC email address(es), comma-separated |
| `--bcc` | — | — | BCC email address(es), comma-separated |
| `--remove` | — | — | Exclude recipients from the outgoing reply (comma-separated emails) |
| `--html` | — | — | Send as HTML (quotes original with Gmail styling; treat --body as HTML) |
| `--html` | — | — | Treat --body as HTML content (default is plain text) |
| `--dry-run` | — | — | Show the request that would be sent without executing it |
| `--remove` | — | — | Exclude recipients from the outgoing reply (comma-separated emails) |

## Examples

Expand All @@ -55,6 +55,8 @@ gws gmail +reply-all --message-id 18f1a2b3c4d --body '<i>Noted</i>' --html
- Use --bcc for recipients who should not be visible to others.
- Use --remove to exclude recipients from the outgoing reply, including the sender or Reply-To target.
- The command fails if no To recipient remains after exclusions and --to additions.
- With --html, the quoted block uses Gmail's gmail_quote CSS classes and preserves HTML formatting. Use fragment tags (<p>, <b>, <a>, etc.) — no <html>/<body> wrapper needed.
- With --html, inline images in the quoted message (cid: references) will appear broken. Externally hosted images are unaffected.

## See Also

Expand Down
6 changes: 4 additions & 2 deletions skills/gws-gmail-reply/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ gws gmail +reply --message-id <ID> --body <TEXT>
| `--body` | ✓ | — | Reply body (plain text, or HTML with --html) |
| `--from` | — | — | Sender address (for send-as/alias; omit to use account default) |
| `--to` | — | — | Additional To email address(es), comma-separated |
| `--cc` | — | — | Additional CC email address(es), comma-separated |
| `--cc` | — | — | CC email address(es), comma-separated |
| `--bcc` | — | — | BCC email address(es), comma-separated |
| `--html` | — | — | Send as HTML (quotes original with Gmail styling; treat --body as HTML) |
| `--html` | — | — | Treat --body as HTML content (default is plain text) |
| `--dry-run` | — | — | Show the request that would be sent without executing it |

## Examples
Expand All @@ -49,6 +49,8 @@ gws gmail +reply --message-id 18f1a2b3c4d --body '<b>Bold reply</b>' --html

- Automatically sets In-Reply-To, References, and threadId headers.
- Quotes the original message in the reply body.
- With --html, the quoted block uses Gmail's gmail_quote CSS classes and preserves HTML formatting. Use fragment tags (<p>, <b>, <a>, etc.) — no <html>/<body> wrapper needed.
- With --html, inline images in the quoted message (cid: references) will appear broken. Externally hosted images are unaffected.
- --to adds extra recipients to the To field.
- For reply-all, use +reply-all instead.

Expand Down
12 changes: 9 additions & 3 deletions skills/gws-gmail-send/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ gws gmail +send --to <EMAILS> --subject <SUBJECT> --body <TEXT>
| `--to` | ✓ | — | Recipient email address(es), comma-separated |
| `--subject` | ✓ | — | Email subject |
| `--body` | ✓ | — | Email body (plain text, or HTML with --html) |
| `--from` | — | — | Sender address (for send-as/alias; omit to use account default) |
| `--attachment` | — | — | Attach a file (can be repeated for multiple files) |
| `--cc` | — | — | CC email address(es), comma-separated |
| `--bcc` | — | — | BCC email address(es), comma-separated |
| `--html` | — | — | Treat --body as HTML content (default is plain text) |
Expand All @@ -39,14 +41,18 @@ gws gmail +send --to <EMAILS> --subject <SUBJECT> --body <TEXT>
```bash
gws gmail +send --to alice@example.com --subject 'Hello' --body 'Hi Alice!'
gws gmail +send --to alice@example.com --subject 'Hello' --body 'Hi!' --cc bob@example.com
gws gmail +send --to alice@example.com --subject 'Hello' --body 'Hi!' --bcc secret@example.com
gws gmail +send --to alice@example.com --subject 'Report' --body 'See attached.' --attachment ./report.pdf
gws gmail +send --to alice@example.com --subject 'Docs' --body 'Files attached.' --attachment a.pdf --attachment b.pdf
gws gmail +send --to alice@example.com --subject 'Hello' --body '<b>Bold</b> text' --html
gws gmail +send --to alice@example.com --subject 'Hello' --body 'Hi!' --from alias@example.com
```

## Tips

- Handles RFC 2822 formatting and base64 encoding automatically.
- For attachments, use the raw API instead: gws gmail users messages send --json '...'
- Handles RFC 5322 formatting, MIME encoding, and base64 automatically.
- Use --from to send from a configured send-as alias instead of your primary address.
- File MIME types are auto-detected from extensions (PDF, DOCX, PNG, etc.).
- With --html, use fragment tags (<p>, <b>, <a>, <br>, etc.) — no <html>/<body> wrapper needed.

> [!CAUTION]
> This is a **write** command — confirm with the user before executing.
Expand Down
1 change: 1 addition & 0 deletions skills/gws-gmail/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ gws gmail <resource> <method> [flags]
| [`+reply`](../gws-gmail-reply/SKILL.md) | Reply to a message (handles threading automatically) |
| [`+reply-all`](../gws-gmail-reply-all/SKILL.md) | Reply-all to a message (handles threading automatically) |
| [`+forward`](../gws-gmail-forward/SKILL.md) | Forward a message to new recipients |
| [`+read`](../gws-gmail-read/SKILL.md) | Read a message and extract its body or headers |
| [`+watch`](../gws-gmail-watch/SKILL.md) | Watch for new emails and stream them as NDJSON |

## API Resources
Expand Down
Loading
Loading