rfq-triage
Pulls one unprocessed RFQ email per scheduled run, files attachments to a per-RFQ Drive folder, has Claude extract customer/qty/material/processes/due/urgency from the message body, appends a row to a Sheets quote log, auto-replies to the customer in-thread with a reference number, notifies the estimator, and relabels the message.
Use case
A small machine shop receives RFQs by email. Without automation, someone has to read each one, save the drawings somewhere sensible, type the customer + qty + due date into the quote tracker, send an acknowledgment, and forward it to the estimator. This workflow does all of it. Schedule it every 5 minutes; backlog catches up automatically.
Setup
- Credentials (Credentials view):
-
google-workspace— Google Workspace service-account JSON with domain-wide delegation -claude-api— Anthropic API key - Runtime environment (Runtime Environments view):
-
bash— InTouch auto-creates this on Linux/macOS install from/bin/bash. Must includebash,awk,grep,cut,tr,mktemp,date,python3, and thegogCLI on PATH. - Windows: InTouch auto-createspowershellandcommand promptinstead. To run this workflow on Windows: install Git Bash or WSL and add abashruntime env in InTouch pointing at it (e.g.C:\Program Files\Git\bin\bash.exe), OR changeruntimeEnvName: "bash"to"powershell"inworkflow.yamland rewrite thescriptblocks in PowerShell. - Gmail prep:
- Create label
RFQ- Create labelprocessed- Create a filter that auto-appliesRFQto inbound customer RFQ emails (by sender domain, byquote request/RFQin subject, or by forwarding from[email protected]) - Drive prep:
- Create a parent folder for RFQs (any name)
- Copy its folder ID from the URL:
https://drive.google.com/drive/folders/<THIS_IS_THE_ID> - Sheets prep:
- Create a sheet with tab
QuoteLogand 11 columns:ref_id | received_at | customer | from_email | project | qty | material | processes | due_date | urgency | status- Copy the spreadsheet ID from the URL - Edit
workflow.yaml— replace the four placeholders: -<<RFQ_LABEL>>→RFQ-<<RFQ_PARENT_FOLDER_ID>>→ the Drive folder ID -<<QUOTE_LOG_SHEET_ID>>→ the Sheet ID -<<ESTIMATOR_EMAIL>>→ the internal estimator's email -<<SHOP_NAME>>→ company name for the auto-reply signature - Schedule the workflow every 5 minutes
Pipeline
- intake —
runtimeenv(bash + gog). Finds the oldest message labeledRFQwithoutprocessed, fetches it as--format full --plainTSV, parses headers + body + attachment rows, creates a dated subfolder under the RFQ parent, downloads each attachment and re-uploads it to Drive, emits a JSON blob. - extract —
anthropic(claude-sonnet-4-6). Parses the JSON blob into structured fields: customer, project, qty, material, processes, due, urgency, complexity. Returns strict JSON. - dispatch —
runtimeenv(bash + gog + python3). Appends a row to the Sheets quote log, sends an in-thread auto-reply to the customer with aRFQ-YYYYMMDD-HHMMSSreference, sends a separate digest to the estimator, then appliesprocessedand removesRFQon the original message.
If intake finds no new RFQ, the rest of the pipeline exits cleanly with no Sheets write, no emails, no API spend beyond one Anthropic call to confirm "empty."
What runs per scheduled fire
gmail messages search "label:RFQ -label:processed" --max 1
↓ message ID
gmail get --format full --plain
↓ headers + body + attachments
drive mkdir <date>_<subject> --parent <RFQs folder ID>
↓ subfolder ID
gmail attachment + drive upload (per attachment)
↓ JSON blob (message_id, thread_id, from, subject, body, folder, attachments[])
anthropic extract
↓ structured RFQ fields
sheets append QuoteLog!A:K <11 values>
gmail send --thread-id <thread> (customer reply)
gmail send (estimator notification)
gmail messages modify --add processed --remove RFQ
Customization
- Schedule cadence — every 5 min for active shops, hourly for quieter ones; cost is one Anthropic call per fire regardless of whether there's work
- Auto-reply wording — edit the
--bodyof the customer-facinggmail sendin thedispatchtask - Estimator digest format — same task, second
gmail sendcall - Sheet columns — if you change the QuoteLog column layout, update the
sheets appendvalue list and the column count in the range (QuoteLog!A:K→A:Netc.) - AI provider — swap
anthropicforopenai,gemini, orollamatask types; same prompt works - Reference ID format — currently
RFQ-YYYYMMDD-HHMMSS; edit theREF_ID=line indispatch - Multiple intake labels — change the search query in
intaketo OR multiple labels ("(label:RFQ OR label:quote) -label:processed")
Verified
The gog flag names (--parent, --out, --thread-id, --add/--remove, --reply-to-message-id) are all confirmed against the bundled gog v0.19.0 (2026-06-01). The gmail get --plain TSV shape and the drive upload/mkdir --plain output keys should be re-verified on first run against your Workspace account. If the bundled gog ever moves to a new major version, re-verify before promoting.
Source
See workflow.yaml.