# **AI Google Sheets Monitoring** (`dtrungtin/ai-google-sheets-monitoring`) Actor

Scrape recipes from Allrecipes with ingredients and directions. This easy-to-use actor gets you an Allrecipes dataset in different formats according to your needs.

- **URL**: https://apify.com/dtrungtin/ai-google-sheets-monitoring.md
- **Developed by:** [Tin](https://apify.com/dtrungtin) (community)
- **Categories:** AI, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Google Sheets URL Monitor

### What does Google Sheets URL Monitor do?

**Google Sheets URL Monitor** turns a plain [Google Sheet](https://docs.google.com/spreadsheets/) into a **no-code web monitoring dashboard**. It reads the URLs listed in your sheet's `URL` column, visits each page in a real browser, extracts the values you care about (prices, titles, star counts — anything you can point a CSS selector at), and **writes the fresh values straight back into the sheet**, stamping an `UPDATED` column with the time of the last check.

Because it runs on the [Apify platform](https://apify.com), you get scheduling, API access, proxy rotation, monitoring, and integrations (Slack, email, webhooks) out of the box.

### Why use Google Sheets URL Monitor?

- **Track prices** of products on e-commerce sites (eBay, Amazon, any shop) directly in a spreadsheet.
- **Watch competitors** — headlines, product names, availability.
- **Monitor GitHub repos** — stars, watchers, releases.
- **No code, no database** — the spreadsheet is both the configuration and the output. Add a row, get data.
- **Schedule it** — run hourly or daily with Apify Schedules and always have fresh numbers in your sheet.

### How does the spreadsheet work?

The sheet itself defines what gets scraped:

| Column header                                    | Meaning                                                                              |
| ------------------------------------------------ | ------------------------------------------------------------------------------------ |
| `URL`                                            | The page to visit (one per row).                                                     |
| Any CSS selector, e.g. `.x-price-primary > span` | The text of the first matching element on that row's page is written into this cell. |
| A plain field name, e.g. `Price`                 | Extracted from the page text by AI (requires an OpenAI API key). No selector needed. |
| `UPDATED`                                        | Receives the date and time of the last successful check (UTC).                       |

A header counts as a CSS selector when it contains selector syntax (`.`, `#`, `[]`, `>`, `+`, `~`, `:`) or consists only of HTML tag names (`h1`, `td strong`). Anything else — `Price`, `Product Name`, `Stars` — is treated as an AI-extracted field.

The AI prompt can even **create new columns**: if your `aiPrompt` asks for extra fields (e.g. _"add a DiscountPercentage column"_), the Actor appends them as new columns at the end of the sheet and fills them — on later runs they behave like regular AI columns.

Selectors that don't match a page (e.g. an eBay price selector on a GitHub row) simply leave the cell empty — so one sheet can mix many different sites.

### How to use Google Sheets URL Monitor

1. Create a Google Sheet with a `URL` column, one or more CSS selector columns, and optionally an `UPDATED` column.
2. Create a [Google Cloud service account](https://cloud.google.com/iam/docs/service-accounts-create), enable the **Google Sheets API**, and download its JSON key.
3. Share the spreadsheet with the service account's `client_email` as an **Editor**.
4. Paste the spreadsheet URL and the JSON key into the Actor input and click **Start**.
5. Watch the values and timestamps appear in your sheet. Add an [Apify Schedule](https://docs.apify.com/platform/schedules) to keep them fresh automatically.

> **Tip:** No service account yet? Just share the sheet as "Anyone with the link can view" and run the Actor without a key — it runs in **read-only mode**, storing extracted values in the dataset so you can verify your selectors before enabling write-back.

### Input

| Field                     | Description                                                                                                                                                                                                                                                                                        |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spreadsheetUrl`          | Full URL of the Google Sheet to monitor (required). Row 1 must contain a `URL` column; every other header is a CSS selector or an AI-extracted field name.                                                                                                                                         |
| `googleServiceAccountKey` | Contents of the Google service account JSON key file (secret). The sheet must be shared with the service account's email as an **Editor**. Falls back to the `GOOGLE_SERVICE_ACCOUNT_KEY` environment variable; without either, the Actor runs in read-only mode (results go to the dataset only). |
| `aiPrompt`                | Optional instructions guiding the AI columns: value formats, language, disambiguation rules (e.g. _"Price is the current selling price only"_), and even new columns to add (e.g. _"add a DiscountPercentage column when the page shows a discount"_).                                             |

Further advanced options (OpenAI model, concurrency, retries, delays, proxy) are available on the Actor's Input tab.

### Output

Every processed row is also stored in the dataset. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
{
    "url": "https://www.ebay.com/itm/335522548886",
    "rowNumber": 3,
    "data": {
        ".x-item-title__mainTitle": "Size 9 - Nike Air Jordan Pro Strong Playoff",
        ".x-price-primary > span": "US $109.19",
        ".article-heading": null
    },
    "error": null,
    "updatedAt": "2026-07-18T09:12:45.000Z"
}
````

| Field       | Description                                                              |
| ----------- | ------------------------------------------------------------------------ |
| `url`       | The monitored page.                                                      |
| `rowNumber` | 1-based row number in the sheet.                                         |
| `data`      | Extracted text per CSS selector (`null` when the selector didn't match). |
| `error`     | Error message if the page failed to load, otherwise `null`.              |
| `updatedAt` | ISO timestamp of the check.                                              |

### How much does it cost to monitor URLs from a Google Sheet?

Each row opens one page in a headless Chrome browser. A run over a few dozen rows typically consumes only a fraction of a compute unit, which fits comfortably within Apify's free tier. Costs scale linearly with the number of rows and how often you schedule the Actor.

### Tips and advanced options

- **Bot-protected sites** (eBay, Amazon): enable residential proxies in the Actor input to avoid blocks.
- **Slow, JavaScript-heavy pages**: increase the selector timeout in the Actor input.
- **Broken selector?** A previously working cell coming back empty usually means the site changed its markup — update the column header.
- Failed pages are logged and left untouched in the sheet, so a temporary outage never wipes your data.

### FAQ, disclaimers, and support

Scraping publicly available data is generally legal, but you are responsible for complying with the target websites' Terms of Service and applicable laws. Do not use this Actor to collect personal data.

Found a bug or need a feature? Open an issue on the Actor's **Issues** tab. For custom monitoring solutions, feel free to reach out.

# Actor input Schema

## `spreadsheetUrl` (type: `string`):

Full URL of the Google Sheet to monitor. Row 1 must be a header row containing a column named <code>URL</code>. Every other non-empty header is either a CSS selector whose extracted text is written into that column, or a plain field name (e.g. <code>Price</code>) that is extracted by AI when an OpenAI API key is provided.

## `aiPrompt` (type: `string`):

Optional instructions guiding how the AI fills the plain-name columns, e.g. <code>Price must be a plain number without currency symbols. Availability is either 'In stock' or 'Out of stock'. Answer in English.</code>

## Actor input object example

```json
{
  "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/1AzIBAKF-_Bv2XRv1wT8SU9yUozdAYOP2JgTASjK7vXo/edit?gid=0#gid=0",
  "aiPrompt": "Price must be a plain number without currency symbols. Answer in English."
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/1AzIBAKF-_Bv2XRv1wT8SU9yUozdAYOP2JgTASjK7vXo/edit?gid=0#gid=0",
    "aiPrompt": "Price must be a plain number without currency symbols. Answer in English."
};

// Run the Actor and wait for it to finish
const run = await client.actor("dtrungtin/ai-google-sheets-monitoring").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/1AzIBAKF-_Bv2XRv1wT8SU9yUozdAYOP2JgTASjK7vXo/edit?gid=0#gid=0",
    "aiPrompt": "Price must be a plain number without currency symbols. Answer in English.",
}

# Run the Actor and wait for it to finish
run = client.actor("dtrungtin/ai-google-sheets-monitoring").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "spreadsheetUrl": "https://docs.google.com/spreadsheets/d/1AzIBAKF-_Bv2XRv1wT8SU9yUozdAYOP2JgTASjK7vXo/edit?gid=0#gid=0",
  "aiPrompt": "Price must be a plain number without currency symbols. Answer in English."
}' |
apify call dtrungtin/ai-google-sheets-monitoring --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dtrungtin/ai-google-sheets-monitoring",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "**AI Google Sheets Monitoring**",
        "description": "Scrape recipes from Allrecipes with ingredients and directions. This easy-to-use actor gets you an Allrecipes dataset in different formats according to your needs.",
        "version": "0.0",
        "x-build-id": "GWgKMlXKL33yydl2i"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dtrungtin~ai-google-sheets-monitoring/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dtrungtin-ai-google-sheets-monitoring",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/dtrungtin~ai-google-sheets-monitoring/runs": {
            "post": {
                "operationId": "runs-sync-dtrungtin-ai-google-sheets-monitoring",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/dtrungtin~ai-google-sheets-monitoring/run-sync": {
            "post": {
                "operationId": "run-sync-dtrungtin-ai-google-sheets-monitoring",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "spreadsheetUrl"
                ],
                "properties": {
                    "spreadsheetUrl": {
                        "title": "Spreadsheet URL",
                        "type": "string",
                        "description": "Full URL of the Google Sheet to monitor. Row 1 must be a header row containing a column named <code>URL</code>. Every other non-empty header is either a CSS selector whose extracted text is written into that column, or a plain field name (e.g. <code>Price</code>) that is extracted by AI when an OpenAI API key is provided."
                    },
                    "aiPrompt": {
                        "title": "AI extraction prompt",
                        "type": "string",
                        "description": "Optional instructions guiding how the AI fills the plain-name columns, e.g. <code>Price must be a plain number without currency symbols. Availability is either 'In stock' or 'Out of stock'. Answer in English.</code>"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
