/ clis / bbc / news.js
news.js
 1  /**
 2   * BBC News headlines — public RSS feed, no browser needed.
 3   */
 4  import { cli, Strategy } from '@jackwener/opencli/registry';
 5  cli({
 6      site: 'bbc',
 7      name: 'news',
 8      description: 'BBC News headlines (RSS)',
 9      domain: 'www.bbc.com',
10      strategy: Strategy.PUBLIC,
11      args: [
12          { name: 'limit', type: 'int', default: 20, help: 'Number of headlines (max 50)' },
13      ],
14      columns: ['rank', 'title', 'description', 'url'],
15      func: async (page, kwargs) => {
16          const count = Math.min(kwargs.limit || 20, 50);
17          const resp = await fetch('https://feeds.bbci.co.uk/news/rss.xml');
18          if (!resp.ok)
19              return [];
20          const xml = await resp.text();
21          // Simple XML parsing without DOMParser (works in Node)
22          const items = [];
23          const itemRegex = /<item>([\s\S]*?)<\/item>/g;
24          let match;
25          while ((match = itemRegex.exec(xml)) && items.length < count) {
26              const block = match[1];
27              const title = block.match(/<title><!\[CDATA\[(.*?)\]\]>|<title>(.*?)<\/title>/)?.[1] || block.match(/<title>(.*?)<\/title>/)?.[1] || '';
28              const desc = block.match(/<description><!\[CDATA\[(.*?)\]\]>|<description>(.*?)<\/description>/)?.[1] || block.match(/<description>(.*?)<\/description>/)?.[1] || '';
29              const link = block.match(/<link>(.*?)<\/link>/)?.[1] || block.match(/<guid[^>]*>(.*?)<\/guid>/)?.[1] || '';
30              if (title) {
31                  items.push({
32                      rank: items.length + 1,
33                      title: title.trim(),
34                      description: desc.trim().substring(0, 200),
35                      url: link.trim(),
36                  });
37              }
38          }
39          return items;
40      },
41  });