代码之家  ›  专栏  ›  技术社区  ›  psudo

电子邮件发送节点快递后发送响应

  •  0
  • psudo  · 技术社区  · 2 年前

    我有以下方法 /signup 路线:

    const {sendEmail} = require("../lib/email");
    
    exports.signup = async (req, res, next) => {
      try {
           //validate request and save user in DB
        
            let content = {
              activateLink: "link to activate email",
            };
    
          await sendEmail(email, "Verification OTP", "otp", content, next);
    
          res.status(201).json({
           message: "User created successfully !",
           userData: {
           _id: result._id.toString(),
            email: result.email,
           },
          });
      }
        catch (err) {
            if (!err.statusCode) {
              err.statusCode = 500;
            }
            next(err);
      }
    };
    

    发送电子邮件的方法:

    const path = require("path");
    const nodemailer = require("nodemailer");
    const hbs = require("nodemailer-express-handlebars");
    const viewPath = path.resolve(__dirname, "../templates/views");
    const partialsPath = path.resolve(__dirname, "../templates/partials");
    const config = require("../config");
    
    exports.sendEmail = async (to, subject, viewName, content, next) => {
        try {
          const transporter = nodemailer.createTransport(config.mailConfig);
          const handlebarsOptions = {
            viewEngine: {
              extName: ".handlebars",
              layoutsDir: viewPath,
              defaultLayout: false,
              partialsDir: partialsPath,
            },
            viewPath: viewPath,
            extName: ".handlebars",
          };
      
          transporter.use("compile", hbs(handlebarsOptions));
      
          const mailOptions = {
            from: "noreply@admin.com", // Update from email
            to: to,
            subject: subject,
            template: viewName,
            context: content,
          };
      
          let info = await transporter.sendMail(mailOptions);
          console.log("Message sent: %s", info.messageId);
        } catch (e) {
          next(e);
        }
      };
    

    使用以上代码块。当我发送帖子请求时,我可以向新注册的用户发送电子邮件。但邮递员一直在发送请求,在发送电子邮件后并没有得到任何响应状态和消息。

    我认为代码执行并没有脱离 sendEmail 方法正在添加 return true; 之后 console.log("Message sent: %s", info.response); 也于事无补。

    如果有人能帮我找出解决办法,我将不胜感激。

    0 回复  |  直到 2 年前
        1
  •  1
  •   Erwin van Hoof    2 年前

    最新编辑 在您提到的注释中,它是中间件,使用(req,res,next)的函数签名是正确的。

    但当我看到你在评论中的那句话时 router.post("/user/signup",UserController.signup); 这是一个正常的路由,签名应该是(req,res)。

    那么你可以试试吗

    const {sendEmail} = require("../lib/email");
    
    exports.signup = async (req, res) => {
      try {
           //validate request and save user in DB
    
            let content = {
              activateLink: "link to activate email",
            };
    
          const result = await sendEmail(email, "Verification OTP", "otp", content);
    
          res.status(201).json({
           message: "User created successfully !",
           userData: {
           _id: result._id.toString(),
            email: result.email,
           },
          });
      } 
      catch (err) {
        console.log(`Something went wrong sending activation mail`, err);
        throw new Error(err);
      }
    };
    
    import { rejects } from "assert";
    
    exports.sendEmail = async (to, subject, viewName, content) => {
    
        return new Promise((resolve, reject) => {
          const transporter = nodemailer.createTransport(config.mailConfig);
          const handlebarsOptions = {
            viewEngine: {
              extName: ".handlebars",
              layoutsDir: viewPath,
              defaultLayout: false,
              partialsDir: partialsPath,
            },
            viewPath: viewPath,
            extName: ".handlebars",
          };
    
          transporter.use("compile", hbs(handlebarsOptions));
    
          const mailOptions = {
            from: "noreply@admin.com", // Update from email
            to: to,
            subject: subject,
            template: viewName,
            context: content,
          };
    
          let info = transporter.sendMail(mailOptions, (err, result) => {
                if (err) {
                    reject(err);
                    return;
                }
                console.log("Message sent: %s", result.messageId);
                resolve(result);
           });
        });
    };
    

    您正在使用哪个版本的nodemailer?6.4.1之前的版本不会返回Promise,因此您需要使用回调。

    通过回调,代码将如下所示:

    const {sendEmail} = require("../lib/email");
    
    exports.signup = async (req, res, next) => {
      try {
           //validate request and save user in DB
        
            let content = {
              activateLink: "link to activate email",
            };
    
          const result = await sendEmail(email, "Verification OTP", "otp", content, next);
    
          res.status(201).json({
           message: "User created successfully !",
           userData: {
           _id: result._id.toString(),
            email: result.email,
           },
          });
      }
        catch (err) {
            if (!err.statusCode) {
              err.statusCode = 500;
            }
            next(err);
      }
    };
    
    import { rejects } from "assert";
    
    exports.sendEmail = async (to, subject, viewName, content) => {
    
        return new Promise((resolve, reject) => {
          const transporter = nodemailer.createTransport(config.mailConfig);
          const handlebarsOptions = {
            viewEngine: {
              extName: ".handlebars",
              layoutsDir: viewPath,
              defaultLayout: false,
              partialsDir: partialsPath,
            },
            viewPath: viewPath,
            extName: ".handlebars",
          };
      
          transporter.use("compile", hbs(handlebarsOptions));
      
          const mailOptions = {
            from: "noreply@admin.com", // Update from email
            to: to,
            subject: subject,
            template: viewName,
            context: content,
          };
      
          let info = transporter.sendMail(mailOptions, (err, result) => {
                if (err) {
                    reject(err);
                    return;
                }
                console.log("Message sent: %s", result.messageId);
                resolve(result);
           });
        });
    };
    

    您需要从返回结果(信息) let info = await transporter.sendMail(mailOptions); signup 方法

            _id: result._id.toString(), <-- result will be undefined here
            email: result.email,        <-- result will be undefined here
    
        2
  •  0
  •   origeva    2 年前

    您的代码应该可以正常工作。 由于我们遗漏了一些代码, 我只能认为可能发生了以下情况之一:

    1. Express字符串化结果失败.email(循环JSON)
    2. transporter.sendMail()promise未解析(是否显示“Message sent:…”日志?)

    你能发布控制台日志吗?

    无论如何,我建议将您的sendEmail函数与捕获错误并将错误传递给下一个函数的职责分开,因为整个函数都被一个try-catch块包围,所以您还可以让sendEmail抛出并捕获它,就像您已经在做的那样。 现在sendEmail不必由快速路由/中间件调用