// 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;