# Google News RSS Delta Monitor (`ursog/google-news-rss-delta-monitor`) Actor

- **URL**: https://apify.com/ursog/google-news-rss-delta-monitor.md
- **Developed by:** [andre donda de sa](https://apify.com/ursog) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google News RSS Delta Monitor

Persistent monitoring for official Google News RSS feeds. The Actor creates a baseline on the first successful run and returns only **new**, **removed-from-feed**, or **updated** article metadata on later runs.

This is a monitoring product, not an RSS downloader or article scraper. It stores prior feed state, compares runs, preserves previous/current values, suppresses duplicate changes, and exposes clear run evidence.

### What it monitors

- keywords;
- company and organization names;
- official Google News topics;
- locations;
- custom official `https://news.google.com/rss...` URLs.

The Actor uses official Google News RSS responses only. It does **not** visit publishers, extract article bodies, use a browser or proxy, call AI, generate sentiment, or use a paid API.

### First run: baseline creation

The first successful run for each monitor saves the current visible RSS items as its baseline. Existing articles are intentionally **not** emitted as new.

The dataset receives one baseline record such as:

```json
{
  "recordType": "baseline",
  "monitorKind": "company",
  "monitorValue": "OpenAI",
  "articlesInBaseline": 82,
  "message": "Baseline created from 82 current articles. Existing articles are not reported as new; later runs emit changes."
}
```

Keep the same `monitorKey` and monitoring inputs on scheduled runs. Changing the key creates an independent baseline.

### Later runs: deltas only

For every stable RSS article identity, the Actor detects:

- `new` — present now, absent from the prior visible feed;
- `removed` — present in the prior visible feed, absent now;
- `updated` — the same stable item changed one or more tracked fields.

Tracked fields:

- title;
- source;
- publication date;
- direct article URL, only when the RSS item itself exposes one;
- Google News URL;
- GUID;
- normalized description hash.

Updated records contain `previousArticle`, `currentArticle`, and a field-level `changes` array.

> **Removal meaning:** Google News RSS is a rolling window. `removed` means the item left the currently visible feed. It does not prove that a publisher deleted or retracted the article.

### Quick start

```json
{
  "keywords": ["artificial intelligence regulation"],
  "monitorKey": "ai-regulation",
  "language": "en",
  "country": "US"
}
```

1. Run once and confirm the **Baselines** view.
2. Save the input as an Apify Task.
3. Schedule the Task with the same `monitorKey`.
4. Read changes from the **Article changes** view or connect a webhook to successful runs.

### Inputs

| Input | Default | Purpose |
|---|---:|---|
| `keywords` | `[]` | Free-form Google News RSS search queries. |
| `companies` | `[]` | Exact quoted company/organization searches. |
| `topics` | `[]` | WORLD, NATION, BUSINESS, TECHNOLOGY, ENTERTAINMENT, SPORTS, SCIENCE, or HEALTH. |
| `locations` | `[]` | Exact quoted place searches. |
| `customRssUrls` | `[]` | Official Google News RSS URLs only. |
| `language` | `en` | Two- or three-letter feed language. |
| `country` | `US` | Two-letter Google News edition. |
| `monitorKey` | `default` | Persistent state namespace. Keep it stable. |
| `maxMonitors` | `50` | Combined unique-monitor ceiling; advanced maximum 250. |
| `maxItemsPerMonitor` | `100` | Maximum visible items retained from each feed. |
| `maxConcurrency` | `10` | Concurrent direct RSS checks. |
| `requestTimeoutSecs` | `10` | Whole HTTP transaction deadline. |
| `maxRequestRetries` | `1` | Bounded retry count for temporary failures. |
| `maxResponseBytes` | `2,000,000` | Streaming response ceiling per feed. |

At least one monitoring input is required. Equivalent duplicate values are normalized, fetched once, and billed once.

### Output and status

Dataset views:

- **Article changes** — new, removed, and updated items;
- **Baselines** — successful first-run setup;
- **Warnings and failures** — blocked, failed, malformed, or oversized sources.

The `OUTPUT` key-value record contains a human-readable run summary with counts, retries, errors, limits, and a dataset link.

Run status is one of:

- `complete` — all requested monitors were checked;
- `empty` — checks succeeded but current feeds contain zero items;
- `partial` — some monitors succeeded and some failed or were blocked;
- `blocked` — no monitor succeeded because source access was blocked.

A blocked or failed source is never reported as a successful empty feed.

### URL provenance and nulls

Every record includes the official RSS `sourceUrl`. Google News RSS normally exposes a Google News redirect URL rather than a resolved publisher article URL. Therefore:

- `googleNewsUrl` contains the supplied Google News link when available;
- `articleUrl` is `null` unless the RSS item itself supplies a direct non-Google URL;
- missing contracted values remain `null` and are never invented.

### Pricing

Provisional Store model: **$0.005 per `monitor-checked` event**.

One event is charged only after one unique monitor was successfully fetched, parsed, persisted, and written to the dataset. Failed, blocked, duplicate, and retry attempts do not create extra charges. Baseline creation and all resulting change rows are included in that monitor check.

Estimated infrastructure is `$0.00015–$0.00045` per successful monitor check in normal batches. At the provisional price, estimated publisher margin after Apify's 20% share is approximately **71–77%**. Live validation must confirm these estimates before public pricing approval.

### Reliability and cost controls

- direct HTTPS only;
- official `news.google.com/rss` URLs only;
- complete-transaction timeouts, including body streaming;
- byte enforcement while chunks are received, even without honest `Content-Length`;
- maximum two retries and no infinite fallback paths;
- per-monitor checkpoints instead of full-state rewrites;
- deterministic output independent of HTTP completion order;
- idempotent PPE intent/completion records;
- default 50-monitor and hard 250-monitor boundaries;
- no browser, proxy, AI, paid API, or publisher-page request.

### Limitations

- RSS is a current rolling window, not a permanent Google News archive.
- Feed membership and ranking can change without a publisher changing its article.
- A changed feed limit, query, country, language, or custom URL changes what “removed” means. Use a new `monitorKey` when intentionally changing monitor semantics.
- Google can change its RSS format or availability.
- No full article text, publisher metadata enrichment, resolved redirect URL, sentiment, or summary is provided.

### Responsible use

The Actor collects only metadata returned by public Google News RSS feeds. Users remain responsible for complying with applicable laws, Google terms, publisher rights, and their own data-retention obligations.

# Changelog

This Actor's version history is a separate document: https://apify.com/ursog/google-news-rss-delta-monitor/changelog.md

# Actor input Schema

## `keywords` (type: `array`):

News searches such as artificial intelligence regulation or battery recycling.

## `companies` (type: `array`):

Company or organization names. Each value is sent as an exact quoted Google News RSS search.

## `topics` (type: `array`):

Official Google News topic feeds.

## `locations` (type: `array`):

Places to monitor as exact quoted Google News RSS searches, such as São Paulo or Austin Texas.

## `customRssUrls` (type: `array`):

Optional advanced input. Only HTTPS URLs on news.google.com whose path starts with /rss are accepted. Other RSS feeds are rejected.

## `language` (type: `string`):

Two- or three-letter language code, such as en or pt.

## `country` (type: `string`):

Two-letter Google News edition code, such as US or BR.

## `monitorKey` (type: `string`):

A stable name for this group of monitors, such as brand-watch or market-news.

## `maxMonitors` (type: `integer`):

Default maximum is 50. Up to 250 requires advanced mode.

## `enableAdvancedLimit` (type: `boolean`):

Enable only after validating a smaller recurring run.

## `maxItemsPerMonitor` (type: `integer`):

Hard output/state ceiling for each RSS feed. Google News feeds normally expose at most about 100 current items.

## `maxConcurrency` (type: `integer`):

Keep the default unless live validation shows a reason to change it.

## `requestTimeoutSecs` (type: `integer`):

Maximum time for the complete RSS transaction, including response streaming.

## `maxRequestRetries` (type: `integer`):

Retries only temporary rate limits, timeouts, and server errors.

## `maxResponseBytes` (type: `integer`):

Streaming byte limit per feed. The request is aborted as soon as the limit is exceeded.

## Actor input object example

```json
{
  "keywords": [],
  "companies": [],
  "topics": [],
  "locations": [],
  "customRssUrls": [],
  "language": "en",
  "country": "US",
  "monitorKey": "default",
  "maxMonitors": 50,
  "enableAdvancedLimit": false,
  "maxItemsPerMonitor": 100,
  "maxConcurrency": 10,
  "requestTimeoutSecs": 10,
  "maxRequestRetries": 1,
  "maxResponseBytes": 2000000
}
```

# Actor output Schema

## `changes` (type: `string`):

No description

## `baselines` (type: `string`):

No description

## `diagnostics` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ursog/google-news-rss-delta-monitor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("ursog/google-news-rss-delta-monitor").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{}' |
apify call ursog/google-news-rss-delta-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ursog/google-news-rss-delta-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/E3KMTH6LJ2CCKMAl0/builds/6785mxKWmx7oKaZ8K/openapi.json
