This repository has been archived on 2024-09-11. You can view files and clone it, but cannot push or open issues or pull requests.
svrjs-blog-newsletter/cronjob/main.js

123 lines
4.1 KiB
JavaScript

var XMLParser = require("fast-xml-parser").XMLParser;
var http = require("http");
var https = require("https");
var fs = require("fs");
var MongoClient = require('mongodb').MongoClient;
var nodemailer = require("nodemailer");
var transporter = nodemailer.createTransport({
host: "localhost",
port: 25,
secure: false, // Use `true` for port 465, `false` for all other ports
tls: {
rejectUnauthorized: false
},
pool: true
});
var fromEmail = "root@localhost";
var mongoURL = "mongodb://localhost/newsletter";
var dbname = "newsletter";
function antiXSS(string) {
return string.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
function connectMongo(callback) {
MongoClient.connect(mongoURL, function (err, db) {
if (err) throw err;
var dbo = db.db(dbname);
dbo.createCollection("emails", function (err, dbres) {
dbo.createCollection("posts", function (err, dbres) {
callback(dbo);
});
});
});
}
function formatTemplate(templateName, templateData, callback) {
fs.readFile(__dirname + "/" + templateName + ".template", function (err, data) {
if (err) throw err;
var tD = data.toString();
Object.keys(templateData).forEach(function (key) {
tD = tD.replace(new RegExp("\\{\\{" + escapeRegExp(key) + "\\}\\}", "g"), templateData[key]);
});
callback(tD);
});
}
https.get("https://blog.svrjs.org/atom.xml", function (res) {
var data = "";
res.on("data", function (chunk) {
data += chunk.toString();
});
res.on("end", function () {
var parser = new XMLParser();
var parsedData = parser.parse(data);
var entries = parsedData.feed.entry;
connectMongo(function (db) {
db.collection("emails").find({}).toArray(function (err, emails) {
if (err) throw err;
var queue = [];
var ent = JSON.parse(JSON.stringify(entries)).reverse();
function getEntriesId(_id) {
if (!_id) _id = 0;
if (_id >= ent.length) {
process.exit(0);
return;
}
db.collection("posts").find({
id: ent[_id].id
}).toArray(function (err, result) {
if (err) throw err;
if (result.length == 0) {
db.collection("posts").insertOne({
id: ent[_id].id
}, function (err, dbres) {
if (err) throw err;
var _qid = _id;
function sendEmail(_id) {
if (!_id) _id = 0;
if (_id >= emails.length) {
getEntriesId(_id + 1);
return;
}
var qim = ent[_qid].id.match(/https:\/\/blog\.svrjs\.org\/[0-9]+\/[0-9]+\/[0-9]+\/([^\/]+)/);
var imageURL = "https://blog.svrjs.org/images/covers/" + (qim ? qim[1] : "missing") + ".png";
formatTemplate("index.html", {
"title": antiXSS(ent[_qid].title),
"summary": ent[_qid].summary.replace(/ (src|href)="\/(?!\/)/g," $1=\"https://blog.svrjs.org/"),
"image": antiXSS(imageURL),
"link": antiXSS(ent[_qid].id),
"unsubscribe": antiXSS("https://newsletter.svrjs.org/unsubscribe.svr?id=" + encodeURIComponent(emails[_id].unsubscribeId))
}, function (data) {
transporter.sendMail({
from: fromEmail,
to: emails[_id].email,
subject: ent[_qid].title + " - SVR.JS Blog Newsletter",
text: 'This message requires HTML to be viewed',
html: data
}, function (err, info) {
if (err) throw err;
sendEmail(_id + 1);
});
});
}
sendEmail();
});
} else {
getEntriesId(_id + 1);
}
});
}
getEntriesId();
});
});
});
});