import { config } from './config/index.js'; import { logger } from './utils/logger.js'; import { NewsletterPipeline } from './core/NewsletterPipeline.js'; import { CronScheduler } from './services/scheduler/CronScheduler.js'; import { EmailService } from './services/email/EmailService.js'; async function main() { const args = process.argv.slice(2); const runNow = args.includes('--run-now'); const dryRun = args.includes('--dry-run'); if (dryRun) { process.env.DRY_RUN = 'true'; } logger.info( { runNow, dryRun: config.features.dryRun || dryRun, cronSchedule: config.scheduler.cronExpression, timezone: config.scheduler.timezone, recipients: config.email.recipients.length, }, 'X-Newsletter starting' ); const pipeline = new NewsletterPipeline(); if (runNow) { logger.info('Running newsletter pipeline immediately'); const result = await pipeline.run(); if (result.success) { logger.info('Newsletter sent successfully'); process.exit(0); } else { logger.error({ errors: result.errors }, 'Newsletter pipeline failed'); process.exit(1); } } // Verify email connection on startup const emailService = new EmailService(); const emailConnected = await emailService.verifyConnection(); if (!emailConnected) { logger.warn('Email service connection could not be verified - will retry on send'); } // Set up scheduled execution const scheduler = new CronScheduler(); scheduler.schedule( 'daily-newsletter', config.scheduler.cronExpression, async () => { const result = await pipeline.run(); if (!result.success) { logger.error({ errors: result.errors }, 'Scheduled newsletter failed'); } }, { timezone: config.scheduler.timezone } ); scheduler.start(); logger.info( { schedule: config.scheduler.cronExpression, timezone: config.scheduler.timezone, }, 'Newsletter scheduler started. Waiting for next scheduled run...' ); // Handle graceful shutdown const shutdown = () => { logger.info('Shutting down...'); scheduler.stop(); process.exit(0); }; process.on('SIGTERM', shutdown); process.on('SIGINT', shutdown); // Keep the process running await new Promise(() => {}); } main().catch((error) => { logger.error({ error }, 'Fatal error'); process.exit(1); });