# RSS News Digest – Keyword Alerts, Duplicates Merged (`petipeti/rss-news-digest`) Actor

Schedule it daily: new RSS/Atom items only, filtered by keywords that understand Japanese spelling variants (ＡＩ/AI/人工知能, サーバー/ｻｰﾊﾞ), and the same story from several feeds merged into one row.

- **URL**: https://apify.com/petipeti/rss-news-digest.md
- **Developed by:** [peti peti](https://apify.com/petipeti) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 item delivereds

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/actors/running/actors-in-store.md#pay-per-event

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

## RSS News Digest – Keyword Alerts, Duplicates Merged

**Every morning, just the new stories you care about – once, even when five sites report them.**

Give it RSS / Atom feeds (news sites, ministries, competitors' blogs, release notes) and optional keywords, then schedule it daily. Each run returns:

- **only items you have not received before** (remembered in a named key-value store in your account)
- **only items matching your keywords** – with matching that understands Japanese:
  - full / half width: `ＡＩ` = `AI`, `ｻｰﾊﾞ` = `サーバ`
  - katakana / hiragana and long vowels: `サーバー` = `サーバ` = `さーば`
  - synonyms on one line: `AI|人工知能|生成AI`
  - English terms match whole words, so `AI` does not fire on "email" or "available"
- **the same story from several feeds merged into one row**, with the other sources listed in `alsoReportedBy` (title similarity, works for Japanese and English)

Pair it with **Google Sheets Sync** (append mode) or an email / Slack integration and the digest lands where your team reads.

### Input

```json
{
  "feedUrls": ["https://www.digital.go.jp/rss/news.xml", "https://example.com/feed"],
  "keywords": ["AI|人工知能|生成AI", "マイナンバー"],
  "excludeKeywords": ["PR"],
  "maxAgeHours": 48
}
```

### Output (one row per story)

```json
{
  "title": "生成AIの新サービスを発表",
  "link": "https://news.example/a/123",
  "published": "2026-10-26T00:00:00.000Z",
  "source": "Example News",
  "summary": "企業向けに…",
  "matchedKeywords": ["AI"],
  "alsoReportedBy": [{ "source": "Other News", "title": "生成ＡＩの新サービス発表、企業向け", "link": "https://other.example/n/9" }]
}
```

A quiet day returns one row `status: "no-new-items"`. The `OUTPUT` record has counts (fetched, too old, seen before, not matching, merged) and per-feed errors.

### Fair use

- Only the feed URLs you enter are fetched – once per run, at least 1 second apart per site. robots.txt is respected; a disallowed feed is reported and skipped. The tool identifies itself as `RssNewsDigest/1.0`.
- Only what the feed itself publishes is used: title, link, date and the first 200 characters of the summary. Article pages are not downloaded. Keep the `source` and `link` when you republish anything, and follow each site's terms.

### Pricing

Pay per event, platform usage included:

| Event | Price |
|---|---|
| Actor start | $0.01 per run |
| `item-delivered` – one new story delivered | $0.50 per 1,000 items |

Example: 10 feeds checked daily with 20 matching stories a day ≈ 30 × ($0.01 + 20 × $0.0005) = **$0.60 per month**. Filtered-out, already-seen and merged duplicate items are free.

### 日本語での説明

指定した RSS・Atom フィードの新着だけを毎日まとめます。キーワードの一致は日本語の表記ゆれに強く、全角半角、カタカナ・ひらがな、長音（サーバー／ｻｰﾊﾞ）を同じものとして扱います。「AI|人工知能」のように同義語もまとめて指定できます。同じニュースが複数のサイトに出たときは1件にまとめ、ほかの出典を並べます。前回までに届けた記事は出しません。記事のページ本体は読まず、フィードに載っているタイトル・リンク・日付・要約の冒頭200文字だけを使います。

料金: 1回 $0.01 ＋ 新着1件 $0.0005（1,000件で $0.50）。絞り込みで外れた記事、既読の記事、まとめた重複は課金しません。

# Actor input Schema

## `feedUrls` (type: `array`):

One feed URL per line, e.g. a news site's, a ministry's or a blog's RSS.

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

Only items mentioning one of these are delivered. Put alternatives on one line separated by |, e.g. AI|人工知能|生成AI. Full/half width, katakana/hiragana and long vowels (サーバー/ｻｰﾊﾞ) are matched automatically; English words match whole words. Empty = all new items.

## `excludeKeywords` (type: `array`):

Items mentioning any of these are dropped. Same matching rules as keywords.

## `maxAgeHours` (type: `integer`):

Items published longer ago are ignored (items without a date are kept).

## `onlyNew` (type: `boolean`):

Remembers delivered items in a named key-value store, so a daily schedule returns each story once.

## `maxItems` (type: `integer`):

Upper limit of delivered items in one run.

## `stateStoreName` (type: `string`):

Named key-value store in your account. Each feed list keeps its own history.

## Actor input object example

```json
{
  "feedUrls": [
    "https://www.digital.go.jp/rss/news.xml"
  ],
  "keywords": [
    "AI|人工知能",
    "マイナンバー"
  ],
  "maxAgeHours": 48,
  "onlyNew": true,
  "maxItems": 500,
  "stateStoreName": "rss-news-digest-state"
}
```

# Actor output Schema

## `results` (type: `string`):

One row per story: title, link, date, source, matched keywords and the other feeds that reported the same story.

## `stats` (type: `string`):

OUTPUT record: items fetched, too old, seen before, not matching, merged duplicates, per-feed errors.

# 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 = {
    "feedUrls": [
        "https://www.digital.go.jp/rss/news.xml"
    ],
    "keywords": [
        "AI|人工知能",
        "マイナンバー"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("petipeti/rss-news-digest").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 = {
    "feedUrls": ["https://www.digital.go.jp/rss/news.xml"],
    "keywords": [
        "AI|人工知能",
        "マイナンバー",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("petipeti/rss-news-digest").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 '{
  "feedUrls": [
    "https://www.digital.go.jp/rss/news.xml"
  ],
  "keywords": [
    "AI|人工知能",
    "マイナンバー"
  ]
}' |
apify call petipeti/rss-news-digest --silent --output-dataset

```

## MCP server setup

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

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/w93blMnJs58WGXjHl/builds/fDHY70K8K15WFNI3E/openapi.json
