bbc/news
bbcRead-onlyBBC News headlines (RSS) or search
www.bbc.com
Last 7 days
0
Last 30 days
0
All time
0
bbc/news.js
/* @meta
{
"name": "bbc/news",
"description": "BBC News headlines (RSS) or search",
"domain": "www.bbc.com",
"args": {
"query": {"required": false, "description": "Search query. If omitted, returns top headlines from RSS feed"},
"count": {"required": false, "description": "Max results to return (default 20)"}
},
"readOnly": true,
"example": "tap site bbc/news \"climate change\""
}
*/
async function(args) {
const count = Math.min(parseInt(args.count) || 20, 50);
// If no query, fetch top headlines via RSS
if (!args.query) {
const rssUrl = 'https://feeds.bbci.co.uk/news/rss.xml';
const resp = await fetch(rssUrl);
if (!resp.ok) return {error: 'HTTP ' + resp.status, hint: 'Failed to fetch BBC RSS feed'};
const xml = await resp.text();
const parser = new DOMParser();
const doc = parser.parseFromString(xml, 'text/xml');
const items = doc.querySelectorAll('item');
const headlines = [];
items.forEach((item, i) => {
if (i >= count) return;
const title = item.querySelector('title')?.textContent?.trim() || '';
const description = item.querySelector('description')?.textContent?.trim() || '';
const link = item.querySelector('link')?.textContent?.trim() || '';
const pubDate = item.querySelector('pubDate')?.textContent?.trim() || '';
headlines.push({title, description, url: link, pubDate});
});
return {source: 'BBC News RSS', count: headlines.length, headlines};
}
// Search mode: fetch BBC search page and parse HTML
const searchUrl = 'https://www.bbc.co.uk/search?q=' + encodeURIComponent(args.query);
const resp = await fetch(searchUrl, {credentials: 'include'});
if (!resp.ok) return {error: 'HTTP ' + resp.status, hint: 'Failed to fetch BBC search results'};
const html = await resp.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const results = [];
// BBC search results use various selectors; try common patterns
// Pattern 1: search result links with data attributes or structured containers
const links = doc.querySelectorAll('a[href]');
const seen = new Set();
links.forEach(a => {
if (results.length >= count) return;
const href = a.getAttribute('href') || '';
// Only keep bbc.co.uk/news or bbc.com/news article links
if (!(href.includes('/news/') || href.includes('/sport/') || href.includes('/reel/'))) return;
if (!href.startsWith('http')) return;
if (seen.has(href)) return;
// Look for a heading or substantial text inside the anchor
const heading = a.querySelector('h1, h2, h3, h4, span, p');
const title = heading ? heading.textContent.trim() : a.textContent.trim();
if (!title || title.length < 5) return;
seen.add(href);
// Try to find a sibling or parent description
let description = '';
const parent = a.closest('li, div, article');
if (parent) {
const pTags = parent.querySelectorAll('p');
for (const p of pTags) {
const txt = p.textContent.trim();
if (txt.length > 20 && txt !== title) {
description = txt.substring(0, 300);
break;
}
}
}
results.push({title, description, url: href});
});
return {query: args.query, count: results.length, results};
}
Updated Mar 31, 2026Created Mar 31, 2026SHA-256: 3c9c5ffd662d…