Skip to content

Feature: Add --attachment flag to gmail +send helper #498

@alimpolat

Description

@alimpolat

Problem

The gmail +send helper currently supports --to, --subject, --body, --cc, --bcc, and --html flags, but has no support for file attachments. The help text suggests using the raw API instead:

TIPS: For attachments, use the raw API instead: gws gmail users messages send --json '...'

However, this workaround has a critical limitation: the entire MIME message (including base64-encoded file contents) must be passed as a command-line argument. On Windows, this hits the ~32,000 character limit (ERROR: Argument list too long), making it impossible to send even a single small PDF attachment via the raw API.

This also affects Linux/macOS systems with the default ARG_MAX limit when sending larger files.

Real-world use case

I needed to send emails with PDF attachments (legal filings to a court) using gws as part of a CLI automation pipeline. The workflow:

  1. Generate PDF documents programmatically
  2. Send them as email attachments to specific recipients

The +send helper was perfect for the text part, but I had to fall back to Python's google-api-python-client to handle attachments — defeating the purpose of having a unified CLI tool.

Proposed solution

Add a --attachment <PATH> flag to gws gmail +send that can be specified multiple times:

# Single attachment
gws gmail +send --to recipient@example.com --subject "Report" --body "See attached." --attachment ./report.pdf

# Multiple attachments
gws gmail +send --to recipient@example.com --subject "Documents" --body "See attached." \
  --attachment ./doc1.pdf \
  --attachment ./doc2.pdf

Implementation notes

  • Read the file(s) from disk and build the MIME multipart message internally (in Rust), avoiding command-line length limits entirely
  • Auto-detect MIME type from file extension (or default to application/octet-stream)
  • Use the filename as the attachment name by default, with an optional --attachment-name override
  • The Gmail API accepts the full MIME message as base64url-encoded raw field — the current +send already constructs this for text-only messages, so this extends that logic

Alternative considered

Supporting @file syntax for --json (like curl's @filename) would also solve the command-line length issue for the raw API approach. But a dedicated --attachment flag is more user-friendly and consistent with the helper's design philosophy of abstracting away RFC 2822 formatting.

Environment

  • gws version: 0.16.0
  • OS: Windows 11 (where the issue is most severe due to lower argument length limits)
  • Also reproducible on Linux/macOS with larger attachments

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions