Adds support for localized push notification in push payload (#4129)

* Adds support for localized push data keys

- passign alert-[lang|locale] or title-[lang|locale] will inject the
  proper locale on the push body based on the installation

* Better handling of the default cases

* Updates changelog

* nits

* nits
This commit is contained in:
Florent Vilmart
2017-09-01 15:22:02 -04:00
committed by GitHub
parent 540daa4c4a
commit 6df944704c
6 changed files with 267 additions and 2 deletions

View File

@@ -65,6 +65,22 @@ export class PushWorker {
sendToAdapter(body: any, installations: any[], pushStatus: any, config: Config): Promise<*> {
pushStatus = pushStatusHandler(config, pushStatus.objectId);
// Check if we have locales in the push body
const locales = utils.getLocalesFromPush(body);
if (locales.length > 0) {
// Get all tranformed bodies for each locale
const bodiesPerLocales = utils.bodiesPerLocales(body, locales);
// Group installations on the specified locales (en, fr, default etc...)
const grouppedInstallations = utils.groupByLocaleIdentifier(installations, locales);
const promises = Object.keys(grouppedInstallations).map((locale) => {
const installations = grouppedInstallations[locale];
const body = bodiesPerLocales[locale];
return this.sendToAdapter(body, installations, pushStatus, config);
});
return Promise.all(promises);
}
if (!utils.isPushIncrementing(body)) {
return this.adapter.send(body, installations, pushStatus.objectId).then((results) => {
return pushStatus.trackSent(results);

View File

@@ -8,6 +8,81 @@ export function isPushIncrementing(body) {
body.data.badge.toLowerCase() == "increment"
}
const localizableKeys = ['alert', 'title'];
export function getLocalesFromPush(body) {
const data = body.data;
if (!data) {
return [];
}
return [...new Set(Object.keys(data).reduce((memo, key) => {
localizableKeys.forEach((localizableKey) => {
if (key.indexOf(`${localizableKey}-`) == 0) {
memo.push(key.slice(localizableKey.length + 1));
}
});
return memo;
}, []))];
}
export function transformPushBodyForLocale(body, locale) {
const data = body.data;
if (!data) {
return body;
}
body = deepcopy(body);
localizableKeys.forEach((key) => {
const localeValue = body.data[`${key}-${locale}`];
if (localeValue) {
body.data[key] = localeValue;
}
});
return stripLocalesFromBody(body);
}
export function stripLocalesFromBody(body) {
if (!body.data) { return body; }
Object.keys(body.data).forEach((key) => {
localizableKeys.forEach((localizableKey) => {
if (key.indexOf(`${localizableKey}-`) == 0) {
delete body.data[key];
}
});
});
return body;
}
export function bodiesPerLocales(body, locales = []) {
// Get all tranformed bodies for each locale
const result = locales.reduce((memo, locale) => {
memo[locale] = transformPushBodyForLocale(body, locale);
return memo;
}, {});
// Set the default locale, with the stripped body
result.default = stripLocalesFromBody(body);
return result;
}
export function groupByLocaleIdentifier(installations, locales = []) {
return installations.reduce((map, installation) => {
let added = false;
locales.forEach((locale) => {
if (added) {
return;
}
if (installation.localeIdentifier && installation.localeIdentifier.indexOf(locale) === 0) {
added = true;
map[locale] = map[locale] || [];
map[locale].push(installation);
}
});
if (!added) {
map.default.push(installation);
}
return map;
}, {default: []});
}
/**
* Check whether the deviceType parameter in qury condition is valid or not.
* @param {Object} where A query condition

View File

@@ -28,7 +28,7 @@ export class PushRouter extends PromiseRouter {
result: true
}
});
});
}).catch(req.config.loggerController.error);
return promise;
}