const Database = require('better-sqlite3'); const db = new Database('bot-node.db'), Parser = require('rss-parser'), request = require('request'), crypto = require('crypto'), parser = new Parser(); // get all feeds from DB let feeds = db.prepare('select * from feeds').all(); for (var feed of feeds) { // fetch new RSS for each feed parser.parseURL(feed.feed, function(err, feedData) { if (err) { console.log('error fetching', feed.feed, err); } else { //console.log(feedData); // get the old feed data from the database let oldFeed = JSON.parse(feed.content); // compare the feed item contents. if there's one or more whole new items (aka a new item with a unique guid), // add the items to a list like // [ { items: [], username }, {}, ... ] let oldItems = oldFeed.items; let newItems = feedData.items; // find the difference of the sets of guids (fall back to title or // description since guid is not required by spec) in the old and new feeds let oldGuidSet = new Set(oldItems.map(el => el.guid || el.title || el.description)); let newGuidSet = new Set(newItems.map(el => el.guid || el.title || el.description)); // find things in the new set that aren't in the old set let difference = new Set( [...newGuidSet].filter(x => !oldGuidSet.has(x))); difference = [...difference]; console.log('diff', difference); if (difference.length > 0) { // get a list of new items in the diff let brandNewItems = newItems.filter(el => difference.includes(el.guid) || difference.includes(el.title) || difference.includes(el.description)); let acct = feed.username; let domain = 'bots.tinysubversions.com'; console.log(acct, brandNewItems); // send the message to everyone for each item! for (var item of brandNewItems) { // FIX THIS item = transformContent(item); console.log(item.urls); let message = `
${item.content}
`; if (item.enclosure && item.enclosure.url && item.enclosure.url.includes('.mp3')) { message += ``; } sendCreateMessage(message, acct, domain, null, null, item); } // update the DB with new contents let content = JSON.stringify(feedData); db.prepare('insert or replace into feeds(feed, username, content) values(?, ?, ?)').run( feed, acct, content); } } }); } // TODO: update the display name of a feed if the feed title has changed // This is a function with a bunch of custom rules for different kinds of content I've found in the wild in things like Reddit rss feeds function transformContent(item) { let cheerio = require('cheerio'); console.log(item.content); if (item.content === undefined) { item.urls = []; return item; } let $ = cheerio.load(item.content); // look through all the links let links = $('a'); let urls = []; console.log('links', links.length); links.each((i,e) => { let url = $(e).attr('href'); // if there's an image, add it as a media attachment if (url.match(/(http)?s?:?(\/\/[^"']*\.(?:png|jpg|jpeg|gif|png|svg))/)) { console.log(url); urls.push(url); } }); item.urls = urls; // remove multiple line breaks $('br+br+br').remove(); $('p').each((i, el) => { if($(el).html().replace(/\s| /g, '').length === 0) {$(el).remove();} }); // convert li items to bullet points $('li').each((i, el) => { console.log($(el).html()); $(el).replaceWith(`- ${$(el).html()}