Email opened/not tracking from nodejs nodemailer

人盡茶涼 提交于 2019-12-05 10:46:36

I am not 100% sure if what i am posting is the correct way to do it but i figured out a way to make it work. Since this post did not get any valid answer all this time and i see some people viewing it i am answering my own question

You cannot track the opening of email if you send the 1px pic along with email as attachments using node-mailer as it will automatically render and send the file along with mail.(no external call made to server = you cannot detect). Render HTML using node-mailer as you do generally and input a pic with source to a route in your server like shown below

<html>
   <body>
      <img src="http://YOUR_SITE.com/track/this/image/UNIQUE_ID_FOR_THIS_IMAGE.jpg">
   </body>
</html>

Now you have no attachments in your node-mailer and the file is not sent along with email, but will be fetched to render when someone opens the email.

You can track who opened the email using the unique key in url.

P.S. Don't forget to send a (1x1)px img file back for the request. so that no 404 error occurs on the client side.

Inject an html line after the body of the email containing the . You can also attach files to SES outbound emails but it's advisable not to go like this.

EDIT: This answer is useless because the URL is resolved by nodemailer before sending the email. Still going to leave it here, as it may point someone to the right direction.


As of nodemailer version 1.3.4, you can use URLs as attachments, eg:

attachments: [
{
  filename: 'receipt.png',
  path: 'http://example.com/email-receipt?id=1\&email=ex@ample.com',
  cid: 'receipt@example.com'
}
//...

Then, you just embed it in your HTML:

<img src="cid:receipt@example.com">

That will do the trick. Might be useful to mention that, in my case, the URL returns a file download.

I still can't understand if the URL is resolved by nodemailer, while packing, or by the email client. But something is doing it because I've tested Thunderbird and Geary (desktop), Gmail and Rainloop (browser) and it's working.

Can't guarantee that will work in every case, though.

I am little late to be answering this question. I too wanted to track mails so after a little research came up with the below solution. Probably not the best but I guess it will work fine.

    var mailOptions = {
        from: 'Name <email@gmail.com>', // sender address
        to: 'email2@gmail.com', // list of receivers
        subject: 'Hello', // Subject line
        text: 'Hello world', // plaintext body
        html: {
          path : 'mail.html'
        }, // html body
        attachments: [{
          filename : "fileName.txt",
          path : 'fileName.txt'
        }]
    };

The above is the code for mailoptions of nodeMailer.

    <p>
      Hello User,
        What is required to do the above things?
    </p>

    <img src="http://localhost:8080/" alt="" />

The above is mail.html

I setup a server that would handle requests. And then I wrote a middleware which would be used for analysis.

    var express = require('express');
    var app = express();

    app.use(function (req, res, next) {
      console.log("A request was made for the image");
      next();
    });

    app.get('/', function (req, res) {
      var fs = require('fs');
      fs.readFile('image.jpeg',function(err,data){
        res.writeHead('200', {'Content-Type': 'image/png'});
        res.end(data,'binary');
      });
    });

    var server = app.listen(8080, function () {
      var host = server.address().address;
      var port = server.address().port;
    });

So when we request to the image we will log "A request was made for the image". Make changes to the above snippets to get things working. Some of the things that I did and failed were serving the image as a static. This did render the image but it did not log when the image was accessed. That being the reason for the image to be read and served.

One more thing since my server is localhost the image wasn't rendered in the mail. But I think it should work fine if all the things were hosted on a server.

EDIT: The get request can also be

    app.get('/', function (req, res) {
      var buf = new Buffer([
        0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00,
        0x80, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x2c,
        0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02,
        0x02, 0x44, 0x01, 0x00, 0x3b]);
        res.writeHead('200', {'Content-Type': 'image/png'});
        res.end(buf,'binary');
    });
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!