From 7105bc195f688949b6827cbbf906b386fdf736e8 Mon Sep 17 00:00:00 2001 From: Negue Date: Fri, 27 Mar 2015 18:35:32 +0100 Subject: [PATCH] add all Changes of #4565 --- common/script/index.coffee | 14 +++++ config.json.example | 7 +++ website/src/controllers/challenges.js | 5 +- website/src/controllers/groups.js | 9 ++++ website/src/controllers/members.js | 9 +++- website/src/controllers/payments/index.js | 19 +++++-- website/src/controllers/pushNotifications.js | 56 ++++++++++++++++++++ website/src/models/user.js | 7 ++- website/src/routes/apiv2.coffee | 10 ++++ 9 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 website/src/controllers/pushNotifications.js diff --git a/common/script/index.coffee b/common/script/index.coffee index 922c38aa65..5f8e0c23f7 100644 --- a/common/script/index.coffee +++ b/common/script/index.coffee @@ -645,6 +645,20 @@ api.wrap = (user, main=true) -> user.markModified? 'preferences.webhooks' cb? null, user.preferences.webhooks + # ------ + # Push Notifications + # ------ + addPushDevice: (req, cb) -> + user.pushDevices = [] unless user.pushDevices + pd = user.pushDevices + item = {regId:req.body.regId, type:req.body.type}; + i = _.findIndex pd, {regId: item.regId} + + pd.push(item) unless i != -1 + + user.markModified? 'pushDevices' + cb? null, user.pushDevices + # ------ # Inbox # ------ diff --git a/config.json.example b/config.json.example index 6933f92426..6b87388d90 100644 --- a/config.json.example +++ b/config.json.example @@ -51,5 +51,12 @@ "token": "token", "username": "username", "password": "password" + }, + "PUSH_CONFIGS": { + "GCM_SERVER_API_KEY": "", + "APN_PEM_FILES": { + "KEY": "key.pem", + "CERT": "cert.pem" + } } } diff --git a/website/src/controllers/challenges.js b/website/src/controllers/challenges.js index 5fabd0fb1c..c133c1e4ca 100644 --- a/website/src/controllers/challenges.js +++ b/website/src/controllers/challenges.js @@ -11,7 +11,7 @@ var logging = require('./../logging'); var csv = require('express-csv'); var utils = require('../utils'); var api = module.exports; - +var pushNotify = require('./pushNotifications'); /* ------------------------------------------------------------------------ @@ -341,6 +341,9 @@ api.selectWinner = function(req, res, next) { {name: 'CHALLENGE_NAME', content: chal.name} ]); } + + pushNotify.sendNotify(saved, shared.i18n.t('wonChallenge'), chal.name); + closeChal(cid, {broken: 'CHALLENGE_CLOSED', winner: saved.profile.name}, cb); } ], function(err){ diff --git a/website/src/controllers/groups.js b/website/src/controllers/groups.js index 4e2a93d79f..d00dc9578d 100644 --- a/website/src/controllers/groups.js +++ b/website/src/controllers/groups.js @@ -14,6 +14,7 @@ var Group = require('./../models/group').model; var Challenge = require('./../models/challenge').model; var isProd = nconf.get('NODE_ENV') === 'production'; var api = module.exports; +var pushNotify = require('./pushNotifications'); /* ------------------------------------------------------------------------ @@ -535,9 +536,13 @@ var inviteByUUIDs = function(uuids, group, req, res, next){ function sendInvite (){ if(group.type === 'guild'){ invite.invitations.guilds.push({id: group._id, name: group.name, inviter:res.locals.user._id}); + + pushNotify.sendNotify(invite, shared.i18n.t('invitedGuild'), group.name); }else{ //req.body.type in 'guild', 'party' invite.invitations.party = {id: group._id, name: group.name, inviter:res.locals.user._id}; + + pushNotify.sendNotify(invite, shared.i18n.t('invitedParty'), group.name); } group.invites.push(invite._id); @@ -860,6 +865,10 @@ api.questAccept = function(req, res, next) { group.quest.leader = user._id; } else { group.quest.members[m] = undefined; + + User.findById(m, function(err,groupMember){ + pushNotify.sendNotify(groupMember, "HabitRPG", "Invitation for the Quest "+quest.text()); + }); } }); diff --git a/website/src/controllers/members.js b/website/src/controllers/members.js index 9102df985a..cf0061fcc2 100644 --- a/website/src/controllers/members.js +++ b/website/src/controllers/members.js @@ -7,6 +7,7 @@ var _ = require('lodash'); var shared = require('../../../common'); var utils = require('../utils'); var nconf = require('nconf'); +var pushNotify = require('./pushNotifications'); var fetchMember = function(uuid, restrict){ return function(cb){ @@ -96,12 +97,18 @@ api.sendGift = function(req, res, next){ member.balance += amt; user.balance -= amt; api.sendMessage(user, member, req.body); + + var byUsername = utils.getUserInfo(user, ['name']).name; + if(member.preferences.emailNotifications.giftedGems !== false){ utils.txnEmail(member, 'gifted-gems', [ - {name: 'GIFTER', content: utils.getUserInfo(user, ['name']).name}, + {name: 'GIFTER', content: byUsername}, {name: 'X_GEMS_GIFTED', content: req.body.gems.amount} ]); } + + pushNotify.sendNotify(member, shared.i18n.t('giftedGems'), req.body.gems.amount + ' Gems - by '+byUsername); + return async.parallel([ function (cb2) { member.save(cb2) }, function (cb2) { user.save(cb2) } diff --git a/website/src/controllers/payments/index.js b/website/src/controllers/payments/index.js index 639fe18ebf..7b23500900 100644 --- a/website/src/controllers/payments/index.js +++ b/website/src/controllers/payments/index.js @@ -12,6 +12,7 @@ var async = require('async'); var iap = require('./iap'); var mongoose= require('mongoose'); var cc = require('coupon-code'); +var pushNotify = require('./../pushNotifications'); function revealMysteryItems(user) { _.each(shared.content.gear.flat, function(item) { @@ -75,12 +76,17 @@ exports.createSubscription = function(data, cb) { data.user.purchased.txnCount++; if (data.gift){ members.sendMessage(data.user, data.gift.member, data.gift); + + var byUserName = utils.getUserInfo(data.user, ['name']).name; + if(data.gift.member.preferences.emailNotifications.giftedSubscription !== false){ utils.txnEmail(data.gift.member, 'gifted-subscription', [ - {name: 'GIFTER', content: utils.getUserInfo(data.user, ['name']).name}, + {name: 'GIFTER', content: byUserName}, {name: 'X_MONTHS_SUBSCRIPTION', content: months} ]); - } + } + + pushNotify.sendNotify(data.gift.member, shared.i18n.t('gifted-subscription'), months + " months - by "+ byUserName); } async.parallel([ function(cb2){data.user.save(cb2)}, @@ -119,13 +125,18 @@ exports.buyGems = function(data, cb) { utils.ga.transaction(data.user._id, amt).item(amt, 1, data.paymentMethod.toLowerCase() + "-checkout", "Gems > " + data.paymentMethod).send(); } if (data.gift){ + var byUsername = utils.getUserInfo(data.user, ['name']).name; + var gemAmount = data.gift.gems.amount || 20; + members.sendMessage(data.user, data.gift.member, data.gift); if(data.gift.member.preferences.emailNotifications.giftedGems !== false){ utils.txnEmail(data.gift.member, 'gifted-gems', [ - {name: 'GIFTER', content: utils.getUserInfo(data.user, ['name']).name}, - {name: 'X_GEMS_GIFTED', content: data.gift.gems.amount || 20} + {name: 'GIFTER', content: byUsername}, + {name: 'X_GEMS_GIFTED', content: gemAmount} ]); } + + pushNotify.sendNotify(data.gift.member, shared.i18n.t('giftedGems'), gemAmount + ' Gems - by '+byUsername); } async.parallel([ function(cb2){data.user.save(cb2)}, diff --git a/website/src/controllers/pushNotifications.js b/website/src/controllers/pushNotifications.js new file mode 100644 index 0000000000..fc576beefc --- /dev/null +++ b/website/src/controllers/pushNotifications.js @@ -0,0 +1,56 @@ +var api = module.exports; +var _ = require('lodash'); +var nconf = require('nconf'); + +var pushNotify = require('push-notify'); + +var gcmApiKey = nconf.get("PUSH_CONFIGS:GCM_SERVER_API_KEY"); + +var gcm = gcmApiKey ? pushNotify.gcm({ + apiKey: gcmApiKey, + retries: 3 +}) : undefined; + +if(gcm){ + gcm.on('transmitted', function (result, message, registrationId) { + console.info("transmitted", result, message, registrationId); + }); + + gcm.on('transmissionError', function (error, message, registrationId) { + console.info("transmissionError", error, message, registrationId); + }); + gcm.on('updated', function (result, registrationId) { + console.info("updated", result, registrationId); + }); +} + +api.sendNotify = function(user, title, msg, timeToLive){ + timeToLive = timeToLive || 15; + + _.forEach(user.pushDevices, function(pushDevice){ + switch(pushDevice.type){ + case "android": + if(gcm){ + console.info("sending", title, msg); + console.info(pushDevice); + + + gcm.send({ + registrationId: pushDevice.regId, + //collapseKey: 'COLLAPSE_KEY', + delayWhileIdle: true, + timeToLive: timeToLive, + data: { + title: title, + message: msg + } + }); + } + + break; + + case "ios": + break; + } + }); +}; \ No newline at end of file diff --git a/website/src/models/user.js b/website/src/models/user.js index 08f286eb41..9d00ecee71 100644 --- a/website/src/models/user.js +++ b/website/src/models/user.js @@ -387,7 +387,12 @@ var UserSchema = new Schema({ todos: {type:[TaskSchemas.TodoSchema]}, rewards: {type:[TaskSchemas.RewardSchema]}, - extra: Schema.Types.Mixed + extra: Schema.Types.Mixed, + + pushDevices: {type: [{ + regId: {type: String}, + type: {type: String} + }],'default': []} }, { strict: true, diff --git a/website/src/routes/apiv2.coffee b/website/src/routes/apiv2.coffee index 479521d054..45729710c7 100644 --- a/website/src/routes/apiv2.coffee +++ b/website/src/routes/apiv2.coffee @@ -396,6 +396,16 @@ module.exports = (swagger, v2) -> ] action: user.deleteWebhook + # Push Notifications + "/user/pushDevice": + spec: + method: 'POST' + description: 'Add a new push devices registration ID' + parameters: [ + body '','New push registration { regId: "123123", type: "android"}','object' + ] + action: user.addPushDevice + # --------------------------------- # Groups # ---------------------------------