0

How can I correctly get mailOptions in triggerExample.ts?

mail.ts:

export const sendNewMail = async (html: string, emails: string[]) => {
  let smtpTransport = nodemailer.createTransport({
    service: "Gmail",
    auth: {
      user: "...",
      pass: "...",
    },
  });
  };

triggerExample.ts:

import { sendNewMail  } from "../../mail.ts";

const ordersExample = await getExample();
    ordersExample.forEach(async order => {
      const email = order.sentEmails.email
let html = ` ...
         <img src="cid:image" width="100%" />

`;

      await sendNewMail (html,[email]);

how to correctly put this mailOptions with async/await in triggerExample.ts :

  var mailOptions = {
    from: "@gmail.com",
    to: emails,
    subject: "subject",
    html: html,
    attachments: [{
      path: __dirname + '/image.jpg',
      cid: 'image' 
  }],
  };
  return smtpTransport.sendMail(
    mailOptions,
    function (error: Error, response: Response) {
      if (error) {
        errors.logError(error);
      } else {
        console.log(`Message sent to ${errors}`);
      }
    }
  );
  • Hi, you can use a try / catch block to get the error from awaiting the sendmail which accepts your options as a parameter? The result of awaiting the sendmail function gives you info / metadata from the response. Let me know if you need an example. Wondering why you are including the image as an attachment though, you have a specific requirement to do so that you're not just linking to the image that is hosted somewhere? – Craig van Tonder Apr 24 '21 at 21:40
  • yes, please, it will be great if you'll show an example . yes, i need it in attachments , just linking doesn't work for me – Causl Local Apr 24 '21 at 21:53
  • a) You [cannot use `forEach` for asynchronous code](https://stackoverflow.com/a/37576787/1048572). b) that `` method doesn't seem to return a promise, you [need to promisify it](https://stackoverflow.com/q/22519784/1048572). – Bergi Apr 24 '21 at 22:42
  • I don't really understand how the three snippets in your question are related to each other. – Bergi Apr 24 '21 at 22:42

1 Answers1

0

It seems that you understand how to send an email, you also understand how to attach an image to the email. What you do not really understand is how to use this in the scope of a promise?

To help you to better understand the flow of the code and how it would be laid out, I have created an example that you can customise by adding your own content and mail options, you can also convert this to typescript where neccessary:

send.js:

const nodemailer = require('nodemailer')
const config = {
  port: 'your smtp port',
  host: 'your smtp host',
  user: 'your username',
  pass: 'your password',
  from: {
    name: 'Sender Name',
    email: 'Sender Email Address'
  }
}
module.exports = {
  send(payload) {
    return new Promise(async (resolve, reject) => {
      try {
        const { subject, name, email } = payload
        // The plaintext version
        const text = 'Hello World!'
        // The html version
        const html = '<p>Hello World!</p>'
        // create reusable transporter object using the default SMTP transport
        const transporter = nodemailer.createTransport({
          port: config.port,
          host: config.host,
          auth: {
            user: config.user,
            pass: config.pass
          },
          secure: true
        })
        // setup email options here
        const mailOptions = {
          from: `"${config.from.name}" <${config.from.email}>`, // sender address
          to: `"${name}" <${email}>`, // comma seperated list of receivers
          subject, // Subject line
          text, // plain text body
          html // html body
        }
        // send mail with defined transport object
        const info = await transporter.sendMail(mailOptions)
        // Success
        return resolve(info)
      } catch (err) {
        return reject(err)
      }
    })
  },
};

main.js:

const { send } = require('./send.js');

(async () => {
  try {
    const payload = {
      subject: 'Test Email',
      name: 'Some Person',
      email: 'Their Email Address'
    }
    const info = await send(payload)
    console.log('successfully sent the email:')
    console.log(info)
  } catch (err) {
    console.log('failed to send the email:')
    console.log(err)
  }
})();

In the case of a successful outcome:

{ accepted: [ 'name@domain.tld' ],
  rejected: [],
  envelopeTime: 605,
  messageTime: 596,
  messageSize: 620,
  response:
   '250 Ok someidortheother',
  envelope:
   { from: 'sender@senderdomain.tld',
     to: [ 'name@domain.tld' ] },
  messageId: '<messageidblah@senderdomain.tld>' }

I can suggest too that you always include a plaintext version of the email so that it can be rendered in email clients which do not support or have been configured not to display the html body content.

Craig van Tonder
  • 7,497
  • 18
  • 64
  • 109