nodemailer-sequelize-queue
Version:
Queue for mails with nodemailer and cron scheduler
107 lines • 11 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MailProcessor = void 0;
const logger_1 = __importDefault(require("./utils/logger"));
const sequelize_1 = require("sequelize");
const uuid_1 = require("uuid");
class MailProcessor {
constructor(queueModel, mailer, maxAttemps = -1, logging = false, limit = 100) {
this.limit = limit;
this.maxAttemps = maxAttemps;
this.logging = logging;
this.queueModel = queueModel;
this.mailer = mailer;
}
async processQueueMails() {
const options = {
limit: this.limit,
};
const worker_uuid = (0, uuid_1.v4)();
try {
if (this.maxAttemps > 0) {
options.where = {
attempts: {
[sequelize_1.Op.lt]: this.maxAttemps,
},
};
}
// Lock the rows
await this.queueModel.update({
worker_uuid,
}, {
where: {
...options.where,
worker_uuid: null,
},
});
// Get the rows of the worker
options.where = {
...options.where,
worker_uuid,
};
const mails = await this.queueModel.findAll(options);
// Remove from queue(prevents duplicate sends with multiple workers)
const models = [];
for (const mail of mails) {
const model = this.sendQueuedMailAndDeleteRow(mail);
models.push(model);
}
await Promise.all(models);
}
catch (e) {
// reset worker_uuid
await this.queueModel.update({
worker_uuid: null,
}, {
where: {
worker_uuid,
},
});
throw e;
}
}
async sendQueuedMailAndDeleteRow(model) {
try {
const message = this.mailer.composeMailFromModel(model);
const result = await this.mailer.sendMail(message);
if (!result.accepted) {
throw new Error('Error sending mail');
}
// Remove from queue
await this.queueModel.destroy({
where: {
id: model.id,
},
});
this.log(`Deleted mail from queue ${model.id}`, 'debug');
return model;
}
catch (err) {
const e = err;
logger_1.default.error(`Error sending mail to ${model.email_to}`, {
model,
error: e.message,
stack: e.stack,
});
await model.update({
last_error: JSON.stringify(e),
attempts: model.attempts + 1,
}, {
where: {
id: model.id,
},
});
return model;
}
}
log(message, level = 'info') {
if (this.logging) {
logger_1.default.log(level, message);
}
}
}
exports.MailProcessor = MailProcessor;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWFpbFByb2Nlc3Nvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9NYWlsUHJvY2Vzc29yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBLDREQUFtQztBQUNuQyx5Q0FBOEI7QUFDOUIsK0JBQWlDO0FBRWpDLE1BQWEsYUFBYTtJQVF4QixZQUNFLFVBQTZCLEVBQzdCLE1BQWUsRUFDZixVQUFVLEdBQUcsQ0FBQyxDQUFDLEVBQ2YsT0FBTyxHQUFHLEtBQUssRUFDZixLQUFLLEdBQUcsR0FBRztRQUVYLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFBO1FBQ2xCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO1FBQzVCLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFBO1FBRXRCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO1FBRTVCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO0lBQ3RCLENBQUM7SUFDTSxLQUFLLENBQUMsaUJBQWlCO1FBQzVCLE1BQU0sT0FBTyxHQUFRO1lBQ25CLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztTQUNsQixDQUFBO1FBRUQsTUFBTSxXQUFXLEdBQUcsSUFBQSxTQUFJLEdBQUUsQ0FBQTtRQUMxQixJQUFJO1lBQ0YsSUFBSSxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRTtnQkFDdkIsT0FBTyxDQUFDLEtBQUssR0FBRztvQkFDZCxRQUFRLEVBQUU7d0JBQ1IsQ0FBQyxjQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVU7cUJBQ3pCO2lCQUNGLENBQUE7YUFDRjtZQUVELGdCQUFnQjtZQUNoQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUMxQjtnQkFDRSxXQUFXO2FBQ1osRUFDRDtnQkFDRSxLQUFLLEVBQUU7b0JBQ0wsR0FBRyxPQUFPLENBQUMsS0FBSztvQkFDaEIsV0FBVyxFQUFFLElBQUk7aUJBQ2xCO2FBQ0YsQ0FDRixDQUFBO1lBRUQsNkJBQTZCO1lBQzdCLE9BQU8sQ0FBQyxLQUFLLEdBQUc7Z0JBQ2QsR0FBRyxPQUFPLENBQUMsS0FBSztnQkFDaEIsV0FBVzthQUNaLENBQUE7WUFFRCxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3BELG9FQUFvRTtZQUVwRSxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUE7WUFDakIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7Z0JBQ3hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFvQixDQUFDLENBQUE7Z0JBQ25FLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7YUFDbkI7WUFFRCxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUE7U0FDMUI7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLG9CQUFvQjtZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUMxQjtnQkFDRSxXQUFXLEVBQUUsSUFBSTthQUNsQixFQUNEO2dCQUNFLEtBQUssRUFBRTtvQkFDTCxXQUFXO2lCQUNaO2FBQ0YsQ0FDRixDQUFBO1lBQ0QsTUFBTSxDQUFDLENBQUE7U0FDUjtJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsMEJBQTBCLENBQUMsS0FBbUI7UUFDMUQsSUFBSTtZQUNGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDdkQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUNsRCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRTtnQkFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO2FBQ3RDO1lBRUQsb0JBQW9CO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUM7Z0JBQzVCLEtBQUssRUFBRTtvQkFDTCxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUU7aUJBQ2I7YUFDRixDQUFDLENBQUE7WUFDRixJQUFJLENBQUMsR0FBRyxDQUFDLDJCQUEyQixLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFFeEQsT0FBTyxLQUFLLENBQUE7U0FDYjtRQUFDLE9BQU8sR0FBWSxFQUFFO1lBQ3JCLE1BQU0sQ0FBQyxHQUFHLEdBQVksQ0FBQTtZQUN0QixnQkFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFO2dCQUN0RCxLQUFLO2dCQUNMLEtBQUssRUFBRSxDQUFDLENBQUMsT0FBTztnQkFDaEIsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLO2FBQ2YsQ0FBQyxDQUFBO1lBQ0YsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUNoQjtnQkFDRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQzdCLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxHQUFHLENBQUM7YUFDN0IsRUFDRDtnQkFDRSxLQUFLLEVBQUU7b0JBQ0wsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFO2lCQUNiO2FBQ0YsQ0FDRixDQUFBO1lBQ0QsT0FBTyxLQUFLLENBQUE7U0FDYjtJQUNILENBQUM7SUFFTyxHQUFHLENBQUMsT0FBZSxFQUFFLEtBQUssR0FBRyxNQUFNO1FBQ3pDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixnQkFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUE7U0FDM0I7SUFDSCxDQUFDO0NBQ0Y7QUEvSEQsc0NBK0hDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSU1haWxlciB9IGZyb20gJy4vTWFpbGVyJ1xuaW1wb3J0IHsgSVF1ZXVlTW9kZWxTdGF0aWMsIE5zcU1haWxRdWV1ZSB9IGZyb20gJy4vUXVldWVNb2RlbCdcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi91dGlscy9sb2dnZXInXG5pbXBvcnQgeyBPcCB9IGZyb20gJ3NlcXVlbGl6ZSdcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tICd1dWlkJ1xuXG5leHBvcnQgY2xhc3MgTWFpbFByb2Nlc3NvciB7XG4gIGV4cHJlc3Npb246IHN0cmluZ1xuICBtYXhBdHRlbXBzOiBudW1iZXJcbiAgbWFpbGVyOiBJTWFpbGVyXG4gIGxvZ2dpbmc6IGJvb2xlYW5cbiAgbGltaXQ6IG51bWJlclxuICBwcml2YXRlIHF1ZXVlTW9kZWw6IElRdWV1ZU1vZGVsU3RhdGljXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcXVldWVNb2RlbDogSVF1ZXVlTW9kZWxTdGF0aWMsXG4gICAgbWFpbGVyOiBJTWFpbGVyLFxuICAgIG1heEF0dGVtcHMgPSAtMSxcbiAgICBsb2dnaW5nID0gZmFsc2UsXG4gICAgbGltaXQgPSAxMDBcbiAgKSB7XG4gICAgdGhpcy5saW1pdCA9IGxpbWl0XG4gICAgdGhpcy5tYXhBdHRlbXBzID0gbWF4QXR0ZW1wc1xuICAgIHRoaXMubG9nZ2luZyA9IGxvZ2dpbmdcblxuICAgIHRoaXMucXVldWVNb2RlbCA9IHF1ZXVlTW9kZWxcblxuICAgIHRoaXMubWFpbGVyID0gbWFpbGVyXG4gIH1cbiAgcHVibGljIGFzeW5jIHByb2Nlc3NRdWV1ZU1haWxzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG9wdGlvbnM6IGFueSA9IHtcbiAgICAgIGxpbWl0OiB0aGlzLmxpbWl0LFxuICAgIH1cblxuICAgIGNvbnN0IHdvcmtlcl91dWlkID0gdXVpZCgpXG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLm1heEF0dGVtcHMgPiAwKSB7XG4gICAgICAgIG9wdGlvbnMud2hlcmUgPSB7XG4gICAgICAgICAgYXR0ZW1wdHM6IHtcbiAgICAgICAgICAgIFtPcC5sdF06IHRoaXMubWF4QXR0ZW1wcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIExvY2sgdGhlIHJvd3NcbiAgICAgIGF3YWl0IHRoaXMucXVldWVNb2RlbC51cGRhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICB3b3JrZXJfdXVpZCxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHdoZXJlOiB7XG4gICAgICAgICAgICAuLi5vcHRpb25zLndoZXJlLFxuICAgICAgICAgICAgd29ya2VyX3V1aWQ6IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgfVxuICAgICAgKVxuXG4gICAgICAvLyBHZXQgdGhlIHJvd3Mgb2YgdGhlIHdvcmtlclxuICAgICAgb3B0aW9ucy53aGVyZSA9IHtcbiAgICAgICAgLi4ub3B0aW9ucy53aGVyZSxcbiAgICAgICAgd29ya2VyX3V1aWQsXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1haWxzID0gYXdhaXQgdGhpcy5xdWV1ZU1vZGVsLmZpbmRBbGwob3B0aW9ucylcbiAgICAgIC8vIFJlbW92ZSBmcm9tIHF1ZXVlKHByZXZlbnRzIGR1cGxpY2F0ZSBzZW5kcyB3aXRoIG11bHRpcGxlIHdvcmtlcnMpXG5cbiAgICAgIGNvbnN0IG1vZGVscyA9IFtdXG4gICAgICBmb3IgKGNvbnN0IG1haWwgb2YgbWFpbHMpIHtcbiAgICAgICAgY29uc3QgbW9kZWwgPSB0aGlzLnNlbmRRdWV1ZWRNYWlsQW5kRGVsZXRlUm93KG1haWwgYXMgTnNxTWFpbFF1ZXVlKVxuICAgICAgICBtb2RlbHMucHVzaChtb2RlbClcbiAgICAgIH1cblxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwobW9kZWxzKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIHJlc2V0IHdvcmtlcl91dWlkXG4gICAgICBhd2FpdCB0aGlzLnF1ZXVlTW9kZWwudXBkYXRlKFxuICAgICAgICB7XG4gICAgICAgICAgd29ya2VyX3V1aWQ6IG51bGwsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB3aGVyZToge1xuICAgICAgICAgICAgd29ya2VyX3V1aWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfVxuICAgICAgKVxuICAgICAgdGhyb3cgZVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFF1ZXVlZE1haWxBbmREZWxldGVSb3cobW9kZWw6IE5zcU1haWxRdWV1ZSk6IFByb21pc2U8TnNxTWFpbFF1ZXVlPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLm1haWxlci5jb21wb3NlTWFpbEZyb21Nb2RlbChtb2RlbClcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMubWFpbGVyLnNlbmRNYWlsKG1lc3NhZ2UpXG4gICAgICBpZiAoIXJlc3VsdC5hY2NlcHRlZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIHNlbmRpbmcgbWFpbCcpXG4gICAgICB9XG5cbiAgICAgIC8vIFJlbW92ZSBmcm9tIHF1ZXVlXG4gICAgICBhd2FpdCB0aGlzLnF1ZXVlTW9kZWwuZGVzdHJveSh7XG4gICAgICAgIHdoZXJlOiB7XG4gICAgICAgICAgaWQ6IG1vZGVsLmlkLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIHRoaXMubG9nKGBEZWxldGVkIG1haWwgZnJvbSBxdWV1ZSAke21vZGVsLmlkfWAsICdkZWJ1ZycpXG5cbiAgICAgIHJldHVybiBtb2RlbFxuICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgY29uc3QgZSA9IGVyciBhcyBFcnJvclxuICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBzZW5kaW5nIG1haWwgdG8gJHttb2RlbC5lbWFpbF90b31gLCB7XG4gICAgICAgIG1vZGVsLFxuICAgICAgICBlcnJvcjogZS5tZXNzYWdlLFxuICAgICAgICBzdGFjazogZS5zdGFjayxcbiAgICAgIH0pXG4gICAgICBhd2FpdCBtb2RlbC51cGRhdGUoXG4gICAgICAgIHtcbiAgICAgICAgICBsYXN0X2Vycm9yOiBKU09OLnN0cmluZ2lmeShlKSxcbiAgICAgICAgICBhdHRlbXB0czogbW9kZWwuYXR0ZW1wdHMgKyAxLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICAgIGlkOiBtb2RlbC5pZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICApXG4gICAgICByZXR1cm4gbW9kZWxcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvZyhtZXNzYWdlOiBzdHJpbmcsIGxldmVsID0gJ2luZm8nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubG9nZ2luZykge1xuICAgICAgbG9nZ2VyLmxvZyhsZXZlbCwgbWVzc2FnZSlcbiAgICB9XG4gIH1cbn1cbiJdfQ==