You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.0 KiB

// newsletter/job/transmit.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0
'use strict';
const path = require('path');
const mongoose = require('mongoose');
const User = mongoose.model('User');
const NewsletterRecipient = mongoose.model('NewsletterRecipient');
const { SiteWorkerProcess } = require(path.join(__dirname, '..', '..', '..', '..', 'lib', 'site-lib'));
class NewsletterTransmitJob extends SiteWorkerProcess {
static get COMPONENT ( ) {
return {
logId: 'newsletter-transmit-job',
index: 'newsletterTransmitJob',
className: 'NewsletterTransmitJob',
};
}
constructor (worker) {
super(worker, NewsletterTransmitJob.COMPONENT);
}
async start ( ) {
await super.start();
this.queue = await this.getJobQueue('newsletter', this.dtp.config.jobQueues.newsletter);
this.log.info('registering job processor', { queue: this.queue.name, name: 'transmit' });
this.queue.process('transmit', this.processTransmit.bind(this));
}
async stop ( ) {
await super.stop();
}
async processTransmit (job) {
const { newsletterId } = job.data;
this.log.info('newsletter email job received', { id: job.id, newsletterId });
try {
/*
* Transmit first to all local user accounts with verified email who've
* opted in for receiving marketing email.
*/
await User
.find({
'flags.isEmailVerified': true,
'optIn.marketing': true,
})
.select('email displayName username username_lc')
.lean()
.cursor()
.eachAsync(async (user) => {
try {
const jobData = {
newsletterId: newsletterId,
recipient: user.email,
recipientName: user.displayName || user.username,
};
const jobOptions = { attempts: 3 };
await this.queue.add('email-send', jobData, jobOptions);
} catch (error) {
this.log.error('failed to create newsletter email job', { error });
}
}, { parallel: 4 });
/*
* Transmit to all newsletter recipients on file who've joined through the
* widget on the site w/o signing up for an account.
*/
await NewsletterRecipient
.find({ 'flags.isVerified': true, 'flags.isOptIn': true, 'flags.isRejected': false })
.lean()
.cursor()
.eachAsync(async (recipient) => {
try {
const jobData = {
newsletterId: newsletterId,
recipient: recipient.address,
};
const jobOptions = { attempts: 3 };
await this.queue.add('email-send', jobData, jobOptions);
} catch (error) {
this.log.error('failed to create newsletter email job', { error });
}
}, { parallel: 4 });
} catch (error) {
this.log.error('failed to send newsletter', { newsletterId, error });
throw error;
}
}
}
module.exports = NewsletterTransmitJob;