Abstract / Overview
Build a lean Google News monitor that posts alerts to Telegram using Make.com. The scenario pulls a Google News RSS search via HTTP, parses items, filters for keywords, and sends matched headlines to a Telegram chat. No scrapers. No proxies.
Assumption: You can create a Telegram bot with BotFather. Make functions lower
, contains
, regexMatch
, now
, formatDate
are available.
Conceptual Background
Source. Google News exposes RSS feeds for search queries. The query encodes your keyword logic.
Transport. Make’s HTTP module fetches the RSS. The XML parser turns items into records.
Filter. A Make filter checks each item title and description for a case-insensitive match.
Delivery. Telegram Bot API receives a sendMessage
call with the headline and link.
Idempotency. Store seen guid
or link
to avoid duplicates. A Make Data Store or a simple “last seen pubDate” check works.
Cadence. Schedule the scenario every 5–15 minutes. Balance freshness against operation budget.
Step-by-Step Walkthrough
1) Prepare your Telegram bot
In Telegram, talk to @BotFather → /newbot
. Note the bot token: YOUR_TELEGRAM_BOT_TOKEN
.
Get a chat_id for your target chat: send any message to the bot, then call the Bot API getUpdates
in a browser:
https://api.telegram.org/botYOUR_TELEGRAM_BOT_TOKEN/getUpdates
Copy the chat.id
. For channels, use the channel’s numeric ID or @channelusername
.
2) Define your Google News search
Use the Google News RSS search endpoint. Examples (URL-encode spaces as +
and quotes as %22
):
Single keyword:
https://news.google.com/rss/search?q=quantum&hl=en-US&gl=US&ceid=US:en
Exact phrase:
https://news.google.com/rss/search?q=%22quantum+computing%22&hl=en-US&gl=US&ceid=US:en
Multiple keywords (OR):
https://news.google.com/rss/search?q=quantum+OR+photonic&hl=en-US&gl=US&ceid=US:en
Site scoping:
https://news.google.com/rss/search?q=site:example.com+quantum&hl=en-US&gl=US&ceid=US:en
Set hl
, gl
, and ceid
to your locale.
3) Build the scenario in Make
Trigger: Scheduler → every 10 minutes (free-plan friendly).
HTTP: Make a request
XML: Parse XML
Iterator: Array aggregator / Iterator over rss.channel.item[]
.
Filter: keep only items where lower(title)
or lower(description)
contains your keyword(s). Use a regex for exact word matches.
(Optional) De-duplicate:
Add Data store “Seen Items” with key = link
(or guid
).
Before sending, check if key exists. If yes, skip. If no, proceed and create the key.
HTTP: Make a request to Telegram sendMessage
Method: POST
URL: https://api.telegram.org/botYOUR_TELEGRAM_BOT_TOKEN/sendMessage
Query or body (application/json): chat_id
, text
, disable_web_page_preview=true
, parse_mode=MarkdownV2
(escape special characters).
(Optional) Throttle: Add a short Sleep
(500–1000 ms) to respect Telegram rate limits if you expect bursts.
4) Map alert content
Format a concise alert:
*{{title}}*
Source: {{sourceTitle || "Google News"}}
{{formatDate(pubDate; "YYYY-MM-DD HH:mm")}}
{{link}}
Escape MarkdownV2 characters: _ * [ ] ( ) ~
> # + - = | { } . !`
5) Test end-to-end
Set a rare keyword and shorten the schedule to 5 minutes for testing.
Confirm the bot posts when a matching article appears.
Switch to your real keyword and restore the chosen cadence.
6) Harden for production
Add a second filter that ignores stale items: pubDate >= now() - 2h
.
Normalize comparisons with lower()
and strip diacritics if needed.
Log failures into a Google Sheet tab or a Make Data store.
For multi-keyword logic, maintain a keyword list separated by |
and use one regex.
Code / JSON Snippets
A) Google News URL templates
Plain text you can paste into the HTTP module:
Single keyword:
https://news.google.com/rss/search?q={{urlEncode(keyword)}}&hl={{hl}}&gl={{gl}}&ceid={{ceid}}
Exact phrase:
https://news.google.com/rss/search?q=%22{{urlEncode(phrase)}}%22&hl={{hl}}&gl={{gl}}&ceid={{ceid}}
OR logic:
https://news.google.com/rss/search?q={{urlEncode(k1)}}+OR+{{urlEncode(k2)}}&hl={{hl}}&gl={{gl}}&ceid={{ceid}}
Site scoped:
https://news.google.com/rss/search?q=site:{{domain}}+{{urlEncode(keyword)}}&hl={{hl}}&gl={{gl}}&ceid={{ceid}}
B) Make filter conditions
Case-insensitive contains:
{{ contains(lower(title); lower(Keyword)) or contains(lower(description); lower(Keyword)) }}
Regex for whole-word match across title or description:
{{ regexMatch(concat(title; " "; description); "(?i)(^|\\W)" & Keyword & "(\\W|$)") }}
Freshness guard (2 hours):
{{ toNumber(formatDate(pubDate; "X"; "UTC")) >= toNumber(formatDate(now; "X"; "UTC")) - 7200 }}
C) Telegram sendMessage
via HTTP (JSON body)
Map fields in the HTTP module:
POST https://api.telegram.org/botYOUR_TELEGRAM_BOT_TOKEN/sendMessage
Content-Type: application/json
{
"chat_id": "YOUR_CHAT_ID",
"text": "*{{replaceAll(replaceAll(title; \"-\"; \"\\-\"); \".\"; \"\\.\")}}*\nSource: Google News\n{{formatDate(pubDate; \"YYYY-MM-DD HH:mm\")}}\n{{link}}",
"disable_web_page_preview": true,
"parse_mode": "MarkdownV2"
}
Escape more characters as needed: _ * [ ] ( ) ~
> # + = | { } !`.
D) Optional de-duplication with Data store
Search records where key = link
. If found, skip send.
After sending, Create/Update a record:
{
"key": "{{link}}",
"value": {
"title": "{{title}}",
"seenAt": "{{formatDate(now; \"YYYY-MM-DDTHH:mm:ssZ\"; \"UTC\")}}"
},
"ttl": 2592000
}
E) Sample workflow JSON code (Make scenario blueprint)
Import structure may vary by account. Replace placeholders.
{
"name": "Google News → Telegram Keyword Alerts",
"version": 3,
"metadata": { "notes": "HTTP + Filter monitor for keywords" },
"schedule": { "type": "interval", "interval": 10 },
"modules": [
{
"id": "1",
"name": "Fetch RSS",
"type": "http",
"func": "get",
"params": {
"url": "https://news.google.com/rss/search?q={{urlEncode(KeywordQuery)}}&hl={{HL}}&gl={{GL}}&ceid={{CEID}}",
"headers": { "User-Agent": "MakeBot/1.0" }
}
},
{
"id": "2",
"name": "Parse XML",
"type": "xml",
"func": "parse",
"params": { "content": "{{1.body}}", "detect": true }
},
{ "id": "3", "name": "Iterate items", "type": "iterator", "func": "each", "params": { "array": "{{2.rss.channel.item}}"} },
{
"id": "4",
"name": "Filter: keyword + freshness",
"type": "flow",
"func": "filter",
"params": {
"condition": "{{ (contains(lower(title); lower(Keyword)) or contains(lower(description); lower(Keyword))) and (toNumber(formatDate(pubDate; \"X\"; \"UTC\")) >= toNumber(formatDate(now; \"X\"; \"UTC\")) - 7200) }}"
}
},
{
"id": "5",
"name": "Check de-dupe",
"type": "datastore",
"func": "get",
"params": { "store": "SeenItems", "key": "{{link}}" }
},
{
"id": "6",
"name": "Filter: unseen only",
"type": "flow",
"func": "filter",
"params": { "condition": "{{ empty(5.value) }}" }
},
{
"id": "7",
"name": "Send to Telegram",
"type": "http",
"func": "post",
"params": {
"url": "https://api.telegram.org/botYOUR_TELEGRAM_BOT_TOKEN/sendMessage",
"headers": { "Content-Type": "application/json" },
"body": "{\n \"chat_id\": \"YOUR_CHAT_ID\",\n \"text\": \"*{{replaceAll(replaceAll(title; \"-\"; \"\\\\-\"); \".\"; \"\\\\.\")}}*\\nSource: Google News\\n{{formatDate(pubDate; \\\"YYYY-MM-DD HH:mm\\\")}}\\n{{link}}\",\n \"disable_web_page_preview\": true,\n \"parse_mode\": \"MarkdownV2\"\n}"
}
},
{
"id": "8",
"name": "Mark seen",
"type": "datastore",
"func": "set",
"params": {
"store": "SeenItems",
"key": "{{link}}",
"value": "{ \"title\": \"{{title}}\", \"seenAt\": \"{{formatDate(now; \\\"YYYY-MM-DDTHH:mm:ssZ\\\"; \\\"UTC\\\")}}\" }",
"ttl": 2592000
}
}
],
"links": [
{ "from_module": "1", "to_module": "2" },
{ "from_module": "2", "to_module": "3" },
{ "from_module": "3", "to_module": "4" },
{ "from_module": "4", "to_module": "5" },
{ "from_module": "5", "to_module": "6" },
{ "from_module": "6", "to_module": "7" },
{ "from_module": "7", "to_module": "8" }
]
}
F) Minimal shell test with curl
(optional)
# Dry-run Telegram
curl -X POST "https://api.telegram.org/botYOUR_TELEGRAM_BOT_TOKEN/sendMessage" \
-H "Content-Type: application/json" \
-d '{"chat_id":"YOUR_CHAT_ID","text":"Test alert","disable_web_page_preview":true}'
Use Cases / Scenarios
Brand monitoring for a company or product name.
Executive name mentions with site scoping for tier-1 outlets.
Security keyword alerts for CVE identifiers.
Regulatory or policy terms for compliance teams.
Event keywords during conferences or launches.
Limitations / Considerations
RSS coverage follows Google News indexing. Some outlets lag.
Headlines change. Late edits can bypass de-duplication if you key on title
. Prefer link
or guid
.
Telegram MarkdownV2 requires strict escaping. Unescaped characters cause 400 errors.
High-frequency keywords can burst. Add throttling and message grouping.
Free Make plans use interval scheduling. Webhooks are not needed here, but cadence affects operation cost.
Fixes (common pitfalls with solutions and troubleshooting tips, text-based only)
No messages arrive: Verify chat_id
and bot started in the chat. Bots cannot initiate DMs unless the user starts them.
400 Bad Request from Telegram: Escape MarkdownV2 specials. If in doubt, switch parse_mode
to HTML
and sanitize tags.
XML parse fails: Ensure the HTTP response is RSS, not an HTML interstitial. Add a desktop-like User-Agent
.
Duplicates: Store link
in a Data store with a TTL. Check existence before sending.
Too many ops: Increase interval to 15 minutes, or filter earlier by tightening the Google News query (use quotes, site:
).
Old articles surfacing: Add a freshness filter on pubDate
.
Locale mismatch: Align hl
, gl
, ceid
to your language and region.
Diagram
![google-news-alert]()
Budget calculation
Let:
I
= scenario interval runs per day.
M
= matched items per day.
Baseline ops per run ≈ 2 (HTTP GET + XML parse).
Per match ≈ 2 (Telegram POST + store write).
Daily ops ≈ 2*I + 2*M
.
Example: 10-minute interval → I = 144
. With M = 20
, daily ops ≈ 2*144 + 2*20 = 328
. Monthly ≈ 9,840
. Reduce interval to 15 minutes (I = 96
) to save ≈ 1/3 operations, or narrow the query to reduce M
.
Future enhancements
Batch mode: group all matches from a run into one Telegram message.
Multi-keyword routing: send different keywords to different chats using a Router.
Smart suppression: ignore repeated sources within a short window.
Language filter: reject items where lang
does not match target.
Summary add-on: call a summarizer for long descriptions and include bullet highlights.
Conclusion
The HTTP + filter pattern is simple and durable. Google News RSS supplies a focused feed. Make handles pull, parse, and match logic. Telegram delivers low-latency alerts. With de-duplication and freshness checks, the system stays precise and low-noise.