Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Duplicate emails sent and timeout #32

Closed
mkey opened this Issue June 08, 2012 · 3 comments

2 participants

mkey eleith
mkey
mkey commented June 08, 2012

Hello.

I've been messing around with various email sending solutions for nodejs and after trying to use nodemailer now I'm getting the same issue with emailjs.

I'm using the following:

windows 32bit XP
nodejs 0.6.19
the latest emailjs (installed with npm --force)
precompiled windows binaries for buffertools from here https://github.com/springmeyer/node-buffertools/tree/win-binary (basically, I just deleted the content of "emailjs\node_modules\buffertools\" and unpacked the archived files from the above mentioned repository into it)

This is the code I'm currently using to send some test emails

var email= require("emailjs"),
server= email.server.connect({
    user:       "sender@gmail.com",
    password:   "sender_password",
    host:       "smtp.gmail.com",
    ssl:        true
});

server.send({
    text:       'www.google.com Confirm',
    from:       "Sender <sender@gmail.com>",
    to:         "receiver@gmail.com",
    subject:    "test confirmation",
    attachment: [
        {
            data:           '<a href="www.google.com">Confirm</a>',
            alternative:    true
        }
    ]
}, function(e, r){
    console.log(e);
    console.log(r);
});

This is my console log

Express server listening on port 8080 in development mode
null
{ attachments: [],
alternative:
{ data: 'Confirm',
alternative: true,
charset: 'utf-8',
type: 'text/html',
inline: true },
header:
{ 'message-id': '1339153866494.0.1600@PC',
from: 'Sender sender@gmail.com',
to: 'receiver@gmail.com',
subject: 'test confirmation' },
content: 'text/plain; charset=utf-8',
text: 'www.google.com Confirm' }
null
{ attachments: [],
alternative:
{ data: 'Confirm',
alternative: true,
charset: 'utf-8',
type: 'text/html',
inline: true },
header:
{ 'message-id': '1339153986421.1.1600@PC',
from: 'Sender sender@gmail.com',
to: 'receiver@gmail.com',
subject: 'test confirmation' },
content: 'text/plain; charset=utf-8',
text: 'www.google.com Confirm' }

I received two emails on my gmail account, the second coming in 2 minutes after the first has arrived. On my client side javascript I have a function waiting for server response, it times out after additional 2 minutes, making a total of 4 after sending the first email.

eleith
Owner
eleith commented June 08, 2012

if i just run your script in an independent file, i can't replicate your experience.

it is possible there is something else in your script that is causing the server.send to run twice.

if you can put together a more complete gist of how you are calling this script from within express, we might have a better chance at seeing what is happening.

but for now, it seems like the error has more to do with your environment rather than emailjs in particular. please let me know if you do end up being able to narrow down the problem a bit.

mkey
mkey commented June 08, 2012

These are very simple scripts, I have just stared working on my project and I'm trying to modularize it as much as possible for the time being.
The only thing that stands out, I'm running this script locally, don't know if that can cause this problem.

The server.js file

var express = require('express'),
app         = express.createServer(),
email       = require('./routes/email'),
main        = require('./routes/main');

// Configuration
app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({ secret: 'little kitty' }));
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
    app.use(express.errorHandler());
});

// Routes
app.get('/', main.index);
app.post('/confirmation', email.index);

app.listen(process.env['PORT_WWW'] || 8080, function(){
    console.log('Express server listening on port %d in %s mode', app.address().port, app.settings.env);
});

The main.js file - client side. Attaches an event listener to a button on the page.

if (window.addEventListener) window.addEventListener("load", Init, false);
else if (window.attachEvent) window.attachEvent("onload", Init);
else if (window.onLoad) window.onload= Init;

function Init(){
    document.getElementById('email').addEventListener('click', function(){
        Request("/confirmation", "token="+document.getElementById('token').value, function(r){
            alert(r.responseText);
        });
    }, false);
}

function Request(url, data, f){
    var r= new XMLHttpRequest();
    if (!r) return;
    r.open((data) ? "POST" : "GET", url, true);
    // r.setRequestHeader('User-Agent','XMLHTTP/1.0');
    if (data) r.setRequestHeader('Content-type','application/x-www-form-urlencoded');
    r.onreadystatechange = function (){
        if (r.readyState!=4) return;
        if (r.status!=200 && r.status!=304){ alert('HTTP error '+r.status); return }
        if (f) f(r);
    }
    if (r.readyState==4) return;
    r.send(data);
}

The email.js file, responding to the "confirmation" request.

exports.index= function(req, res){
    if (!req.session.auth || req.body.token!=req.session.token)
        res.redirect('/');
    else {
var email= require("emailjs"),
server= email.server.connect({
    user:       "@gmail.com",
    password:   "",
    host:       "smtp.gmail.com",
    ssl:        true
});

console.log("--- sending mail ---");
server.send({
    text:       'www.google.com Confirm',
    from:       " <@gmail.com>",
    to:         "@gmail.com",
    subject:    "test confirmation",
    attachment: [
        {
            data:           '<a href="www.google.com">Confirm</a>',
            alternative:    true
        }
    ]
}, function(e, r){
    console.log(e);
    console.log(r);
});

    }
};

The main.js file - server side. This one renders the page where the button sending mail is located.

var lang=   require('../routes/lang'),
tb=         require('../toolbox.js');

exports.index= function(req, res){
    if (req.session.auth!=1){
        req.session.auth=           1;
        req.session.lang=           lang.en;
        req.session.token= tb.sha1(Math.random());
    }
    res.render('main', { title: '', s: req.session });
};

As you may have seen, I have added this just before the send method

console.log("--- sending mail ---");

The console log

$ node server.js
Express server listening on port 8080 in development mode
--- sending mail ---
null
{ attachments: [],
alternative:
{ data: 'Confirm',
alternative: true,
charset: 'utf-8',
type: 'text/html',
inline: true },
header:
{ 'message-id': '1339178853241.0.3704@Markec-PC',
from: 'Radek Killa radek.killa@gmail.com',
to: 'marko.knezevic82@gmail.com',
subject: 'test confirmation 2' },
content: 'text/plain; charset=utf-8',
text: 'www.google.com Confirm' }
--- sending mail ---
null
{ attachments: [],
alternative:
{ data: 'Confirm',
alternative: true,
charset: 'utf-8',
type: 'text/html',
inline: true },
header:
{ 'message-id': '1339178973218.1.3704@Markec-PC',
from: 'Radek Killa radek.killa@gmail.com',
to: 'marko.knezevic82@gmail.com',
subject: 'test confirmation 2' },
content: 'text/plain; charset=utf-8',
text: 'www.google.com Confirm' }

Result is the same, 2 mails and 4 minutes to timeout. So, the script does run two times lol The question is, "why the hell?"

... figured it out, my email.js didn't actually send anything back to the browser, a very stupid mistake to make :D

The updated email.js

exports.index= function(req, res){
    if (!req.session.auth || req.body.token!=req.session.token)
        res.send('Sending failure');
    else {
var email= require("emailjs"),
server= email.server.connect({
    user:       "@gmail.com",
    password:   "",
    host:       "smtp.gmail.com",
    ssl:        true
});

console.log("--- sending mail ---");
server.send({
    text:       'www.google.com Confirm',
    from:       " <@gmail.com>",
    to:         "@gmail.com",
    subject:    "test confirmation",
    attachment: [
        {
            data:           '<a href="www.google.com">Confirm</a>',
            alternative:    true
        }
    ]
}, function(e, r){
    if (!e) res.send('Sending OK');
    console.log(e);
    console.log(r);
});

    }
};

Thanks for your time.

eleith
Owner
eleith commented June 08, 2012

have you ruled out the possibility that two requests from the page are being sent, thus calling the email send snippet twice?

also, it is best to end the request from the page with a res.send(200) either before the email is sent or afterwards if you don't want to send a 200 till the email has been sent.

the timeout you reported earlier may be an express timeout since you are not explicitly ending the request.

since you are actually receiving the emails, emailjs is not timing out.

in order to debug, i'ld put some console logs right before you require emailjs to see how many times that is being called, chances are you'll see it being called more than once!

good luck.

eleith eleith closed this June 08, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.