#!/usr/bin/env ts-node /** * Bulk email sending example using Nodemailer transport */ import nodemailer from 'nodemailer'; import { createTransport } from '../src/index'; async function bulkEmailExample() { console.log('Bulk Email Example using SMTP WebSocket Transport\n'); // Create the WebSocket transport const transport = createTransport({ host: 'localhost', port: 3000, auth: { user: 'your-api-key-here' }, maxQueueSize: 1000, // Handle large queues debug: false // Disable debug for bulk operations }); const transporter = nodemailer.createTransporter(transport); // Sample recipient list const recipients = [ { email: 'user1@example.com', name: 'User One' }, { email: 'user2@example.com', name: 'User Two' }, { email: 'user3@example.com', name: 'User Three' }, { email: 'user4@example.com', name: 'User Four' }, { email: 'user5@example.com', name: 'User Five' } ]; console.log(`Sending emails to ${recipients.length} recipients...\n`); const results = []; const startTime = Date.now(); // Send emails concurrently (transport handles queuing automatically) const emailPromises = recipients.map(async (recipient, index) => { try { const info = await transporter.sendMail({ from: 'newsletter@example.com', to: recipient.email, subject: `Newsletter #${index + 1} - ${new Date().toLocaleDateString()}`, text: `Hello ${recipient.name}!\n\nThis is your personalized newsletter.\n\nBest regards,\nThe Newsletter Team`, html: `
This is your personalized newsletter for ${new Date().toLocaleDateString()}.
This email was delivered via our SMTP WebSocket transport system.
Newsletter #${index + 1} | Sent at ${new Date().toLocaleTimeString()}
` }); console.log(`Email ${index + 1}/${recipients.length} sent to ${recipient.email}`); return { success: true, recipient: recipient.email, messageId: info.messageId, response: info.response }; } catch (error) { console.error(`Failed to send email ${index + 1} to ${recipient.email}:`, (error as Error).message); return { success: false, recipient: recipient.email, error: (error as Error).message }; } }); // Wait for all emails to complete const emailResults = await Promise.allSettled(emailPromises); const duration = Date.now() - startTime; // Process results let successful = 0; let failed = 0; emailResults.forEach((result) => { if (result.status === 'fulfilled') { results.push(result.value); if (result.value.success) { successful++; } else { failed++; } } else { failed++; results.push({ success: false, error: result.reason.message }); } }); // Display summary console.log('\n--- Bulk Email Results ---'); console.log(`Total emails: ${recipients.length}`); console.log(`Successful: ${successful}`); console.log(`Failed: ${failed}`); console.log(`Duration: ${(duration / 1000).toFixed(2)} seconds`); console.log(`Average time per email: ${(duration / recipients.length).toFixed(0)}ms`); // Display failed emails if any if (failed > 0) { console.log('\nFailed emails:'); results.forEach((result, index) => { if (!result.success) { console.log(` ${index + 1}. ${result.recipient || 'Unknown'}: ${result.error}`); } }); } // Close transport await transport.close(); console.log('\nTransport closed'); } // Advanced bulk email with throttling async function throttledBulkEmail() { console.log('\nThrottled Bulk Email Example\n'); const transport = createTransport({ host: 'localhost', port: 3000, auth: { user: 'your-api-key-here' } }); const transporter = nodemailer.createTransporter(transport); // Generate larger recipient list const recipients = Array.from({ length: 20 }, (_, i) => ({ email: `user${i + 1}@example.com`, name: `User ${i + 1}` })); console.log(`Sending throttled emails to ${recipients.length} recipients...`); console.log('Processing 5 emails at a time with 1 second delay between batches\n'); const batchSize = 5; const batches = []; for (let i = 0; i < recipients.length; i += batchSize) { batches.push(recipients.slice(i, i + batchSize)); } let totalSuccessful = 0; let totalFailed = 0; for (let batchIndex = 0; batchIndex < batches.length; batchIndex++) { const batch = batches[batchIndex]; console.log(`Processing batch ${batchIndex + 1}/${batches.length} (${batch.length} emails)...`); const batchPromises = batch.map(async (recipient) => { try { await transporter.sendMail({ from: 'batch@example.com', to: recipient.email, subject: `Batch Email - ${recipient.name}`, text: `Hello ${recipient.name}, this is a batch email.` }); return { success: true, email: recipient.email }; } catch (error) { return { success: false, email: recipient.email, error: (error as Error).message }; } }); const batchResults = await Promise.all(batchPromises); const batchSuccessful = batchResults.filter(r => r.success).length; const batchFailed = batchResults.filter(r => !r.success).length; totalSuccessful += batchSuccessful; totalFailed += batchFailed; console.log(`Batch ${batchIndex + 1} complete: ${batchSuccessful} successful, ${batchFailed} failed`); // Wait between batches (except for the last one) if (batchIndex < batches.length - 1) { await new Promise(resolve => setTimeout(resolve, 1000)); } } console.log(`\nThrottled bulk email complete: ${totalSuccessful} successful, ${totalFailed} failed`); await transport.close(); } // Run the examples if (require.main === module) { (async () => { try { await bulkEmailExample(); await throttledBulkEmail(); console.log('\nBulk email examples completed successfully'); } catch (error) { console.error('\nExamples failed:', error); } finally { process.exit(0); } })(); } export { bulkEmailExample, throttledBulkEmail };