adba
Version:
Any DataBase to API
173 lines (172 loc) • 7.11 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import nodemailer from "nodemailer";
import Handlebars from "handlebars";
import { splitAndFlat, t, flatten } from "dbl-utils";
import moment from "moment";
const config = {
EmailProcessModel: null,
SystemModel: null,
colorPrimary: '#ffffff',
attemptsTotal: 3,
maxScheduling: 10,
maxPriorScheduling: 20,
priorOrder: 10,
runningPriorSchedule: false,
runningSchedule: false,
priorDelay: 1000 * 60,
delay: 1000 * 60 * 60,
templates: {}
};
export function setEmailProcessModel(EmailProcessModel) {
config.EmailProcessModel = EmailProcessModel;
}
export function setSystemModel(SystemModel) {
config.SystemModel = SystemModel;
}
export function colorPrimary(color) {
config.colorPrimary = color;
}
export function setConfig(cfg) {
Object.assign(config, cfg);
}
const buildTemplate = (templateName, data) => {
const text = Object.entries(flatten(data)).map(([key, value]) => `${t(key, 'emailKeyTemplate>' + templateName)}: ${t(value, 'emailValueTemplate>' + templateName)}`).join('\n');
let html = text;
let subject = data.subject;
if (config.templates[templateName]) {
const subjectTemplater = Handlebars.compile(config.templates[templateName].subject);
subject = subjectTemplater(data);
const htmlTemplater = Handlebars.compile(config.templates[templateName].template);
html = htmlTemplater(data);
}
return {
subject,
html,
text
};
};
const sendEmail = (to_1, template_1, data_1, ...args_1) => __awaiter(void 0, [to_1, template_1, data_1, ...args_1], void 0, function* (to, template, data, order = 10) {
if (!config.EmailProcessModel)
return false;
const emailElements = buildTemplate(template, data);
const emailProcess = config.EmailProcessModel.fromJson(Object.assign(Object.assign({ emailAddress: splitAndFlat([to]) }, emailElements), { order, active: true }));
try {
const response = yield config.EmailProcessModel.query().insert(emailProcess);
console.log('email scheduled:', response);
return true;
}
catch (err) {
console.error('error scheduling email:');
console.error(err);
return false;
}
});
export const processEmailList = (transporter, emailList) => __awaiter(void 0, void 0, void 0, function* () {
if (!config.EmailProcessModel)
return false;
for (const emailDoc of emailList) {
if (['archived', 'completed'].includes(emailDoc.status))
continue;
try {
yield transporter.sendMail({
from: emailDoc.from,
to: emailDoc.emailAddress,
html: emailDoc.html,
text: emailDoc.text,
attachments: emailDoc.attachments,
cc: emailDoc.cc,
bcc: emailDoc.bcc,
subject: emailDoc.subject,
});
console.log(`Email sent to ${emailDoc.emailAddress}`);
emailDoc.status = 'completed';
emailDoc.lastAttempt = moment().format('YYYY-mm-dd HH:mm:ss');
emailDoc.active = false;
}
catch (error) {
console.error('Failed to send email:', error);
emailDoc.attempts += 1;
emailDoc.lastAttempt = moment().format('YYYY-mm-dd HH:mm:ss');
emailDoc.status = emailDoc.attempts > config.attemptsTotal ? 'archived' : 'failed';
}
yield config.EmailProcessModel.query().update(emailDoc).catch(e => console.error(e));
}
});
export const enqueueEmailList = (transportConf) => __awaiter(void 0, void 0, void 0, function* () {
if (!config.SystemModel)
return false;
if (!config.EmailProcessModel)
return false;
let t9r;
try {
//configuration of oauth2.0
/* const sysTokens: ISystemConfigModel | null =
await config.SystemModel.query().findOne({ name: 'emailTokens' }) as ISystemConfigModel | null;
if (!sysTokens || !sysTokens.value) throw new Error('Email OAuth2 not configured');
const refreshToken = sysTokens.value;
{
service: process.env.EMAIL_SERVICE,
auth: {
type: 'OAuth2',
user: process.env.EMAIL_USER,
clientId: process.env.EMAIL_CLIENT_ID,
clientSecret: process.env.EMAIL_CLIENT_SECRET,
refreshToken
}
} */
t9r = yield new Promise((resolve, reject) => {
const transporter = nodemailer.createTransport(transportConf);
transporter.verify((error, success) => {
if (error) {
console.error('Error connecting to the SMTP server:', error);
reject(error);
}
else {
console.log('Server is ready to send emails:', success);
resolve(transporter);
}
});
});
}
catch (error) {
console.error('[ERROR]', error);
return false;
}
console.log('enqueue emails');
setInterval(() => __awaiter(void 0, void 0, void 0, function* () {
config.runningPriorSchedule = true;
const emailList = yield config.EmailProcessModel.query()
.where('order', '<=', config.priorOrder)
.whereNotIn('status', ['completed', 'expired', 'archived'])
.where('attempts', '<=', config.attemptsTotal)
.orderBy('order', "ASC")
.limit(config.maxPriorScheduling);
console.log('emailList prior:', emailList.length);
yield processEmailList(t9r, emailList);
config.runningPriorSchedule = false;
}), config.priorDelay);
setInterval(() => __awaiter(void 0, void 0, void 0, function* () {
if (config.runningPriorSchedule)
return;
config.runningSchedule = true;
const emailList = yield config.EmailProcessModel.query()
.where('order', '>', config.priorOrder)
.whereNotIn('status', ['completed', 'expired', 'archived'])
.where('attempts', '<=', config.attemptsTotal)
.orderBy('order', "ASC")
.limit(config.maxScheduling);
console.log('emailList standard:', emailList.length);
yield processEmailList(t9r, emailList);
config.runningSchedule = false;
}), config.delay);
return true;
});
export default sendEmail;