make it send emails
This commit is contained in:
parent
9cd41efb1d
commit
36d10a5010
4 changed files with 172 additions and 112 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
* a point to unsubscribe
|
||||
* stop the ui prompting if already subscribed
|
||||
* send actual emails with content
|
||||
* move settings to settings.json
|
||||
* Clean up all code
|
||||
|
||||
* Get the modified contents from the API HTML diff
|
||||
* Keep a record of when a user was last on a pad
|
||||
|
|
2
ep.json
2
ep.json
|
@ -4,7 +4,7 @@
|
|||
"name": "ep_email_notifications",
|
||||
"hooks": {
|
||||
"padUpdate": "ep_email_notifications/update",
|
||||
"handleMessage": "ep_email_notifications/update",
|
||||
"handleMessage": "ep_email_notifications/handleMessage",
|
||||
"eejsBlock_scripts": "ep_email_notifications/client",
|
||||
"eejsBlock_editbarMenuRight": "ep_email_notifications/client:eejsBlock_toolbarRight",
|
||||
"eejsBlock_embedPopup": "ep_email_notifications/client:eejsBlock_embedPopup"
|
||||
|
|
108
handleMessage.js
Normal file
108
handleMessage.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
var db = require('../../src/node/db/DB').db,
|
||||
API = require('../../src/node/db/API.js'),
|
||||
async = require('../../src/node_modules/async'),
|
||||
check = require('validator').check,
|
||||
settings = require('../../src/node/utils/Settings');
|
||||
|
||||
var pluginSettings = settings.ep_email_notifications;
|
||||
|
||||
// When a new message comes in from the client - FML this is ugly
|
||||
exports.handleMessage = function(hook_name, context, callback){
|
||||
if (context.message && context.message.data){
|
||||
if (context.message.data.type == 'USERINFO_UPDATE' ) { // if it's a request to update an authors email
|
||||
if (context.message.data.userInfo){
|
||||
if(context.message.data.userInfo.email){ // it contains email
|
||||
console.debug(context.message);
|
||||
|
||||
// does email Subscription already exist for this email address?
|
||||
db.get("emailSubscription:"+context.message.data.padId, function(err, userIds){
|
||||
|
||||
var alreadyExists = false;
|
||||
if(userIds){
|
||||
async.forEach(Object.keys(userIds), function(user, cb){
|
||||
console.debug("UserIds subscribed by email to this pad:", userIds);
|
||||
if(user == context.message.data.userInfo.email){ // If we already have this email registered for this pad
|
||||
|
||||
// This user ID is already assigned to this padId so don't do anything except tell the user they are already subscribed somehow..
|
||||
alreadyExists = true;
|
||||
console.debug("email ", user, "already subscribed to ", context.message.data.padId, " so sending message to client");
|
||||
|
||||
context.client.json.send({ type: "COLLABROOM",
|
||||
data:{
|
||||
type: "emailSubscriptionSuccess",
|
||||
payload: false
|
||||
}
|
||||
});
|
||||
}
|
||||
cb();
|
||||
},
|
||||
|
||||
function(err){
|
||||
// There should be something in here!
|
||||
}); // end async for each
|
||||
}
|
||||
var validatesAsEmail = check(context.message.data.userInfo.email).isEmail();
|
||||
if(!validatesAsEmail){ // send validation failed if it's malformed.. y'know in general fuck em!
|
||||
console.warn("Dropped email subscription due to malformed email address");
|
||||
context.client.json.send({ type: "COLLABROOM",
|
||||
data:{
|
||||
type: "emailSubscriptionSuccess",
|
||||
payload: false
|
||||
}
|
||||
});
|
||||
}
|
||||
if(alreadyExists == false && validatesAsEmail){
|
||||
console.debug ("Wrote to the database and sent client a positive response ",context.message.data.userInfo.email);
|
||||
|
||||
exports.setAuthorEmail(
|
||||
context.message.data.userInfo.userId,
|
||||
context.message.data.userInfo.email, callback
|
||||
);
|
||||
|
||||
exports.setAuthorEmailRegistered(
|
||||
context.message.data.userInfo.email,
|
||||
context.message.data.userInfo.userId,
|
||||
context.message.data.padId
|
||||
);
|
||||
|
||||
context.client.json.send({ type: "COLLABROOM",
|
||||
data:{
|
||||
type: "emailSubscriptionSuccess",
|
||||
payload: true
|
||||
}
|
||||
});
|
||||
}
|
||||
}); // close db get
|
||||
|
||||
callback(null); // don't run onto passing colorId or anything else to the message handler
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
// Updates the database with the email record
|
||||
exports.setAuthorEmail = function (author, email, callback){
|
||||
db.setSub("globalAuthor:" + author, ["email"], email, callback);
|
||||
}
|
||||
|
||||
// Write email and padId to the database
|
||||
exports.setAuthorEmailRegistered = function(email, authorId, padId){
|
||||
var timestamp = new Date().getTime();
|
||||
var registered = {
|
||||
authorId: authorId,
|
||||
timestamp: timestamp
|
||||
};
|
||||
console.debug("registered", registered, " to ", padId);
|
||||
|
||||
// Here we have to basically hack a new value into the database, this isn't clean or polite.
|
||||
db.get("emailSubscription:" + padId, function(err, value){ // get the current value
|
||||
if(!value){value = {};} // if an emailSubscription doesnt exist yet for this padId don't panic
|
||||
value[email] = registered; // add the registered values to the object
|
||||
db.set("emailSubscription:" + padId, value); // stick it in the database
|
||||
});
|
||||
|
||||
}
|
||||
|
169
update.js
169
update.js
|
@ -1,98 +1,25 @@
|
|||
// We check pads periodically for activity and notify owners when someone begins editing and when someone finishes.
|
||||
|
||||
var db = require('../../src/node/db/DB').db,
|
||||
API = require('../../src/node/db/API.js'),
|
||||
async = require('../../src/node_modules/async'),
|
||||
check = require('validator').check,
|
||||
email = require('emailjs'),
|
||||
settings = require('../../src/node/utils/Settings');
|
||||
|
||||
var pluginSettings = settings.ep_email_notifications;
|
||||
var checkInterval = 60000; // Move me to the settings file
|
||||
var staleTime = 3600000; // Move me to settings
|
||||
var checkInterval = 3000; // How frequently to check for pad updates -- Move me to the settings file
|
||||
var staleTime = 3000; // How stale does a pad need to be before notifying subscribers? Move me to settings
|
||||
var timers = {};
|
||||
var fromName = "John McLear";
|
||||
var fromEmail = "john@mclear.co.uk";
|
||||
var urlToPads = "http://beta.etherpad.org/p/";
|
||||
|
||||
// When a new message comes in from the client
|
||||
exports.handleMessage = function(hook_name, context, callback){
|
||||
if (context.message && context.message.data){
|
||||
if (context.message.data.type == 'USERINFO_UPDATE' ) { // if it's a request to update an authors email
|
||||
if (context.message.data.userInfo){
|
||||
if(context.message.data.userInfo.email){ // it contains email
|
||||
console.debug(context.message);
|
||||
|
||||
// does email Subscription already exist for this email address?
|
||||
db.get("emailSubscription:"+context.message.data.padId, function(err, userIds){
|
||||
|
||||
var alreadyExists = false;
|
||||
if(userIds){
|
||||
async.forEach(Object.keys(userIds), function(user, cb){
|
||||
console.debug("UserIds subscribed by email to this pad:", userIds);
|
||||
if(user == context.message.data.userInfo.email){ // If we already have this email registered for this pad
|
||||
|
||||
// This user ID is already assigned to this padId so don't do anything except tell the user they are already subscribed somehow..
|
||||
alreadyExists = true;
|
||||
console.debug("email ", user, "already subscribed to ", context.message.data.padId, " so sending message to client");
|
||||
|
||||
context.client.json.send({ type: "COLLABROOM",
|
||||
data:{
|
||||
type: "emailSubscriptionSuccess",
|
||||
payload: false
|
||||
}
|
||||
});
|
||||
}
|
||||
cb();
|
||||
},
|
||||
|
||||
function(err){
|
||||
// There should be something in here!
|
||||
}); // end async for each
|
||||
}
|
||||
|
||||
var validatesAsEmail = check(context.message.data.userInfo.email).isEmail();
|
||||
if(!validatesAsEmail){ // send validation failed if it's malformed.. y'know in general fuck em!
|
||||
console.warn("Dropped email subscription due to malformed email address");
|
||||
context.client.json.send({ type: "COLLABROOM",
|
||||
data:{
|
||||
type: "emailSubscriptionSuccess",
|
||||
payload: false
|
||||
}
|
||||
});
|
||||
}
|
||||
if(alreadyExists == false && validatesAsEmail){
|
||||
console.warn ("Wrote to the database and sent client a positive response ",context.message.data.userInfo.email);
|
||||
|
||||
exports.setAuthorEmail(
|
||||
context.message.data.userInfo.userId,
|
||||
context.message.data.userInfo.email, callback
|
||||
);
|
||||
|
||||
exports.setAuthorEmailRegistered(
|
||||
context.message.data.userInfo.email,
|
||||
context.message.data.userInfo.userId,
|
||||
context.message.data.padId
|
||||
);
|
||||
|
||||
context.client.json.send({ type: "COLLABROOM",
|
||||
data:{
|
||||
type: "emailSubscriptionSuccess",
|
||||
payload: true
|
||||
}
|
||||
});
|
||||
}
|
||||
}); // close db get
|
||||
|
||||
callback(null); // don't run onto passing colorId or anything else to the message handler
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
exports.doesPadIdEmailAssociationAlreadyExist = function (padId, email){
|
||||
var found = false;
|
||||
db.get("emailSubscription:"+padId, function(err, value){
|
||||
return value;
|
||||
});
|
||||
}
|
||||
var server = email.server.connect({
|
||||
user: "username",
|
||||
password:"password",
|
||||
host: "smtp.gmail.com",
|
||||
});
|
||||
|
||||
exports.padUpdate = function (hook_name, _pad) {
|
||||
|
||||
|
@ -102,6 +29,8 @@ exports.padUpdate = function (hook_name, _pad) {
|
|||
|
||||
// does an interval not exist for this pad?
|
||||
if(!timers[padId]){
|
||||
console.warn("Someone started editing "+padId);
|
||||
exports.notifyBegin(padId);
|
||||
console.debug("Created an interval time check for "+padId);
|
||||
// if not then create one and write it to the timers object
|
||||
timers[padId] = exports.createInterval(padId, checkInterval);
|
||||
|
@ -111,6 +40,49 @@ exports.padUpdate = function (hook_name, _pad) {
|
|||
|
||||
};
|
||||
|
||||
exports.notifyBegin = function(padId){
|
||||
db.get("emailSubscription:" + padId, function(err, recipients){ // get everyone we need to email
|
||||
async.forEach(Object.keys(recipients), function(recipient, cb){
|
||||
console.debug("Emailing "+recipient +" about a new begin update");
|
||||
|
||||
server.send({
|
||||
text: "Your pad at "+urlToPads+"/p/"+padId +" is being edited, we're just emailing you let you know :)",
|
||||
from: fromName+ "<"+fromEmail+">",
|
||||
to: recipient,
|
||||
subject: "Someone begin editing "+padId
|
||||
}, function(err, message) { console.log(err || message); });
|
||||
|
||||
cb(); // finish each user
|
||||
},
|
||||
function(err){
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
exports.notifyEnd = function(padId){
|
||||
// get the modified contents...
|
||||
|
||||
|
||||
db.get("emailSubscription:" + padId, function(err, recipients){ // get everyone we need to email
|
||||
async.forEach(Object.keys(recipients), function(recipient, cb){
|
||||
console.debug("Emailing "+recipient +" about a new begin update");
|
||||
|
||||
server.send({
|
||||
text: "Your pad at "+urlToPads+"/p/"+padId +" has finished being edited, we're just emailing you let you know :) The changes look like this:" + changesToPad,
|
||||
from: fromName+ "<"+fromEmail+">",
|
||||
to: recipient,
|
||||
subject: "Someone begin editing "+padId
|
||||
}, function(err, message) { console.log(err || message); });
|
||||
|
||||
cb(); // finish each user
|
||||
},
|
||||
function(err){
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
exports.sendUpdates = function(padId){
|
||||
|
||||
// check to see if we can delete this interval
|
||||
|
@ -119,13 +91,14 @@ exports.sendUpdates = function(padId){
|
|||
// we delete an interval if a pad hasn't been edited in X seconds.
|
||||
var currTS = new Date().getTime();
|
||||
if(currTS - message.lastEdited > staleTime){
|
||||
exports.notifyEnd(padId);
|
||||
console.warn("Interval went stale so deleting it from object and timer");
|
||||
var interval = timers[padId];
|
||||
clearInterval(timers[padId]); // remove the interval timer
|
||||
delete timers[padId]; // remove the entry from the padId
|
||||
|
||||
}else{
|
||||
console.debug("email timeotu not stale so not deleting");
|
||||
console.debug("email timeout not stale so not deleting");
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -186,25 +159,3 @@ exports.createInterval = function(padId){
|
|||
});
|
||||
}
|
||||
|
||||
// Updates the database with the email record
|
||||
exports.setAuthorEmail = function (author, email, callback){
|
||||
db.setSub("globalAuthor:" + author, ["email"], email, callback);
|
||||
}
|
||||
|
||||
// Write email and padId to the database
|
||||
exports.setAuthorEmailRegistered = function(email, authorId, padId){
|
||||
var timestamp = new Date().getTime();
|
||||
var registered = {
|
||||
authorId: authorId,
|
||||
timestamp: timestamp
|
||||
};
|
||||
console.debug("registered", registered, " to ", padId);
|
||||
|
||||
// Here we have to basically hack a new value into the database, this isn't clean or polite.
|
||||
db.get("emailSubscription:" + padId, function(err, value){ // get the current value
|
||||
if(!value){value = {};} // if an emailSubscription doesnt exist yet for this padId don't panic
|
||||
value[email] = registered; // add the registered values to the object
|
||||
db.set("emailSubscription:" + padId, value); // stick it in the database
|
||||
});
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue