This repository has been archived by the owner on Sep 20, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 195
/
Copy pathbrowserPush.js
85 lines (79 loc) · 2.53 KB
/
browserPush.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
const Sequelize = require('sequelize')
const PushSubscription = require('./models').PushSubscription
const { getNotificationMessage } = require('./notification')
const webpush = require('web-push')
const logger = require('./logger')
//
// Browser push subscripttions
//
async function browserPush(
eventName,
party,
buyerAddress,
sellerAddress,
offer
) {
if (!eventName) throw new Error('eventName not defined')
if (!party) throw new Error('party not defined')
if (!buyerAddress) throw new Error('buyerAddress not defined')
if (!sellerAddress) throw new Error('sellerAddress not defined')
if (!offer) throw new Error('offer not defined')
// Query the DB to get subscriptions from the seller and/or buyer.
// Note the filter ensures we do not send notification to the party
// who initiated the action:
// - seller initiated action -> only buyer gets notified.
// - buyer initiated action -> only seller gets notified.
// - 3rd party initiated action -> both buyer and seller get notified.
const subs = await PushSubscription.findAll({
where: {
account: {
[Sequelize.Op.in]: [buyerAddress, sellerAddress].filter(
a => a && a !== party
)
}
}
})
// Filter out redundant endpoints before iterating.
await subs
.filter((s, i, self) => {
return self.map(ms => ms.endpoint).indexOf(s.endpoint) === i
})
.forEach(async s => {
try {
const recipient = s.account
const recipientRole = recipient === sellerAddress ? 'seller' : 'buyer'
const message = getNotificationMessage(
eventName,
party,
recipient,
recipientRole
)
if (!message) {
return
}
// Send the push notification.
// TODO: Add safeguard against sending duplicate messages since the
// event-listener only provides at-least-once guarantees and may
// call this webhook more than once for the same event.
const pushSubscription = {
endpoint: s.endpoint,
keys: s.keys
}
const pushPayload = JSON.stringify({
title: message.title,
body: message.body,
account: recipient,
offerId: offer.id
})
await webpush.sendNotification(pushSubscription, pushPayload)
} catch (e) {
// Subscription is no longer valid - delete it in the DB.
if (e.statusCode === 410) {
s.destroy()
} else {
logger.error(e)
}
}
})
}
module.exports = { browserPush }