// newsletter.js // Copyright (C) 2021 Digital Telepresence, LLC // License: Apache-2.0 'use strict'; const DTP_COMPONENT_NAME = 'newsletter'; const path = require('path'); require('dotenv').config({ path: path.resolve(__dirname, '..', '..', '.env') }); const mongoose = require('mongoose'); const { SitePlatform, SiteLog } = require(path.join(__dirname, '..', '..', 'lib', 'site-lib')); module.pkg = require(path.resolve(__dirname, '..', '..', 'package.json')); module.config = { componentName: DTP_COMPONENT_NAME, root: path.resolve(__dirname, '..', '..'), }; module.log = new SiteLog(module, module.config.componentName); module.sendNewsletter = async (job) => { module.log.info('newsletter email job received', { data: job.data }); const NewsletterRecipient = mongoose.model('NewsletterRecipient'); try { /* * Create one Bull Queue job per email to be delivered. */ await NewsletterRecipient .find({ 'flags.isVerified': true, 'flags.isOptIn': true, 'flags.isRejected': false }) .lean() .cursor() .eachAsync(async (recipient) => { try { const jobData = { newsletterId: job.data.newsletterId, recipient: recipient.address, }; const jobOptions = { attempts: 3, }; await module.jobQueue.add('email-send', jobData, jobOptions); } catch (error) { module.log.error('failed to create newsletter email job'); // but continue } }, { parallel: 4 }); } catch (error) { module.log('failed to send newsletter', { newsletterId: job.data.newsletterId, error }); throw error; // throw error to Bull so it can report in job reports } }; module.sendNewsletterEmail = async (job) => { const { newsletter: newsletterService, email: emailService } = module.services; const { newsletterId, recipient } = job.data; try { let newsletter = module.newsletters[newsletterId]; if (!newsletter) { newsletter = await newsletterService.getById(newsletterId); module.newsletters[newsletterId] = newsletter; //TODO: clean up memory leak of newsletter (remove when all emails are sent) } if (!newsletter) { throw new Error('newsletter not found'); } const response = await emailService.send({ from: 'demo@wherever.com', to: recipient, subject: newsletter.title, html: newsletter.content.html, text: newsletter.content.text, }); job.log(`newsletter email sent: ${response}`); } catch (error) { module.error('failed to send newsletter email', { newsletterId, recipient, error }); throw error; // throw error to Bull so it can report in job reports } }; (async ( ) => { try { /* * Platform startup */ await SitePlatform.startPlatform(module); const { jobQueue: jobQueueService } = module.services; module.jobQueue = await jobQueueService.getJobQueue('newsletter', { attempts: 3, }); module.jobQueue.process('email', module.sendNewsletter); module.jobQueue.process('email-send', module.sendNewsletterEmail); /* * Worker startup */ module.log.info(`${module.pkg.name} v${module.pkg.version} Newsletter worker started`); } catch (error) { module.log.error('failed to start Newsletter worker', { error }); process.exit(-1); } })();