Skip to content

SamJale/Google-News-Monitor-API

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Google News Monitor API

This is a simple media brand monitoring tool built using the Google News API (via SearchApi.io) as a data source. Enter a brand name or keyword you would like to monitor, and the tool will search daily for coverage, providing an AI summary and sentiment label for each article using OpenAI.

Unlike Google News and its broad keyword matching, this tool ensures an exact keyword match to filter out irrelevant articles. With built-in Slack notifications, you can pick a keyword, see who is writing about it, get a quick read on whether the coverage is positive or negative.

The tool provides a basic web dashboard UI, as well as a REST API and CLI access.

Dashboard showing a tracked keyword report with sentiment counts, AI period summary, daily volume chart, and a filtered article list

Features

  • Search news by keyword with controls for time range, result count, and country.
  • Per-article AI enrichment: sentiment (positive / negative / neutral) and a one-sentence summary.
  • Keyword-match detection that flags which articles actually mention your brand, separately from what Google returned.
  • AI period summary - a paragraph-long narrative of what the coverage is saying for the day, week, month, or all-time.
  • Daily background job keeps every tracked keyword fresh without you opening the app.
  • Slack alerts for risk phrases (lawsuit, breach, outage…), negative sentiment, or volume spikes.
  • Volume chart with day / month / year buckets and zero-fill so the spacing is even.
  • Three interfaces - a Tailwind dashboard (no build step), a REST API, and a CLI.
  • CSV export of any article list.

Use cases

  • Brand monitoring - track every mention of your company, get a daily digest, and a Slack ping when coverage turns negative.
  • Competitive intel - drop in your competitors as keywords and watch the volume chart for spikes that hint at launches, raises, or controversies.
  • Launch tracking - add the codename of an upcoming product. After launch day you have a clean record of who covered it, what they said, and the tone.
  • Topic research - track broad terms like AI safety regulation or battery recycling and build a long-running archive you can export to CSV.
  • Crisis monitoring - combine the Slack webhook with the risk-phrase detector for a low-effort early warning system.
  • Beat reporting - keep tabs on a sector, a company, or a public figure and surface new coverage every morning.

Who it's for

  • Founders who want to know what the press is saying about their company without paying for Meltwater.
  • Marketers building reports on share of voice, campaign coverage, or competitor activity.
  • PR and comms teams that need a daily digest and an early warning when something goes sideways.
  • Journalists tracking a beat - a company, a sector, a person, an ongoing story - and wanting one place to see what's new.
  • Researchers and analysts building a corpus of coverage on a topic over time.
  • Developers who want a clean JSON feed of news mentions they can pipe into Slack, Zapier, n8n, or a custom dashboard.

How it works

    keyword  ──►  Google News API  ──►  raw articles
                                              │
                                              ▼
                                      OpenAI enrichment
                                  (sentiment + summary, JSON)
                                              │
                                              ▼
                                       SQLite (data.db)
                                              │
                                              ▼
                                   ┌──────────┴───────────┐
                                   ▼                      ▼
                              dashboard              REST / CLI
  1. You search a keyword from the dashboard, the CLI, or by hitting an API URL.
  2. The keyword is sent to Google News through SearchApi.io with nfpr=1, which is Google's "don't auto-correct my query" flag. Without that, a search for searchapi would silently become serpapi.
  3. Every article that comes back is sent to OpenAI for a structured JSON response: sentiment (positive / negative / neutral) plus a one-sentence summary. The system prompt forces JSON output so nothing free-form ever reaches the database.
  4. The article, sentiment, and summary are saved to a local SQLite file. Dates like "1 week ago" or "May 30, 2023" are normalized to ISO format on the way in, so filters and charts behave.
  5. Each article is also flagged as a "keyword match" or not, based on whether the brand name actually appears in the title, snippet, URL, source, or AI summary. Matches sort to the top of every report.
  6. If you've added a Slack webhook, articles that trip a risk phrase, come back with negative sentiment, or arrive in a volume spike will post to your channel.
  7. A cron job runs once a day to keep every monitored keyword fresh.

Setup

You need Python 3.10 or newer. Three commands:

git clone https://github.com/YOUR-ORG/google-news-monitor.git
cd google-news-monitor
pip install -r requirements.txt

Then start the app:

python app.py

A browser tab opens at http://127.0.0.1:5000/. The first run creates data.db and all its tables automatically - no manual SQL.

You need two API keys. Either paste them into the Settings button in the top-right of the dashboard, or copy .env.example to .env and edit it directly:

Slack alerts are optional. If you want them, paste an incoming webhook URL into Settings and hit Send test message to confirm it works.

Using the dashboard

The main page has:

  • A search bar with time range (Last 24 hours through Last year or Any time), result count, and a country dropdown for geo-targeted news.
  • A Monitor daily checkbox next to it. Tick that to add the keyword to the daily background job.
  • A list of tracked keywords with quick links to each one's report.
  • A Report panel that opens after you search. It shows total mentions, keyword-match count, sentiment breakdown, an AI-written narrative of the period, a volume chart, and the article list.
  • An "Only show keyword matches" toggle above the article list.
  • A Download CSV button that exports the visible article list.

REST API

All endpoints return JSON. The server runs on 127.0.0.1:5000 by default.

Method Path Purpose
GET /healthz Liveness check
GET /api/keywords List tracked keywords
POST /api/keywords Add a keyword
DELETE /api/keywords/<keyword> Stop tracking
POST /api/search Run the pipeline once (fetch + enrich + save)
POST /api/cron/run Run the daily job immediately
GET /api/report/<keyword> Full report - every article in the period
GET /api/matches/<keyword> Same payload, filtered to keyword matches only
GET /api/analytics/<keyword> Sentiment totals + bucketed volume for the chart
GET /api/alerts Recent breaking-news alerts
GET /api/settings Current settings (keys are masked)
POST /api/settings Update keys, model, Slack webhook
POST /api/settings/test-slack Send a test Slack message

The report and matches endpoints auto-fetch on first use. If there's nothing in the database for that keyword yet, the pipeline runs first and the report comes back populated. Subsequent calls are instant. Pass ?fetch=true to force a refresh.

Query parameters

For /api/report and /api/matches:

  • period - daily, weekly, monthly, or all (default: all for matches, weekly for report)
  • fetch - true to force a fresh fetch even when data already exists
  • num - max results from Google News when auto-fetching (default 50)
  • when - 1h, 1d, 7d, 1m, 1y (default: any time)
  • gl - 2-letter country code, e.g. us, gb, de

Example

A single URL is enough to spin up a fresh monitor for a brand new keyword:

GET http://127.0.0.1:5000/api/matches/n8n?period=all

Response (trimmed):

{
  "status": "ok",
  "metadata": {
    "period": "all",
    "period_start": null,
    "period_end": "2026-05-21T14:22:08.103+00:00",
    "exact_match_query": "n8n",
    "total_mentions": 4,
    "keyword_matches": 4,
    "positive": 3,
    "negative": 0,
    "neutral": 1,
    "filter": "matches_only",
    "auto_fetch": { "fetched": 12, "new": 12 }
  },
  "ai_period_summary": "Coverage of n8n centered on its rapid adoption in AI agent tooling, a Series B funding round, and the launch of a self-hosted Enterprise tier. Tone was largely positive, with reporters framing n8n as a credible open-source alternative to Zapier and Make.",
  "articles": [
    {
      "title": "n8n raises $60M Series B as AI workflow tools heat up",
      "source": "TechCrunch",
      "url": "https://techcrunch.com/2026/05/14/n8n-series-b/",
      "published_at": "2026-05-14",
      "sentiment": "positive",
      "matches_keyword": true,
      "ai_summary": "n8n raised a $60M Series B led by Highland Europe, citing strong demand from teams building AI agent workflows.",
      "snippet": "Berlin-based n8n said Wednesday it had raised $60 million..."
    },
    {
      "title": "Self-hosting n8n vs Zapier: a 2026 comparison",
      "source": "Hacker Noon",
      "url": "https://hackernoon.com/n8n-vs-zapier-2026",
      "published_at": "2026-04-30",
      "sentiment": "neutral",
      "matches_keyword": true,
      "ai_summary": "A side-by-side teardown of n8n and Zapier for indie devs, weighing self-hosting effort against per-task pricing.",
      "snippet": "If you're shipping a SaaS in 2026 and need automation..."
    }
  ]
}

The two interesting fields per article are sentiment and matches_keyword. The metadata block carries the rolled-up counts. auto_fetch only appears when a fresh pipeline run happened on this request.

Other examples

# Force a refresh of a keyword you've already searched
curl "http://127.0.0.1:5000/api/matches/searchapi.io?fetch=true&when=1m&gl=us"

# Add a keyword without running a search
curl -X POST http://127.0.0.1:5000/api/keywords \
  -H 'Content-Type: application/json' \
  -d '{"keyword": "anthropic", "monitored": true}'

# Run the daily job for everything that's flagged
curl -X POST http://127.0.0.1:5000/api/cron/run

CLI

The CLI does everything the API does, from your terminal.

python cli.py init                          # create the DB (also happens automatically)
python cli.py add "anthropic"               # start tracking
python cli.py list                          # show what's monitored
python cli.py search "n8n" --when 1m --gl us --num 50
python cli.py report "n8n" --period weekly
python cli.py cron                          # run the daily job manually
python cli.py remove "anthropic"
python cli.py reset                         # wipe the DB (asks first)

Project layout

google-news-monitor/
├── app.py                  # Boots Flask, runs DB migrations, starts the cron
├── cli.py                  # Click-based command line
├── monitor/
│   ├── db.py               # SQLite store + bucketed analytics
│   ├── dates.py            # Parses "1 week ago" / "May 30, 2023" into ISO
│   ├── search.py           # SearchApi.io Google News client
│   ├── ai.py               # OpenAI sentiment + summary, strict JSON output
│   ├── alerts.py           # Risk phrases + volume spikes + Slack formatter
│   ├── pipeline.py         # Fetch → enrich → save → alert
│   ├── scheduler.py        # APScheduler daily cron
│   ├── settings.py         # Read/write .env from the UI
│   └── api.py              # Flask REST blueprint + dashboard route
├── templates/
│   └── dashboard.html      # Tailwind + Chart.js, no build step
├── tests/
│   └── test_filter.py      # Sanity checks for contributors
├── requirements.txt
├── .env.example
└── .gitignore

Tests

The test suite is for developers contributing to the project, not something an end user needs to run. It exercises the parts of the codebase most likely to silently break:

  • That the OpenAI system prompts force JSON output (so the database ingestion never sees free-form text).
  • That the database self-heals on first boot - data.db and its tables get created automatically if missing.
  • That the keyword-matching logic and query passthrough behave as expected.

If you're modifying the codebase and want to make sure you haven't broken anything:

python -m unittest tests.test_filter -v

License

MIT.

About

A news and media keyword monitoring tool built on the Google News API. Tracks keyword mentions, brand mentions, sentiment, and volume over time. Has a user friendly dashboard, REST API, and CLI. Daily monitoring cron job and Slack notifications built in.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors