Skip to main content

Sheets

Server Source code Package

Google Sheets store with zero runtime dependencies. Uses raw fetch against the Sheets v4 REST API with built-in auth: Application Default Credentials (ADC) on Cloud Run / GKE, or explicit service account JWT for non-GCP environments.

Designed for demos and small-scale prototyping where the spreadsheet itself is the operator-facing UI for tweaking lookup data. Not a production CRM substitute.

Caveats and quotas (read first)

The Sheets API is rate-limited and slow. Wiring this store directly into a high-throughput pipeline burns quota in seconds.

  • Quota: 60 read requests / minute / user / project, 60 write requests / minute / user / project.
  • Latency: 200 to 800 ms per HTTP round-trip.
  • No internal cache: the package does NOT cache reads. Caching is the consumer's responsibility, see "Wiring with the core cache" below.
  • Concurrency: last writer wins on the same cell. There is no transactional getAndSet.
  • Single-writer model: if two pipeline instances both write to the same sheet, their keyToRow indexes diverge.
  • Demo and small-prototype grade only. Not a production CRM substitute.

Installation

Loading...
Loading...

Configuration

This store uses the standard store config wrapper (consent, data, env, id, ...). For the shared fields see store configuration. Package-specific fields live under config.settings and are listed below.

Settings

PropertyTypeDescriptionMore
id*stringSpreadsheet ID, the segment between /d/ and /edit in the URL
sheetstringSheet (tab) name within the spreadsheet
keystringColumn letter for keys (the lookup column)
valuestringColumn letter for values (JSON-serialized blob)
headerRowsintegerNumber of header rows to skip when reading the key column
credentialsstring | objectService account JSON (string or object). Omit for ADC on Cloud Run/GKE
* Required fields

Mapping

This package does not define custom rule-level settings. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.

Examples

Read with ADC

Read a value from the Sheets store using ADC, no credentials field needed on Cloud Run or GKE

Event
Out

Write with service account

Append or update a JSON value in the configured sheet using an explicit service account JSON

Event
Out

Wiring with the built-in cache

To absorb the Sheets quota, wire the store with the built-in cache via Flow.Store.cache. The cache is on by default with an in-memory tier and requires no extra store declaration:

Loading...

Use ttl: 5000 for demos (fast iteration), ttl: 60000 or higher for production-ish loads. Without a cache, every event hits Sheets directly and trips the 60 req/min quota in under one second.

The cache config lives at packages/core/src/types/cache.ts. See the understanding-stores skill for the broader store/cache pattern.

Provisioning

The package ships an idempotent setup() lifecycle, invoked only by the explicit operator command:

Loading...

It never runs automatically. It verifies the spreadsheet exists and (if configured) writes the setup.headers row.

Setup options

OptionTypeDefaultNotes
headersstring[](none)Header values written to row 1 of the configured sheet. Idempotent overwrite, no drift detect.

id is taken from settings.id and is NOT duplicated under setup.

Behavior

  • Existence probe: setup issues GET /spreadsheets/<id>?fields=spreadsheetId and throws an actionable error on 404.
  • Header write: when setup.headers is provided, setup issues PUT /values/<sheet>!A1:<lastCol>1?valueInputOption=RAW with the headers as the row values. Re-running with the same headers is a no-op overwrite.
  • No shareWith: Drive API integration is intentionally out of scope in this version (it requires a separate OAuth scope). Share the spreadsheet manually with the service account email before running setup.

Runtime hard-fail

The first call to init() issues a single GET /spreadsheets/<id>?fields=spreadsheetId per process per spreadsheet ID. On 404 it throws with an actionable message:

Loading...

Operators see the error pointing at the exact command to fix it. Subsequent calls in the same process skip the check via an in-memory cache.

Authentication

Cloud Run / GKE (ADC)

When running on GCP infrastructure, omit credentials. The store fetches access tokens from the metadata server automatically. Required OAuth scope: https://www.googleapis.com/auth/spreadsheets.

Non-GCP (service account)

Pass a service account JSON via $env. reference. The store signs JWTs locally using node:crypto and exchanges them for access tokens via Google's OAuth2 endpoint.

Loading...

The SHEETS_SA_KEY environment variable should contain the full service account JSON (with client_email and private_key fields). Share the spreadsheet with the service account email before running setup.

API

Loading...

Each value is JSON-stringified into one cell (the value column). Reads JSON-parse the cell back. A non-parseable cell logs a debug line and returns undefined.

set() for an unknown key appends a new row, capturing the row index from the API response. set() for a known key updates the existing value cell. delete() blanks the value cell, the row stays in place to keep keyToRow indexes stable.

Limitations

  • Single-cell value shape. Multi-column structured rows are out of scope, ship a richer schema in a later phase if customers ask.
  • No drift detection on header content. If an operator manually edits row 1, the next walkeros setup store.<id> overwrites it without warning.
  • No transactional updates. set is two HTTP calls (read index, write cell). Concurrent writers can interleave.
💡 Need implementation support?
elbwalker offers hands-on support: setup review, measurement planning, destination mapping, and live troubleshooting. Book a 2-hour session (€399)