Mailgun附件没有显示出来

时间:2016-07-16 20:57:46

标签: node.js forms mailgun

使用Nodejs,我已经能够将表单中上传的文件临时存储到某个位置。从那里开始,我想使用mailgun-js发送附有该文件的电子邮件。

我能够收到电子邮件以显示附件,但附件(在我的测试用例中,我上传普通的png文件)将被破坏。破碎,我的意思是:

borked image

我不确定发生了什么 - 但我似乎找不到其他有问题的人;所以我确定我做错了。我感谢任何帮助。

编辑:如果我对路径进行硬编码(即我将图像放在文件夹中,然后将附件设置为该路径),那么它会正确发送附件,我可以查看它没有问题。

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var https = require('https');
var fs = require('fs-extra');
var busboy = require('connect-busboy');
var multer = require('multer');

var app = express();
var upload = multer(({ dest: __dirname + '/tmp/' }));

// view engine setup
app.set('port', (process.env.PORT || 5000));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(favicon(path.join(__dirname,'public','images','favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(busboy());

// Used for accessing webpages without the .html extension!
var publicdir = __dirname + '/public';
app.use(function(req, res, next) {
  if (req.path.indexOf('.') === -1) {
    var file = publicdir + req.path + '.html';
    fs.exists(file, function(exists) {
      if (exists)
      req.url += '.html';
      next();
    });
  }
  else
  next();
});
app.use(express.static(publicdir));
//end .html extension removal

var type = upload.single('file');
app.post('/submit', type, function(req, res, next) {
  console.log("____ Clicked submit ____");

  //whether or not this form will carry an attachment
  var hasAttachment = (req.body.attachment == '') ? false : true;

  //path of file
  var target_path; //actual image
  var tmp_path;

  var name = req.body.name;
  var email = req.body.email;
  var subject = req.body.subject;
  var message = req.body.message;


  //if there is an attachment, handle getting the file
  if (hasAttachment) {
    tmp_path = req.file.path;

    //The original name of the uploaded file stored in the variable target_path
    target_path = __dirname + '/tmp/' + req.file.originalname;

    //A better way to copy the uploaded file.
    var src = fs.createReadStream(tmp_path);
    var dest = fs.createWriteStream(target_path);
    src.pipe(dest);
  }

  //Use validator to sanitize for valid emails
  var validator = require('validator');
  if (!validator.isEmail(email)) {
    console.log("Not a valid email");
    res.end();
    return;
  }

  //Mailgun api stuff
  var api_key = 'redacted';
  var domain = 'redacted';
  var mailgun = require('mailgun-js')({
    apiKey: api_key,
    domain: domain
  });

  //data for mailgun (to, from, name, etc.)
  var data;

  if (hasAttachment) {
    console.log(target_path);

    data = {
      from: email,
      to: 'myEmail@gmail.com',
      subject: subject + ' - ' + name,
      text: message,
      attachment: target_path
    };
  } else {
    data = {
      from: email,
      to: 'myEmail@gmail.com',
      subject: subject + ' - ' + name,
      text: message
    };
  }

  console.log(data);

  mailgun.messages().send(data, function (error, result) {
    if (error) {
      console.error(error);
      return;
    }
  });

  console.log("Sent an email!!!");
  res.redirect('/contact');

  //delete the files after sending the email
  if (hasAttachment) {
    fs.unlink(target_path);
    fs.unlink(tmp_path);
  }
});

var server = app.listen(app.get('port'), function() {
  //nothing
}); //server closing-bracket



/**
* ERROR HANDLING
*/
// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    console.error("***ERROR: " + err.message);
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

module.exports = app;

1 个答案:

答案 0 :(得分:1)

send()是异步的,您在文件有机会完成之前删除该文件。

相反,一旦确定已完成,请删除send回调中的文件。

<强>更新

除了上述内容之外,您的文件副本也是异步发生的,并且您试图在复制完成之前传输文件。所以一定要等到那个:

dest.on("close", function(error, result) {
  if (error) {
    console.log("COPY ERROR", error);
    // TODO: respond with some error result

  } else {
    mailgun.messages().send(data, function (error, result) {
      // delete the files
      if (hasAttachment) {
        fs.unlink(target_path);
        fs.unlink(tmp_path);
      }

      if (error) {
         console.error(error);
         // TODO: respond with some error result
      } else {
        console.log("Sent an email!!!");
        res.redirect('/contact');
      }
    });
  }
});

上述更改将使您的代码正常工作。

我认为您正在复制文件,以便图像在电子邮件中正确显示。 (Mailgun根据文件扩展名推断如何处理附件,而Multer的默认临时文件名不包含扩展名。)

您可以通过配置Multer来保留文件扩展名,从而完全避免复制。 https://github.com/expressjs/multer#storage