This repository has been archived by the owner on Jul 9, 2021. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
push.ts
87 lines (77 loc) · 2.24 KB
/
push.ts
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
import { NowRequest, NowResponse } from '@now/node';
import Expo, { ExpoPushMessage } from 'expo-server-sdk';
import { PushTicket } from '../src/models';
import {
assertWhitelistedIP,
constructExpoMessage,
ExpoPushSuccessTicket,
findUsersForNotifications,
isExpoPushMessage,
sendBatchToExpo,
universalFetch
} from '../src/push';
import { connectToDatabase, logger, sentrySetup } from '../src/util';
sentrySetup();
/**
* Send push notifications to all relevant users.
*/
export default async function(
req: NowRequest,
res: NowResponse
): Promise<void> {
try {
if (!assertWhitelistedIP(req, res)) {
return;
}
await connectToDatabase(process.env.MONGODB_ATLAS_URI);
// Fetch all users to whom we should show a notification
const users = (
await Promise.all(
(['daily', 'weekly', 'monthly'] as const).map(findUsersForNotifications)
)
).flat();
// Craft a push notification message for each user
const messages = await Promise.all(
users.map(async user => {
if (!user.notifications) {
throw new Error(
`User ${user.id} cannot not have notifications, as per our db query. qed.`
);
}
// FIXME add retries + timeout
const { value } = await universalFetch(user.notifications.universalId);
return {
userId: user._id,
message: constructExpoMessage(user, value)
};
})
);
// Find the messages that are valid
const validMessages = messages.filter(({ message }) =>
isExpoPushMessage(message)
);
// Send the valid messages, we get the tickets
const tickets = await sendBatchToExpo(
new Expo(),
validMessages.map(({ message }) => message as ExpoPushMessage)
);
await PushTicket.insertMany(
tickets.map((ticket, index) => ({
...ticket,
receiptId: (ticket as ExpoPushSuccessTicket).id,
userId: validMessages[index].userId
}))
);
res.send({
status: 'ok',
details: `Successfully sent ${validMessages.length}/${messages.length} push notifications`
});
} catch (error) {
logger.error(error);
res.status(500);
res.send({
status: 'error',
details: error.message
});
}
}