This repository has been archived by the owner on Nov 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
controller.js
87 lines (67 loc) · 3.29 KB
/
controller.js
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
"use strict";
const Promise = require("bluebird");
module.exports = function(dependencies) {
const Notification = dependencies.Notification;
const md5 = dependencies.md5
function Controller(props) {
this.apn = props.apn;
this.logger = props.logger;
this.redis = props.redis;
this.prefix = props.prefix;
}
Controller.prototype.register = function register(username, accountId, deviceToken, subtopic) {
const prefix = this.prefix;
this.logger.log("info", "Controller.register", { username });
this.redis.sadd(`${prefix}${username}:device`, `${deviceToken}:${accountId}`);
this.redis.del(`${prefix}${username}:${deviceToken}:${accountId}:subscriptions`);
}
Controller.prototype.notify = function notify(username, mailbox) {
const prefix = this.prefix;
const usernameKey = `${prefix}${username}`
const mailboxHash = md5(mailbox);
this.logger.log("info", "Controller.notify", { username, mailbox });
return this.redis.smembers(`${usernameKey}:device`)
.then( deviceAccounts => Promise.all(
deviceAccounts.map( deviceAccount => {
this.logger.log("debug", "Controller.notify.device", { username, device: deviceAccount });
return this.redis.sismember(`${usernameKey}:${deviceAccount}:subscriptions`, mailboxHash)
.then( shouldSend => {
this.logger.log("debug", "Controller.notify.shouldSend", { username, device: deviceAccount, shouldSend });
if (!shouldSend) {
return null;
}
const [device, accountId] = deviceAccount.split(":", 2);
const notification = new Notification({aps: {"account-id": accountId, m: [mailboxHash]}});
this.logger.log("info", "Controller.notify.send", { username, device, notification: notification.compile()});
return Promise.resolve(this.apn.send(notification, device))
.then( ( { failed } ) => failed)
.filter( ( result ) => {
if (result.response) {
let reason = result.response.reason;
if (reason == "Unregistered") {
this.logger.log("warn", "Controller.notify.send.unregistered", { username, device });
return true;
}
this.logger.log("warn", "Controller.notify.send.failure", { username, device, reason });
} else if (result.error) {
this.logger.log("error", "Controller.notify.send.error", {username, device, error: result.error });
}
return false
})
.each( failed => Promise.all([
this.redis.srem(`${usernameKey}:device`, `${failed.device}:${accountId}`),
this.redis.del(`${usernameKey}:${deviceAccount}:subscriptions`),
])
);
});
})
)
);
}
Controller.prototype.subscribe = function subscribe(username, accountId, device, mailbox) {
const prefix = this.prefix;
this.logger.log("info", "Controller.subscribe", { username, mailbox })
this.redis.sadd(`${prefix}${username}:${device}:${accountId}:subscriptions`, md5(mailbox));
}
return Controller;
};