forked from parse-community/parse-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPushWorker.js
More file actions
122 lines (111 loc) · 3.79 KB
/
PushWorker.js
File metadata and controls
122 lines (111 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// @flow
// @flow-disable-next
import deepcopy from 'deepcopy';
import AdaptableController from '../Controllers/AdaptableController';
import { master } from '../Auth';
import Config from '../Config';
import { PushAdapter } from '../Adapters/Push/PushAdapter';
import rest from '../rest';
import { pushStatusHandler } from '../StatusHandler';
import * as utils from './utils';
import { ParseMessageQueue } from '../ParseMessageQueue';
import { PushQueue } from './PushQueue';
import logger from '../logger';
function groupByBadge(installations) {
return installations.reduce((map, installation) => {
const badge = installation.badge + '';
map[badge] = map[badge] || [];
map[badge].push(installation);
return map;
}, {});
}
export class PushWorker {
subscriber: ?any;
adapter: any;
channel: string;
constructor(pushAdapter: PushAdapter, subscriberConfig: any = {}) {
AdaptableController.validateAdapter(pushAdapter, this, PushAdapter);
this.adapter = pushAdapter;
this.channel = subscriberConfig.channel || PushQueue.defaultPushChannel();
this.subscriber = ParseMessageQueue.createSubscriber(subscriberConfig);
if (this.subscriber) {
const subscriber = this.subscriber;
subscriber.subscribe(this.channel);
subscriber.on('message', (channel, messageStr) => {
const workItem = JSON.parse(messageStr);
this.run(workItem);
});
}
}
run({ body, query, pushStatus, applicationId, UTCOffset }: any): Promise<*> {
const config = Config.get(applicationId);
const auth = master(config);
const where = utils.applyDeviceTokenExists(query.where);
delete query.where;
pushStatus = pushStatusHandler(config, pushStatus.objectId);
return rest
.find(config, auth, '_Installation', where, query)
.then(({ results }) => {
if (results.length == 0) {
return;
}
return this.sendToAdapter(body, results, pushStatus, config, UTCOffset);
});
}
sendToAdapter(
body: any,
installations: any[],
pushStatus: any,
config: Config,
UTCOffset: ?any
): Promise<*> {
// 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,
UTCOffset
);
});
return Promise.all(promises);
}
if (!utils.isPushIncrementing(body)) {
logger.verbose(`Sending push to ${installations.length}`);
return this.adapter
.send(body, installations, pushStatus.objectId)
.then(results => {
return pushStatus.trackSent(results, UTCOffset).then(() => results);
});
}
// Collect the badges to reduce the # of calls
const badgeInstallationsMap = groupByBadge(installations);
// Map the on the badges count and return the send result
const promises = Object.keys(badgeInstallationsMap).map(badge => {
const payload = deepcopy(body);
payload.data.badge = parseInt(badge);
const installations = badgeInstallationsMap[badge];
return this.sendToAdapter(
payload,
installations,
pushStatus,
config,
UTCOffset
);
});
return Promise.all(promises);
}
}
export default PushWorker;