0

I want to send a payment form inside an email using node.js nodemailer.

My emails are successfully sent, but when I add an HTML file that I created the email has errors.

const fs = require("fs");
const { promisify } = require("util");
const readFile = promisify(fs.readFile);

let transporter = nodemailer.createTransport({
  service: "gmail",
  auth: {
    user: "mymail",
    pass: "mypass",
  },
});

let mailOptions = {
          from: "[email protected]",
          to: invoice.customeremail,
          subject: "Payment forServices",
          text: "Please pay to Recieve the order ",
          html: readFile("C://Users//admin//task//payment.html", "utf8"),
        };

        transporter.sendMail(mailOptions, function (err, data) {
          if (err) {
            console.log("error", err);
          } else {
            console.log("email sent!");
          }
        });

I want the HTML file to be displayed in my email. Is there any way to do that?

5
  • You have turned fs.readFile into a promise, therefore the value of html in mailOptions is a pending promise which is not a valid string. Just use the fs.readFileSync method instead or call await readFile which will give an error because it's not in an async function. Commented Sep 20, 2020 at 12:54
  • error TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer. Received an instance of Promise at validChunk (_stream_writable.js:281:10) at PassThrough.Writable.write (_stream_writable.js:316:21) at PassThrough.Writable.end (_stream_writable.js:585:10) at Immediate._onImmediate (C:\Users\admin\B.O.T task\node_modules\nodemailer\lib\mime-node\index.js:959:46) at processImmediate (internal/timers.js:456:21) { code: 'ESTREAM', command: 'API' } Commented Sep 20, 2020 at 12:58
  • i get this error @Milo Commented Sep 20, 2020 at 12:58
  • @jayzee Wrap your mailoptions and sendMail() into fs.readFile() that will solve your issue. Commented Sep 20, 2020 at 15:34
  • i didn't quite understand Commented Sep 20, 2020 at 15:40

2 Answers 2

1

According to me the right way to send html markup using node mailer can be achieved by wrapping your mailOptions and transporter.sendMail() function into the fs.readFile() like this:

First we will correctly read the html file using fs and when we will have the file in the callback function in the html variable we can send it with the email.

var nodemailer = require('nodemailer');
var fs = require('fs');

var transporter = nodemailer.createTransport({
 service: 'gmail',
 auth: {
   user: '[email protected]',
   pass: 'yourpassword'
 }
});

fs.readFile('Path here', {encoding: 'utf-8'}, function (err, html) {
 if (err) {
   console.log(err);
 } else {
   let mailOptions = {
     from: '[email protected]',
     to: '[email protected]',
     subject: 'Sending Html in node mailer',
     html: html
   };

   transporter.sendMail(mailOptions, function(error, info) {
    if (error) {
     console.log(error);
    } else {
     console.log('Email has been sent: ' + info.response);
    }
  });
 }
});
Sign up to request clarification or add additional context in comments.

7 Comments

i will try that
@jayzee try it and let me know in the comments.
i cant make it work... idk why can u help me on skype or its not possible?
are you getting any error ? I have added the complete file in code. Now Just change the credentials and try!
and replace html with the path?
|
0

I made some modifications to Mohammad Basit's answer to allow me to pass a modified link into the email.

On one line of my html file, I created a link that looks like this:

<a href="mySite.herokuapp.com/resetPassword/#replaceWithLink#">Reset Password</a>

Then I used JavaScript's String replace() method to replace the #replaceWithLink# text with whatever I want after the file is loaded with fs.readFile.

Here's a snippet from my app.js node file:

//Sends password reset email
const sendPassResetEmail = function(emailAddress){
  //email host information
  const transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth:{
      user: process.env.gmailUsr,
      pass: process.env.gmailPass
    }
  });

  fs.readFile('./emails/passwordReset.html', {encoding: 'utf-8'}, (err, data)=>{
    let htmlFile = data;
    htmlFile = htmlFile.replace("#replaceWithLink#", "myOtherLinkTest")

    if(err){
      console.warn("Error getting password reset template: " + err);
    }else{
      transporter.sendMail({
        from:'"TedCounter :)"<EMAIL-ADDRESS-HERE>',
        to: emailAddress,
        subject:"Ted Counter",
        html: htmlFile
      });
    }
  });
}

The result is #replaceWithLink# is replaced with myOtherLinkTest in the email.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.