Commit 1942842e authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Implement sending e-mail updates to subscribers.

The e-mail sender we use is configurable in ./config.js.
parent 60b6225e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ app.get('/auth/:sdk/:version/comments', validator.hasStartKey, function(req, res

// Adds new comment
app.post('/auth/:sdk/:version/comments', validator.isLoggedIn, function(req, res) {
    new Request(req).addComment(req.body.target, req.body.comment, function(comment_id) {
    new Request(req).addComment(req.body.target, req.body.comment, req.body.url, function(comment_id) {
        res.json({ id: comment_id, success: true });
    });
});
+9 −0
Original line number Diff line number Diff line
@@ -19,6 +19,15 @@ module.exports = {
        database: ''
    },

    // Config for nodemailer
    email: {
        from: "Sencha Documentation <no-reply@sencha.com>",
        config: {
            host: 'localhost',
            port: 25
        }
    },

    // old MongoDB database
    mongoDb: 'mongodb://localhost:27017/comments'
};

comments/mailer.js

0 → 100644
+98 −0
Original line number Diff line number Diff line
var nodemailer = require("nodemailer");
var config = require("./config");

/**
 * Takes care of notifying subscribers about a new comment.
 *
 * @constructor
 *
 * @param {Object} cfg Config object:
 * @param {TableFactory} cfg.db Access to database tables.
 * @param {Object} cfg.comment The new comment that was posted.
 * @param {String} cfg.threadUrl The URL from where the comment came from.
 */
function Mailer(cfg) {
    this.db = cfg.db;
    this.comment = cfg.comment;
    this.threadUrl = cfg.threadUrl;
}

Mailer.prototype = {
    /**
     * Sends e-mail updates about the comment to all subscribers who
     * have subscribed to that thread.
     */
    sendEmailUpdates: function() {
        this.db.subscriptions().findUsersByTarget(this.comment.target_id, function(err, users) {
            // don't send e-mail to the user who posted the comment
            var otherUsers = users.filter(function(u){
                return u.id !== this.comment.user_id;
            }, this);

            if (otherUsers.length === 0) {
                return;
            }

            var emails = otherUsers.map(this.createMessage, this);

            this.batchSend(emails);
        }.bind(this));
    },

    createMessage: function(user) {
        var title = this.createTitle();

        return {
            from: config.email.from,
            to: user.email,
            subject: "Comment on '" + title + "'",
            text: [
                "A comment by " + user.username + " on '" + title + "' was posted on the Sencha Documentation:\n",
                this.comment.content + "\n",
                "--",
                "Original thread: " + this.threadUrl
            ].join("\n")
        };
    },

    createTitle: function() {
        if (this.comment.type === "class") {
            return this.comment.cls + " " + this.comment.member;
        }
        else {
            return this.comment.type + " " + this.comment.cls;
        }
    },

    batchSend: function(emails) {
        this.transport = nodemailer.createTransport("SMTP", config.email.config);

        this.send(emails, function() {
            this.transport.close();
        }.bind(this));
    },

    // Here the actual sending happens
    send: function(emails, callback) {
        var mail = emails.shift();

        if (!mail) {
            callback();
            return;
        }

        this.transport.sendMail(mail, function(err) {
            if (err) {
                console.log("Failed sending e-mail to " + mail.to);
                console.log(err);
            }
            else {
                console.log("Sent e-mail to " + mail.to);
            }

            this.send(emails, callback);
        }.bind(this));
    }
};

module.exports = Mailer;
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
        "connect-mysql-session": "~0.1",
        "marked": "~0.2",
        "sanitizer": "~0.0",
        "nodemailer": "~0.3",
        "mongoose": "~3.0"
    }
}
+15 −1
Original line number Diff line number Diff line
var TableFactory = require("./table_factory");
var ApiAdapter = require("./api_adapter");
var Mailer = require("./mailer");

/**
 * Handles JSON API request.
@@ -77,7 +78,7 @@ Request.prototype = {
        });
    },

    addComment: function(target, content, callback) {
    addComment: function(target, content, threadUrl, callback) {
        var comment = {
            user_id: this.getUserId(),
            target: ApiAdapter.targetFromJson(JSON.parse(target)),
@@ -93,6 +94,19 @@ Request.prototype = {
            else {
                callback(comment_id);
            }

            this.sendEmailUpdates(comment_id, threadUrl);
        }.bind(this));
    },

    sendEmailUpdates: function(comment_id, threadUrl) {
        this.db.comments().getById(comment_id, function(err, comment) {
            var mailer = new Mailer({
                db: this.db,
                comment: comment,
                threadUrl: threadUrl
            });
            mailer.sendEmailUpdates();
        }.bind(this));
    },