Skip to content

Commit 9d937af

Browse files
authored
feat(gmail): add --html flag for HTML email composition (#417)
Add --html flag to +send, +reply, +reply-all, and +forward, enabling HTML email composition. When set, --body is treated as HTML content and the Content-Type switches from text/plain to text/html. For replies and forwards, the quoted/forwarded block matches Gmail web UI fidelity: gmail_quote_container class, gmail_sendername structure, mailto links in attribution and metadata, <div dir="ltr"> wrapper on quoted content, and RFC 2822 dates reformatted to Gmail's human-friendly style. When the original message has no HTML body, plain text is HTML-escaped with <br> line breaks as a fallback (with a stderr diagnostic).
1 parent 2df32ee commit 9d937af

9 files changed

Lines changed: 1183 additions & 223 deletions

File tree

.changeset/add-html-mode.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@googleworkspace/cli": minor
3+
---
4+
5+
Add `--html` flag to `+send`, `+reply`, `+reply-all`, and `+forward` for HTML email composition.

skills/gws-gmail-forward/SKILL.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ gws gmail +forward --message-id <ID> --to <EMAILS>
2424

2525
## Flags
2626

27-
| Flag | Required | Default | Description |
28-
|------|----------|---------|-------------|
29-
| `--message-id` ||| Gmail message ID to forward |
30-
| `--to` ||| Recipient email address(es), comma-separated |
31-
| `--from` ||| Sender address (for send-as/alias; omit to use account default) |
32-
| `--cc` ||| CC email address(es), comma-separated |
33-
| `--bcc` ||| BCC email address(es), comma-separated |
34-
| `--body` ||| Optional note to include above the forwarded message |
35-
| `--dry-run` ||| Show the request that would be sent without executing it |
27+
| Flag | Required | Default | Description |
28+
| -------------- | -------- | ------- | ----------------------------------------------------------------------------- |
29+
| `--message-id` ||| Gmail message ID to forward |
30+
| `--to` ||| Recipient email address(es), comma-separated |
31+
| `--from` ||| Sender address (for send-as/alias; omit to use account default) |
32+
| `--cc` ||| CC email address(es), comma-separated |
33+
| `--bcc` ||| BCC email address(es), comma-separated |
34+
| `--body` ||| Optional note above the forwarded message (plain text, or HTML with `--html`) |
35+
| `--html` ||| Treat `--body` as HTML content (default is plain text) |
36+
| `--dry-run` ||| Show the request that would be sent without executing it |
3637

3738
## Examples
3839

@@ -41,11 +42,14 @@ gws gmail +forward --message-id 18f1a2b3c4d --to dave@example.com
4142
gws gmail +forward --message-id 18f1a2b3c4d --to dave@example.com --body 'FYI see below'
4243
gws gmail +forward --message-id 18f1a2b3c4d --to dave@example.com --cc eve@example.com
4344
gws gmail +forward --message-id 18f1a2b3c4d --to dave@example.com --bcc secret@example.com
45+
gws gmail +forward --message-id 18f1a2b3c4d --to dave@example.com --body '<p>FYI</p>' --html
4446
```
4547

4648
## Tips
4749

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

5054
## See Also
5155

skills/gws-gmail-reply-all/SKILL.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,17 @@ gws gmail +reply-all --message-id <ID> --body <TEXT>
2424

2525
## Flags
2626

27-
| Flag | Required | Default | Description |
28-
|------|----------|---------|-------------|
29-
| `--message-id` ||| Gmail message ID to reply to |
30-
| `--body` ||| Reply body (plain text) |
31-
| `--from` ||| Sender address (for send-as/alias; omit to use account default) |
32-
| `--to` ||| Additional To email address(es), comma-separated |
33-
| `--cc` ||| Additional CC email address(es), comma-separated |
34-
| `--bcc` ||| BCC email address(es), comma-separated |
35-
| `--remove` ||| Exclude recipients from the outgoing reply (comma-separated emails) |
36-
| `--dry-run` ||| Show the request that would be sent without executing it |
27+
| Flag | Required | Default | Description |
28+
| -------------- | -------- | ------- | ------------------------------------------------------------------- |
29+
| `--message-id` ||| Gmail message ID to reply to |
30+
| `--body` ||| Reply body (plain text, or HTML if `--html` is set) |
31+
| `--from` ||| Sender address (for send-as/alias; omit to use account default) |
32+
| `--to` ||| Additional To email address(es), comma-separated |
33+
| `--cc` ||| Additional CC email address(es), comma-separated |
34+
| `--bcc` ||| BCC email address(es), comma-separated |
35+
| `--remove` ||| Exclude recipients from the outgoing reply (comma-separated emails) |
36+
| `--html` ||| Treat `--body` as HTML content (default is plain text) |
37+
| `--dry-run` ||| Show the request that would be sent without executing it |
3738

3839
## Examples
3940

@@ -43,16 +44,19 @@ gws gmail +reply-all --message-id 18f1a2b3c4d --body 'Updated' --remove bob@exam
4344
gws gmail +reply-all --message-id 18f1a2b3c4d --body 'Adding Eve' --cc eve@example.com
4445
gws gmail +reply-all --message-id 18f1a2b3c4d --body 'Adding Dave' --to dave@example.com
4546
gws gmail +reply-all --message-id 18f1a2b3c4d --body 'Reply' --bcc secret@example.com
47+
gws gmail +reply-all --message-id 18f1a2b3c4d --body '<i>Noted</i>' --html
4648
```
4749

4850
## Tips
4951

5052
- Replies to the sender and all original To/CC recipients.
51-
- Use --to to add extra recipients to the To field.
52-
- Use --cc to add new CC recipients.
53-
- Use --bcc for recipients who should not be visible to others.
54-
- Use --remove to exclude recipients from the outgoing reply, including the sender or Reply-To target.
55-
- The command fails if no To recipient remains after exclusions and --to additions.
53+
- Use `--to` to add extra recipients to the To field.
54+
- Use `--cc` to add new CC recipients.
55+
- Use `--bcc` for recipients who should not be visible to others.
56+
- Use `--remove` to exclude recipients from the outgoing reply, including the sender or Reply-To target.
57+
- The command fails if no To recipient remains after exclusions and `--to` additions.
58+
- With `--html`, the quoted block uses Gmail's `gmail_quote` CSS classes and preserves the original message's HTML formatting. Use HTML fragment tags (`<p>`, `<b>`, `<a>`, etc.) — no `<html>`/`<body>` wrapper needed.
59+
- With `--html`, inline images embedded in the quoted message (`cid:` references) will appear broken. Externally hosted images are unaffected.
5660

5761
## See Also
5862

skills/gws-gmail-reply/SKILL.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ gws gmail +reply --message-id <ID> --body <TEXT>
2424

2525
## Flags
2626

27-
| Flag | Required | Default | Description |
28-
|------|----------|---------|-------------|
29-
| `--message-id` ||| Gmail message ID to reply to |
30-
| `--body` ||| Reply body (plain text) |
31-
| `--from` ||| Sender address (for send-as/alias; omit to use account default) |
32-
| `--to` ||| Additional To email address(es), comma-separated |
33-
| `--cc` ||| Additional CC email address(es), comma-separated |
34-
| `--bcc` ||| BCC email address(es), comma-separated |
35-
| `--dry-run` ||| Show the request that would be sent without executing it |
27+
| Flag | Required | Default | Description |
28+
| -------------- | -------- | ------- | --------------------------------------------------------------- |
29+
| `--message-id` ||| Gmail message ID to reply to |
30+
| `--body` ||| Reply body (plain text, or HTML if `--html` is set) |
31+
| `--from` ||| Sender address (for send-as/alias; omit to use account default) |
32+
| `--to` ||| Additional To email address(es), comma-separated |
33+
| `--cc` ||| Additional CC email address(es), comma-separated |
34+
| `--bcc` ||| BCC email address(es), comma-separated |
35+
| `--html` ||| Treat `--body` as HTML content (default is plain text) |
36+
| `--dry-run` ||| Show the request that would be sent without executing it |
3637

3738
## Examples
3839

@@ -41,14 +42,17 @@ gws gmail +reply --message-id 18f1a2b3c4d --body 'Thanks, got it!'
4142
gws gmail +reply --message-id 18f1a2b3c4d --body 'Looping in Carol' --cc carol@example.com
4243
gws gmail +reply --message-id 18f1a2b3c4d --body 'Adding Dave' --to dave@example.com
4344
gws gmail +reply --message-id 18f1a2b3c4d --body 'Reply' --bcc secret@example.com
45+
gws gmail +reply --message-id 18f1a2b3c4d --body '<b>Bold reply</b>' --html
4446
```
4547

4648
## Tips
4749

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

5357
## See Also
5458

skills/gws-gmail-send/SKILL.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,30 @@ gws gmail +send --to <EMAILS> --subject <SUBJECT> --body <TEXT>
2424

2525
## Flags
2626

27-
| Flag | Required | Default | Description |
28-
|------|----------|---------|-------------|
29-
| `--to` ||| Recipient email address(es), comma-separated |
30-
| `--subject` ||| Email subject |
31-
| `--body` ||| Email body (plain text) |
32-
| `--cc` ||| CC email address(es), comma-separated |
33-
| `--bcc` ||| BCC email address(es), comma-separated |
34-
| `--dry-run` ||| Show the request that would be sent without executing it |
27+
| Flag | Required | Default | Description |
28+
| ----------- | -------- | ------- | -------------------------------------------------------- |
29+
| `--to` ||| Recipient email address(es), comma-separated |
30+
| `--subject` ||| Email subject |
31+
| `--body` ||| Email body (plain text, or HTML if `--html` is set) |
32+
| `--cc` ||| CC email address(es), comma-separated |
33+
| `--bcc` ||| BCC email address(es), comma-separated |
34+
| `--html` ||| Treat `--body` as HTML content (default is plain text) |
35+
| `--dry-run` ||| Show the request that would be sent without executing it |
3536

3637
## Examples
3738

3839
```bash
3940
gws gmail +send --to alice@example.com --subject 'Hello' --body 'Hi Alice!'
4041
gws gmail +send --to alice@example.com --subject 'Hello' --body 'Hi!' --cc bob@example.com
4142
gws gmail +send --to alice@example.com --subject 'Hello' --body 'Hi!' --bcc secret@example.com
43+
gws gmail +send --to alice@example.com --subject 'Hello' --body '<b>Bold</b> text' --html
4244
```
4345

4446
## Tips
4547

4648
- Handles RFC 2822 formatting and base64 encoding automatically.
47-
- For HTML bodies or attachments, use the raw API instead: gws gmail users messages send --json '...'
49+
- With `--html`, the `--body` value should be HTML content, not a full document. Use tags like `<p>`, `<b>`, `<i>`, `<a href="...">`, `<br>`, `<ul>/<ol>/<li>`, `<table>`. No need for `<html>`/`<head>`/`<body>` wrappers.
50+
- For attachments, use the raw API instead: gws gmail users messages send --json '...'
4851

4952
> [!CAUTION]
5053
> This is a **write** command — confirm with the user before executing.

0 commit comments

Comments
 (0)