0

I am attempting to send an email using Nodemailer and Twilio Sendgrid, following the tutorial here. As far as I can tell I am following the instructions in the tutorial, as well as theNodemailer and Sendgrid documentation. Every time this method is called, the code in the catch block executes, and I get the error Error: Missing credentials for "PLAIN".

My question was closed due to association with the question here, however my problem is different and none of the solutions on the thread apply. I am using my own domain to send, not gmail.com. I want to solve the problem without using Oauth2, which from what I understand I should not need, given that I am using an email domain I control. Also I am already using pass' rather than 'password for my authorization data (the top solution on the associated answer).

I've been stuck on this for a few days now , and I'd appreciate any insight anyone can offer!

Here is my code:

async function sendEmail(email, code) {
    try{
        const smtpEndpoint = "smtp.sendgrid.net";
        const port = 465;
        const senderAddress = 'Name "contact@mydomain.com"';
        const toAddress = email;
        const smtpUsername = "apikey";
        const smtpPassword = process.env.SG_APIKEY;
        const subject = "Verify your email";

        var body_html = `<!DOCTYPE> 
        <html>
          <body>
            <p>Your authentication code is : </p> <b>${code}</b>
          </body>
        </html>`;

        let transporter = nodemailer.createTransport({
          host: smtpEndpoint,
          port: port,
          secure: true, 
          auth: {
            user: smtpUsername,
            pass: smtpPassword,
          },
          logger: true,
          debug: true,
        });
        
        let mailOptions = {
          from: senderAddress,
          to: toAddress,
          subject: subject,
          html: body_html,
        };

        let info = await transporter.sendMail(mailOptions);
        return { error: false };
    } catch (error) {
    console.error("send-email-error", error);

    return {
      error: true,
      message: "Cannot send email",
    };
  }
}

And here is the log: error log in bash terminal

Thanks!

2 Answers2

1

You have already identified the issue of API key not being passed into the Nodemailer transport. While hardcoding the key is a possible solution, it's not a good practice. Usually secrets and keys are managed via environment variables so they are, for example, not accidentally committed to a repository and can be configured externally without changing the code.

In the tutorial you linked, working with the environment variable is addressed, but I see there is a mistake with .env file. So let me try to recap how to properly get SG_APIKEY from environment variable and .env file.

  • In your project directory create the .env file with the following contents:
    SG_APIKEY=<your_sendgrid_api_key>
    
    (obviously replace <your_sendgrid_api_key> with your actual API key)
  • Make sure dotenv package is installed: npm i dotenv
  • At the beginning of the file where you use Nodemailer, add the following line:
    require("dotenv").config();
    
    This will ensure the SG_APIKEY is loaded from .env file.
  • You can check if the env variable is set correctly with console.log(process.env.SG_APIKEY)
jnv
  • 882
  • 10
  • 18
0

A comment on the (closed) previous version of this thread solved the problem for me:

enter image description here

  • I don't think posting the question again makes sense when the previous was closed. I do agree folks a trigger happy on closing questions here. I'll vote to reopen yours, although I don't think it'll get enough votes... – Swimburger May 22 '22 at 19:38
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 23 '22 at 01:24
  • @Swimburger thank you. I'm pretty new to Stackoverflow and I can't complain, nor do I want to criticize anyone. I reposted the question because I had missed the comment on the previous version of the thread that ultimately solved the issue, and I was still seeking an answer. I tried to clarify the distinction from other threads in my repost. When the issue was resolved I wanted to include the answer here in case it could be helpful to someone, and to give credit where it was due. I'm very open to suggestions regarding StackOverflow etiquette. – Ryan Schafer Jun 23 '22 at 03:22
  • @RyanSchafer, it's all good. I'm glad you got your answer, that's what's most important! – Swimburger Jun 23 '22 at 14:57