React + NodeJS - nodemailer google 云函数

React + NodeJS - nodemailer google cloud functions

我正在尝试制作一个 reactJS 应用程序,并希望在人们最终填写表格时发送一些电子邮件。

为此,我首先创建了一个 sendGrid 函数,但不太喜欢延迟和电子邮件模板(以及每天超过 100 封邮件的事实。

然后我读到我可以使用 Nodemailer +(或不使用)express + firebase 和 google 云功能。我写了这个函数:

exports.mailSun = functions.https.onRequest((req, res) => {
  const { name, dest } = req.query;

  var transporter = nodemailer.createTransport({
    service: 'Gmail',
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
        user: 'xxx@gmail.com',
        pass: 'xxx'
  }
  });
  const mailOptions = {
    from: 'hello@sunny.com', // sender address
    to: 'pedrospecter@gmail.com', // list of receivers
    subject: 'Elavtal', // Subject line
    html: '<p>Grattis för ditt nya avtal. Elbolag kommer att kontakta dig inom kort.</p>'// plain text body
  };

return transporter.sendMail(mailOptions, function (err, info) {
  if(err)
    console.log(err)
  else
    console.log(info);
});
}); 

然后我尝试了

exports.sendMail= functions.https.onRequest((req, res) => {

  cors(req, res, () => {

      // getting dest email by query string
      const { name, dest } = req.query;
      var transporter = nodemailer.createTransport({
        service: 'Gmail',
          host: "smtp.gmail.com",
          port: 465,
          secure: true,
          auth: {
              user: 'xxx@gmail.com',
              pass: 'xxx'
        }
        });
      const mailOptions = {
          from: 'Sunny <xxxb@gmail.com>', // Something like: Jane Doe <janedoe@gmail.com>
          to: 'xxx@mail.com',
          subject: 'nytt Avtal', // email subject
          text: `<p Ni har fått ett nytt avtal. Logga in på Sunny för att se kunddetaljer.</p> ` // email content in HTML
      };

      // returning result
      return transporter.sendMail(mailOptions, (erro, info) => {
          if(erro){
              return res.send(erro.toString());
          }
          return res.send('Sent');
      });
  });    
});

谁能帮我解决问题?

我猜你正在尝试使用登录名/密码登录,但你正在使用 oauth2 设置创建传输此外,你应该删除选项中的 from 键,因为 gmail 会用你的电子邮件覆盖它(我不知道它是否会造成错误)。 我还注意到您在邮件选项中使用了文本键,但是在有可用的 html 键时发送了 html(可能会导致一些问题)。


const gmailEmail = functions.config().gmail.email;
const gmailPassword = functions.config().gmail.password;


// create transport 
const mailTransport = nodemailer.createTransport({
  service: "gmail",
  auth: {
    user: gmailEmail,
    pass: gmailPassword
  }
});

exports.sendMail= functions.https.onRequest((req, res) => {

  cors(req, res, () => {


      const mailOptions = {
          to: 'xxx@mail.com',
          subject: 'nytt Avtal', // email subject
          text: `<p Ni har fått ett nytt avtal. Logga in på Sunny för att se kunddetaljer.</p> ` // email content in HTML
      };

      // returning result
      return transporter.sendMail(mailOptions, (erro, info) => {
          if(erro){
              return res.send(erro.toString());
          }
          return res.send('Sent');
      });
  });    
});

还有一些配置与您的 google 帐户有关

  • 接受安全性较低的应用程序google security

  • 关闭验证码unlock captcha

您可以测试您的函数并在 google 云函数控制台中查看错误 gcp / functions 它帮助我调试了同样的问题。

不使用sendMail()方法的回调版本,而是使用Promise版本,如下:

exports.mailSun = functions.https.onRequest((req, res) => {
    const { name, dest } = req.query;

    var transporter = nodemailer.createTransport({
        service: 'Gmail',
        host: 'smtp.gmail.com',
        port: 465,
        secure: true,
        auth: {
            user: 'xxx@gmail.com',
            pass: 'xxx'
        }
    });
    const mailOptions = {
        from: 'hello@sunny.com', // sender address
        to: 'pedrospecter@gmail.com', // list of receivers
        subject: 'Elavtal', // Subject line
        html: '<p>Grattis för ditt nya avtal. Elbolag kommer att kontakta dig inom kort.</p>'// plain text body
    };

    return transporter.sendMail(mailOptions)
        .then(info => {
            res.send("email sent");
        })
        .catch(err => {
            console.log(err);
            res.status(500).send("Error sending mail")
        })
});

doc

If callback argument is not set then the method returns a Promise object. Nodemailer itself does not use Promises internally but it wraps the return into a Promise for convenience. If callback is not defined for sendMail then the method returns a native Promise object instead