# Google Sheets

> Read-only access to one spreadsheet by ID, sheet name, lookup column and value column, so a rule can compare Meta metrics against numbers a person maintains.

Source: https://adops.id/integrations/google-sheets/
Last updated: 2026-08-20
Publisher: AdOps (https://adops.id) — an independent product, not affiliated with Meta Platforms, Inc.

---

## Key facts

- **In-memory cache window:** 2 minutes since the row set was last read (The window is measured from the last read, not from the fetch, so a set read continuously stays in memory.)
- **Mirror refresh stamp:** 2 minutes after a CSV-export fetch, 5 minutes after the Sheets API fallback
- **CSV download timeout:** 30 seconds
- **Fetch order:** CSV export first, the Sheets API client second, the database mirror last
- **Access:** A Google service account holding the Drive and Spreadsheets scopes
- **Where a custom metric can be used:** Condition metric, comparison metric, budget amount and campaign-name token

**AdOps reads:** One spreadsheet, addressed by the file ID taken from its URL; One sheet inside that spreadsheet, addressed by sheet name; A lookup column, matched against the campaign ID currently being evaluated; A value column, read from the first row whose lookup column matches; The sheet's full row set, downloaded as CSV from Google's export endpoint with a 30-second timeout; The sheet's internal gid, resolved once per sheet name and then cached

**AdOps writes:** Nothing. AdOps never writes a cell, a row, a sheet or a file back to Google Sheets; The only persistence happens inside AdOps: fetched rows are mirrored into its own database, keyed uniquely by file ID and sheet name

AdOps reads Google Sheets so a rule can act on numbers Meta never sees. A custom metric stores a spreadsheet ID, a sheet name, a lookup column and a value column; during evaluation AdOps matches the first row whose lookup column equals the campaign ID and reads that row's value column as the metric's value.

## What is this integration actually for?

Target ROAS by product line, a real margin per SKU, a stock level, an offline revenue figure, a fee table. These live in a back-office spreadsheet that somebody already maintains, and Meta has no idea they exist. Binding one to a custom metric lets a rule compare a live Meta metric against it, so an automation can pause a campaign whose Purchase ROAS has fallen below the target that particular product needs, rather than below a single number hard-coded across the whole account.

Once defined, a custom metric behaves like any other metric in the builder. It can be the left side of a condition, the metric another condition is compared against, the amount a budget action writes, and a token inside a campaign-name template.

## How does AdOps fetch a sheet?

Three layers, tried in order. First the direct CSV export endpoint, with a 30-second timeout, parsed by a quote-aware reader that keeps commas inside quoted cells, handles doubled quotes, trims header names and discards any row whose column count does not match the header, so a ragged export cannot shift values into the wrong columns. If that fails, AdOps retries through the Google Sheets client, authenticated with a Google service account holding the Drive and Spreadsheets scopes. If Google is unreachable altogether, AdOps serves the rows it last mirrored into its own database.

Fetched rows are cached in memory under the file ID and sheet name. The entry is served while it is read at least once every 2 minutes and is evicted after 2 minutes with no read, which means one batch of several hundred campaigns pointed at the same sheet costs a single download. The persisted mirror is stamped for refresh 2 minutes after a CSV fetch and 5 minutes after the slower API fallback.

## What are the limits worth knowing?

Two, stated plainly. The cache window is measured from the last read, so a sheet under continuous access is not re-downloaded on a fixed schedule: a rule running back-to-back sees one snapshot for the length of the batch. And because the database mirror is the last fallback, an error from Google is not always visible to the rule. If access to the spreadsheet is revoked but a previous copy exists, evaluation continues against the last known rows instead of stopping.

A custom metric also reads a single row per formula line, the first one whose lookup column matches, rather than summing every matching row. If a lookup value appears twice in the sheet, only the first occurrence is read.

## How is a metric set up?

In Custom Metrics, create a metric with a name, an optional description and the Google Spreadsheet ID from the sheet's URL, then choose Google Sheets as the data source and fill in the sheet name, the lookup column and the value column. Saving validates against the live sheet: if a column name does not exist, the save is refused and AdOps lists the columns it found.
