forked from PTFS-Europe/ems-email
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnotify_updates.js
123 lines (105 loc) · 4.59 KB
/
notify_updates.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
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
const db = require('../ems-db');
const { sendEmail } = require('./lib');
const pageSize = 100;
const result = {};
const doPage = async (offset = 0) => {
console.log(`Retrieving queries ${offset} - ${offset + pageSize}`);
// We pass a role_code of 'STAFF' to ensure we get all queries staff
// can access, i.e. all queries
const queriesResult = await db.resolvers.queries.allQueries({
query: { limit: pageSize, offset},
user: { role_code: 'STAFF'}
});
console.log(`Received ${queriesResult.rowCount} queries`);
if (queriesResult.rowCount === 0) {
return;
}
// Get all queries
const queries = queriesResult.rows;
// We need the IDs of all queries we received
const query_ids = queries.map((query) => query.id);
// Now get the participants of all retrieved queries
const participants = await db.resolvers.queries.participants(query_ids);
// Get all query user relationships
const queryUser = await db.resolvers.queryuser.allUserQueries();
// Iterate each query (we use 'for' so we iterate in sequence)
for (const query of queries) {
const messages = await db.resolvers.messages.allMessages(
{ query: { query_id: query.id } }
);
// The participants of this query
const allUsers = participants.rows
.filter((participant) => participant.query_id === query.id)
.map((final) => final.creator_id);
// Iterate each user
allUsers.forEach((userId) => {
// Get the most_recent_seen & most_recent_digest for this
// user/query combination
const currentState = queryUser.rows.find(
(qU) => qU.query_id === query.id && qU.user_id === userId
);
if (!currentState) return;
const highMark = currentState.most_recent_seen > currentState.most_recent_digest ?
currentState.most_recent_seen : currentState.most_recent_digest;
// Get the messages that occurred after this point that were not sent by
// this user (we shouldn't get any that were sent by this user because their
// highMark would be higher, but just to be sure)
// We sort them by ID so we can establish the new high mark
const newMessages = messages.rows.filter(
(message) => message.id > highMark && message.creator_id !== userId
).sort((a, b) => a.id - b.id);
if (newMessages.length > 0) {
const maxId = newMessages[newMessages.length - 1].id;
const newResult = {
id: query.id,
title: query.title,
messageCount: newMessages.length,
highMark: maxId,
userId
};
if (result[userId]) {
result[userId] = [...result[userId], newResult];
} else {
result[userId] = [newResult];
}
}
});
};
await doPage(offset + pageSize + 1);
};
const prepareSendEmails = async () => {
// Iterate each user (we use 'for' so we iterate in sequence, this
// is not strictly necessary, but will make for easier to read logs)
for (const id of Object.keys(result)) {
const user = await db.resolvers.users.getUser({ params: { id } });
console.log(`Retrieved user with ID ${user.rows[0].id}`);
const encryptedEmail = user.rows[0].email;
if (!encryptedEmail || encryptedEmail.length === 0) {
console.log('-- User does not have an email address');
continue;
}
const queries = result[id].map((query) =>
({
url: `${process.env.BASE_URL}/query/${query.id}`,
query
})
);
const email = await db.resolvers.users.getUserEmail(encryptedEmail);
console.log('Sending email');
await sendEmail({to: email, name: user.rows[0].name, queries, type: 'updated-query'});
}
};
const init = async (offset) => {
console.log(`Starting updated query email job at ${new Date().toISOString()}`);
// Compile users to be notified
await doPage(offset);
console.log(`Completed compiling ${Object.keys(result).length} users to be notified`);
if (Object.keys(result).length === 0) {
console.log('Nothing to do');
console.log(`Ended updated query email job at ${new Date().toISOString()}`);
return;
}
await prepareSendEmails();
console.log(`Ended email job at ${new Date().toISOString()}`);
};
module.exports = { init };