Author: saqibkhan

  • Email Templates with Dynamic Content

    For more dynamic content within email templates, you can use template engines with placeholders. For instance, you can use Handlebars or Pug for advanced templating.

    Example with Handlebars and Nodemailer:

    Install Handlebars:

    npm install handlebars nodemailer-express-handlebars
    

    Set Up Handlebars:

    const nodemailer = require('nodemailer');
    const hbs = require('nodemailer-express-handlebars');
    const path = require('path');
    
    // Create a transporter object
    let transporter = nodemailer.createTransport({
    
    service: 'gmail',
    auth: {
        user: process.env.EMAIL_USER,
        pass: process.env.EMAIL_PASS
    }
    }); // Configure Handlebars transporter.use('compile', hbs({
    viewEngine: {
        extName: '.hbs',
        layoutsDir: path.resolve('./views/'),
        defaultLayout: 'template',
    },
    viewPath: path.resolve('./views/'),
    extName: '.hbs'
    })); // Email options let mailOptions = {
    from: '"Your Name" <[email protected]>',
    to: '[email protected]',
    subject: 'Welcome!',
    template: 'welcome', // 'welcome.hbs'
    context: {
        name: 'John Doe',
        activationLink: 'https://example.com/activate?token=123456'
    }
    }; // Send email transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.error('Error sending email:', error);
    }
    console.log('Email sent successfully:', info.response);
    });

    Template File (views/welcome.hbs):

    <!DOCTYPE html>
    <html>
    <head>
    
    &lt;title>Welcome {{name}}&lt;/title>
    </head> <body>
    &lt;h1>Welcome, {{name}}!&lt;/h1>
    &lt;p>Please activate your account by clicking &lt;a href="{{activationLink}}">here&lt;/a>.&lt;/p>
    </body> </html>
  • Rate Limiting and Throttling

    When sending a large number of emails, implement rate limiting or throttling to avoid being marked as spam or hitting rate limits of your email provider. Libraries like bottleneck can help with this.

    Example with Bottleneck:

    const Bottleneck = require('bottleneck');
    const limiter = new Bottleneck({
    
    maxConcurrent: 2,
    minTime: 500 // milliseconds
    }); const sendEmail = limiter.wrap(async (emailOptions) => {
    await transporter.sendMail(emailOptions);
    }); // Add jobs to send emails sendEmail({ to: '[email protected]', subject: 'Throttled Email', text: 'This email is sent with throttling.' });
  • Sending Emails from Multiple Accounts

    If you need to send emails from multiple accounts, create multiple transporters and choose one based on the recipient or other criteria.

    const transporter1 = nodemailer.createTransport({
    
    service: 'gmail',
    auth: {
        user: '[email protected]',
        pass: 'password1'
    }
    }); const transporter2 = nodemailer.createTransport({
    service: 'yahoo',
    auth: {
        user: '[email protected]',
        pass: 'password2'
    }
    }); // Use the appropriate transporter based on some logic const transporter = someCondition ? transporter1 : transporter2;
  • Testing Emails

    To test email functionality without sending real emails, use services like Mailtrap or Ethereal. These services provide a fake SMTP server to capture and view emails.

    Configure Mailtrap:

    let transporter = nodemailer.createTransport({
    
    host: 'smtp.mailtrap.io',
    port: 2525,
    auth: {
        user: process.env.MAILTRAP_USER,
        pass: process.env.MAILTRAP_PASS
    }
    });
  • Email Logging and Tracking

    If you need to track email opens or clicks, integrate with an email tracking service or use webhooks. Services like Mailgun or SendGrid provide these features.

    Example with Mailgun:

    const mailgun = require('mailgun-js');
    const mg = mailgun({ apiKey: process.env.MAILGUN_API_KEY, domain: process.env.MAILGUN_DOMAIN });
    
    const data = {
    
    from: 'Your Name &lt;[email protected]>',
    to: '[email protected]',
    subject: 'Hello',
    text: 'Hello world!'
    }; mg.messages().send(data, (error, body) => {
    if (error) {
        console.error('Error sending email:', error);
    } else {
        console.log('Email sent successfully:', body);
    }
    });
  • Handling Large Attachments

    For sending large attachments, consider using a file hosting service like AWS S3 and include a link to the file in your email instead of attaching the file directly.

    Example:

    let mailOptions = {
    
    from: '"Your Name" &lt;[email protected]>',
    to: '[email protected]',
    subject: 'Large File',
    text: 'Please download the file from the following link: https://s3.amazonaws.com/your-bucket/large-file.zip',
    html: '&lt;p>Please download the file from the following link: &lt;a href="https://s3.amazonaws.com/your-bucket/large-file.zip">Download&lt;/a>&lt;/p>'
    };
  • Using Email Queues

    To handle high volumes of emails or to ensure reliable delivery, consider using an email queue. Libraries like Bull or Agenda can help with this.

    Example using Bull:

    Install Bull and Redis:

    npm install bull
    

    Set up a Bull queue:

    const Bull = require('bull');
    const nodemailer = require('nodemailer');
    const redis = require('redis');
    
    // Create a Redis client
    const redisClient = redis.createClient();
    
    // Create a Bull queue
    const emailQueue = new Bull('email', { redis: redisClient });
    
    // Create a transporter object
    const transporter = nodemailer.createTransport({
    
    service: 'gmail',
    auth: {
        user: process.env.EMAIL_USER,
        pass: process.env.EMAIL_PASS
    }
    }); // Process email jobs emailQueue.process(async (job) => {
    const { to, subject, text } = job.data;
    await transporter.sendMail({ from: process.env.EMAIL_USER, to, subject, text });
    }); // Add a job to the queue emailQueue.add({
    to: '[email protected]',
    subject: 'Queued Email',
    text: 'This email was sent using a Bull queue.'
    });
  • Using HTML Templates

    If you need to send dynamic HTML emails, consider using templating engines like Handlebars or EJS. Here’s how you might use Handlebars with Nodemailer:

    Install the required packages:

    npm install handlebars nodemailer-express-handlebars
    

    Set up Nodemailer with Handlebars:

    const nodemailer = require('nodemailer');
    const path = require('path');
    const hbs = require('nodemailer-express-handlebars');
    
    // Create a transporter object
    let transporter = nodemailer.createTransport({
    
    service: 'gmail',
    auth: {
        user: process.env.EMAIL_USER,
        pass: process.env.EMAIL_PASS
    }
    }); // Set up Handlebars transporter.use('compile', hbs({
    viewEngine: {
        extName: '.hbs',
        partialsDir: path.resolve('./views/'),
        layoutsDir: path.resolve('./views/'),
        defaultLayout: 'email'
    },
    viewPath: path.resolve('./views/'),
    extName: '.hbs'
    })); // Email options let mailOptions = {
    from: '"Your Name" &lt;[email protected]>',
    to: '[email protected]',
    subject: 'Hello with Handlebars',
    template: 'email', // Name of the template file (email.hbs)
    context: { // Data to pass to the template
        name: 'Recipient',
        message: 'This is a test email using Handlebars!'
    }
    }; // Send email transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        return console.error('Error sending email:', error);
    }
    console.log('Email sent successfully:', info.response);
    });

    Template file (views/email.hbs):

    <!DOCTYPE html>
    <html>
    <head>
    
    &lt;title>{{subject}}&lt;/title>
    </head> <body>
    &lt;h1>Hello, {{name}}!&lt;/h1>
    &lt;p>{{message}}&lt;/p>
    </body> </html>
  • Sending to Multiple Recipients

    You can send emails to multiple recipients by separating email addresses with commas:

    to: '[email protected], [email protected]'
    
  • Handling Errors

    Always handle errors gracefully:

    transporter.sendMail(mailOptions, (error, info) => {
    
    if (error) {
        return console.error('Error sending email:', error);
    }
    console.log('Email sent successfully:', info.response);
    });