irc-bot/tasks/rss.js

92 lines
2.6 KiB
JavaScript

const request = require("request");
const FeedParser = require("feedparser");
// For pushing updates from https://links.tildeverse.org
module.exports = class RSS {
constructor(client, alias, source, use, channels, interval) {
this.name = "RSS";
this.client = client;
this.alias = alias;
this.source = source;
this.use = use;
this.channels = channels;
this.interval = interval;
const task_memories = this.client.memory.tasks;
task_memories[this.alias] = task_memories[this.alias] || {};
this.memory = task_memories[this.alias];
}
start() {
this.memory.status = "running";
this.memory.timestamp = Date.now();
this.memory.known = [];
this.fetch(this.cache.bind(this));
this.job = setInterval(this.run.bind(this), this.interval);
}
stop(ack) {
clearInterval(this.job);
this.client.say(ack, `Stopping task "${this.alias}"`);
}
run() {
// this.fetch(console.log.bind(console));
this.fetch(this.mirror.bind(this));
}
cache(item) {
this.memory.known.push(item.guid);
}
mirror(item) {
if (this.memory.known.indexOf(item.guid) >= 0) return;
this.memory.known.push(item.guid);
const use = item[this.use].replace(/(<\/?[^>]+>)|\\n/g, "");
const user = item.author.split("@")[0];
const post = `${use} (posted by ${user}) <${item.guid}>`;
const response = `[${this.alias}] ${post}`;
this.channels.forEach((channel) => {
this.client.say(channel, response);
});
}
fetch(callback) {
const req = request(this.source);
const parser = new FeedParser();
req.on("error", (error) => {
console.error(`${this.name}::error: [request] ${error}`);
});
req.on("response", (res) => {
const status = res.statusCode;
if (status !== 200) {
req.emit("error", new Error(`Bad status code (${status})`));
} else {
req.pipe(parser);
}
});
parser.on("error", (error) => {
console.error(`${this.name}::error: [request] ${error}`);
});
parser.on("readable", () => {
let item = parser.read();
let meta = parser.meta;
while (item) {
callback(item);
item = parser.read();
}
});
parser.on("end", () => {
this.memory.timestamp = Date.now();
});
}
}