Gmail Filter Tooling — Change Log

What changed, why, and how to use it going forward.

Account affected: leeweisern@gmail.com  ·  Host: this VPS  ·  google-workspace CLI v1.0.0 → v1.1.0

The problem

ZALORA promotional emails kept landing in your inbox despite having filters for them. Investigation found ~10 separate ZALORA filters, nearly all matching the exact address noreply@em.zalora.com.my — several of them redundant or conflicting (some trashed, some archived, some labelled). Exact full-address matching is fragile: senders rotate subdomains and addresses, so mail slips through.

1. Immediate fix (your mailbox)

Done directly via the Gmail API and verified live:

Also set up earlier in the session — Time internet bill

Created a Bills label (Label_51) and a filter on time.com.my → label Bills + skip Inbox. The current Time bill (RM145.20, due 09 Jun) was filed under Bills and removed from the inbox.

2. CLI updated — google-workspace v1.1.0

The CLI previously had no way to read or write Gmail filters — that work required hand-written curl calls through the broker proxy. I added five new commands so it's first-class going forward. File: ~/.hermes/tools/google-workspace.

CommandWhat it doesTested
gmail-filters-list <email>List all filters with their IDs, criteria & actions✅ returned 142
gmail-labels-list <email>List labels with their Label_ IDs✅ found Bills
gmail-filter-create <email>Create a filter — --from/--to/--subject/--query + --add/--remove✅ created
gmail-filter-delete <email> <id>Delete a filter by ID✅ deleted
gmail-modify <email> --ids …Archive/label existing messages (batchModify)✅ via flow

Create & delete were tested as a full round-trip on a throwaway filter (create → capture ID → delete → confirm). Syntax validated with bun build.

Usage examples

# See every filter (with IDs you can delete by)
google-workspace gmail-filters-list leeweisern@gmail.com

# The robust fix pattern: domain-level, not exact-address
google-workspace gmail-filter-create leeweisern@gmail.com \
  --from zalora.com.my --remove INBOX,UNREAD

# Route a bill to a label and out of the inbox
google-workspace gmail-filter-create leeweisern@gmail.com \
  --from noreply@time.com.my --add Label_51 --remove INBOX

# Archive/label messages already sitting in the inbox
google-workspace gmail-modify leeweisern@gmail.com \
  --ids 19e8...,19e7... --remove INBOX,UNREAD

# Remove a filter
google-workspace gmail-filter-delete leeweisern@gmail.com <filterId>

Label semantics: INBOX = inbox · UNREAD = unread · TRASH = trash · SPAM = spam. Archive = remove INBOX. Mark read = remove UNREAD.

3. Skill updated — gmail

Added a Filters and labels section to the gmail skill documenting the new commands, plus two durable lessons so this knowledge survives:

Net effect

Next time you ask to manage Gmail filters, I run a single CLI command instead of hand-crafting API calls — faster, less error-prone, and the approach is documented so it stays consistent.

Still open — your call

Generated by Hermes · changes applied and verified against the live account before this page was written.