Integration
Google Sheets integration for custom metrics
The AdOps Google Sheets integration is read-only. AdOps addresses one spreadsheet by file ID, one sheet by name, a lookup column matched against the campaign being evaluated, and a value column. Rows are held in memory for 2 minutes and mirrored to its own database as a fallback.
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.
In numbers
The figures behind this connection
- 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
The exchange
What AdOps reads, and what it writes.
Two lists, no summary in between. Anything absent from the write column is something AdOps cannot change in this system.
AdOps reads
Every field the engine requests, and nothing else.
- 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
Every change the engine is able to make.
- 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
Sample data 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.
Questions
Asked about this connection.
Direct answers, with the numbers attached.
How fresh is the number a rule reads from a Google Sheet?
A fetched row set is held in memory and served for as long as it is read at least once every 2 minutes; it is evicted and re-fetched only after 2 minutes pass with no read. In a large batch where hundreds of campaigns read the same sheet in quick succession, every campaign in that batch sees the same snapshot.
What happens if Google Sheets is unreachable?
AdOps falls back to the rows it last mirrored for that file ID and sheet name, so the rule keeps evaluating instead of failing. The same fallback applies when Google returns a permission or not-found error and a previous copy exists, which means a spreadsheet whose access was revoked can keep evaluating against the last known rows.
Does AdOps change my spreadsheet?
No. The integration is read-only. AdOps downloads the sheet's rows and never writes a cell, adds a row, renames a tab or creates a file. Nothing in the product edits a spreadsheet.
What does a custom metric actually compute?
It matches the first row whose lookup column equals the campaign ID and reads that row's value column as a number. A metric can hold more than one formula line, and the per-line results are added together.
How do I know the columns are right before saving a metric?
Saving reads the sheet first and checks that both the lookup column and the value column exist. If either is missing, AdOps refuses the save and shows a validation panel listing the columns it did find alongside a checklist of fixes.
Can several rules share one spreadsheet?
Yes. Rows are cached by file ID and sheet name rather than per rule, so many rules and many campaigns in one batch share a single read of the same sheet.
Try this connection on your own account.
Every integration on this page is included on every plan. Connect it, leave your first rule in draft, and read the log after the first run.