Push notifications (#7682)

* Fix Social Push notifications

* Fix code formatting issues

* Fix commented issues

* Fix Syntax errors

* update push notify dependency

* specify push-notify version

* change how apn key is loaded

* feat(push-notifications): improve logging

* feat(push-notifications): disable v2 push notifications

* test(push-notifications): add unit tests and improve integration ones

* fix(push-notifications): throw when required params are missing

* fix(tests): correct descriptions and remove wrong comment

* fix(push-notifications): trim APN key

* fix(apn): log feedback only if it has data

* fix(apn): load cert and key differently

* fix(tests): correctly load apn during tests

* download creds from S3 and create AWS lib

* convert s3 buffer to a string

* fix(apn): remove console.log and do not use cert twice

* invert key and cert, disable failing test

* invert key and cert
This commit is contained in:
Matteo Pagliazzi
2016-06-23 00:19:37 +02:00
committed by GitHub
parent 09c7c45cd5
commit 08d7727881
26 changed files with 626 additions and 293 deletions

View File

@@ -20,7 +20,6 @@ import { removeFromArray } from '../../libs/api-v3/collectionManipulators';
import * as firebase from '../../libs/api-v3/firebase';
import { sendTxn as sendTxnEmail } from '../../libs/api-v3/email';
import { encrypt } from '../../libs/api-v3/encryption';
import common from '../../../../common';
import sendPushNotification from '../../libs/api-v3/pushNotifications';
let api = {};
@@ -537,11 +536,18 @@ async function _inviteByUUID (uuid, group, inviter, req, res) {
sendTxnEmail(userToInvite, `invited-${groupTemplate}`, emailVars);
}
sendPushNotification(
userToInvite,
common.i18n.t(group.type === 'guild' ? 'invitedGuild' : 'invitedParty'),
group.name
);
if (userToInvite.preferences.pushNotifications[`invited${groupLabel}`] !== false) {
let identifier = group.type === 'guild' ? 'invitedGuild' : 'invitedParty';
sendPushNotification(
userToInvite,
{
title: group.name,
message: res.t(identifier),
identifier,
payload: {groupID: group._id},
}
);
}
let userInvited = await userToInvite.save();
if (group.type === 'guild') {

View File

@@ -302,6 +302,18 @@ api.sendPrivateMessage = {
{name: 'PMS_INBOX_URL', content: '/#/options/groups/inbox'},
]);
}
if (receiver.preferences.pushNotifications.newPM !== false) {
sendPushNotification(
receiver,
{
title: res.t('newPM'),
message: res.t('newPMInfo', {name: getUserInfo(sender, ['name']).name, message}),
identifier: 'newPM',
category: 'newPM',
payload: {replyTo: sender._id},
}
);
}
res.respond(200, {});
},
@@ -372,8 +384,15 @@ api.transferGems = {
{name: 'X_GEMS_GIFTED', content: gemAmount},
]);
}
sendPushNotification(sender, res.t('giftedGems'), res.t('giftedGemsInfo', { amount: gemAmount, name: byUsername }));
if (receiver.preferences.pushNotifications.giftedGems !== false) {
sendPushNotification(receiver,
{
title: res.t('giftedGems'),
message: res.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}),
identifier: 'giftedGems',
payload: {replyTo: sender._id},
});
}
res.respond(200, {});
},

View File

@@ -0,0 +1,95 @@
import { authWithHeaders } from '../../middlewares/api-v3/auth';
import {
NotAuthorized,
NotFound,
} from '../../libs/api-v3/errors';
let api = {};
/**
* @apiIgnore
* @api {post} /api/v3/user/push-devices Add a push device to a user
* @apiVersion 3.0.0
* @apiName UserAddPushDevice
* @apiGroup User
*
* @apiParam {string} regId The id of the push device
* @apiParam {string} type The type of push device
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
*/
api.addPushDevice = {
method: 'POST',
url: '/user/push-devices',
middlewares: [authWithHeaders()],
async handler (req, res) {
let user = res.locals.user;
req.checkBody('regId', res.t('regIdRequired')).notEmpty();
req.checkBody('type', res.t('typeRequired')).notEmpty().isIn(['ios', 'android']);
let validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
let pushDevices = user.pushDevices;
let item = {
regId: req.body.regId,
type: req.body.type,
};
if (pushDevices.find(device => device.regId === item.regId)) {
throw new NotAuthorized(res.t('pushDeviceAlreadyAdded'));
}
pushDevices.push(item);
await user.save();
res.respond(200, user.pushDevices, res.t('pushDeviceAdded'));
},
};
/**
* @apiIgnore
* @api {delete} /api/v3/user/push-devices remove a push device from a user
* @apiVersion 3.0.0
* @apiName UserRemovePushDevice
* @apiGroup User
*
* @apiParam {string} regId The id of the push device
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
*/
api.removePushDevice = {
method: 'DELETE',
url: '/user/push-devices/:regId',
middlewares: [authWithHeaders()],
async handler (req, res) {
let user = res.locals.user;
req.checkParams('regId', res.t('regIdRequired')).notEmpty();
let validationErrors = req.validationErrors();
if (validationErrors) throw validationErrors;
let regId = req.params.regId;
let pushDevices = user.pushDevices;
let indexOfPushDevice = pushDevices.findIndex((element) => {
return element.regId === regId;
});
if (indexOfPushDevice === -1) {
throw new NotFound(res.t('pushDeviceNotFound'));
}
pushDevices.splice(indexOfPushDevice, 1);
await user.save();
res.respond(200, user.pushDevices, res.t('pushDeviceRemoved'));
},
};
module.exports = api;

View File

@@ -106,11 +106,18 @@ api.inviteToQuest = {
let inviterVars = getUserInfo(user, ['name', 'email']);
let membersToEmail = members.filter(member => {
// send push notifications while filtering members before sending emails
sendPushNotification(
member,
common.i18n.t('questInvitationTitle'),
common.i18n.t('questInvitationInfo', { quest: quest.text() })
);
if (member.preferences.pushNotifications.invitedQuest !== false) {
sendPushNotification(
member,
{
title: res.t('questInvitationTitle'),
message: res.t('questInvitationInfo', {quest: quest.text(req.language)}),
identifier: 'questInvitation',
category: 'questInvitation',
}
);
}
return member.preferences.emailNotifications.invitedQuest !== false;
});

View File

@@ -1266,32 +1266,6 @@ api.userReroll = {
},
};
/**
* @api {post} /api/v3/user/addPushDevice Add a push device to a user
* @apiVersion 3.0.0
* @apiName UserAddPushDevice
* @apiGroup User
*
* @apiParam {string} regId The id of the push device
* @apiParam {string} uuid The type of push device
*
* @apiSuccess {Object} data List of push devices
* @apiSuccess {string} message Success message
*/
api.userAddPushDevice = {
method: 'POST',
middlewares: [authWithHeaders()],
url: '/user/addPushDevice',
async handler (req, res) {
let user = res.locals.user;
let addPushDeviceRes = common.ops.addPushDevice(user, req);
await user.save();
res.respond(200, ...addPushDeviceRes);
},
};
/**
* @api {post} /api/v3/user/reset Reset user
* @apiVersion 3.0.0