-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathcron.ts
107 lines (99 loc) · 3.51 KB
/
cron.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { getLatestPost, getPost } from "./hn";
import {
getLastCheckedId,
setLastCheckedId,
checkIfPostWasChecked,
getTeamsAndKeywords,
} from "./upstash";
import { equalsIgnoreOrder, postScanner } from "./helpers";
import { sendSlackMessage } from "./slack";
export async function cron() {
// last checked post id from redis, latest post id from hacker news
const [lastCheckedId, latestPostId] = await Promise.all([
getLastCheckedId(),
getLatestPost(),
]);
if (latestPostId === lastCheckedId) {
// if latest post id is the same as last checked id, do nothing
return { results: "No new posts" };
}
const teamsAndKeywords = await getTeamsAndKeywords(); // get all team keys from redis
const scanner = postScanner(teamsAndKeywords); // create a post scanner that contains all teams and their keywords in a constructed regex
let results: {
[postId: string]: string[]; // for each post, store the teams that it was sent to
} = {};
let errors: any[] = [];
for (let i = lastCheckedId + 1; i <= latestPostId; i++) {
if (await checkIfPostWasChecked(i)) continue; // avoid double checking posts
const post = await getPost(i); // get post from hacker news
if (!post) {
console.log(`Hacker News post not found. Post number: ${i}`); // by the off chance that the post fails to fetch/doesn't exist, log it
continue;
}
if (post.deleted) {
continue; // if post is deleted, skip it
}
console.log("checking for keywords in post", i);
const interestedTeams = Array.from(scanner(post)); // get teams that are interested in this post
if (interestedTeams.length > 0) {
results[i] = interestedTeams; // add post id and interested teams to results
await Promise.all(
interestedTeams.map(async (teamId) => {
console.log("sending post to team", teamId);
try {
await sendSlackMessage(i, teamId); // send post to team
} catch (e) {
console.log(
`Error sending post ${i} to team ${teamId}. Cause of error: ${e}`
);
errors.push({
error: e,
postId: i,
teamId: teamId,
}); // if there's an error, add it to errors
}
})
);
}
}
await setLastCheckedId(latestPostId); // set last checked post id in redis
return {
summary: `Processed post ${lastCheckedId} to post ${latestPostId} (${
latestPostId - lastCheckedId
} posts)`,
results,
errors,
};
}
export async function testCron(
postsToTest: number[],
fakeTeamsAndKeywords: { [teamId: string]: string[] },
fakeInterestedTeams: { [postId: number]: string[] }
) {
const scanner = postScanner(fakeTeamsAndKeywords);
let results: { [postId: number]: string } = {};
for (const id of postsToTest) {
console.log(`checking for post ${id}`);
const post = await getPost(id); // get post from hacker news
if (!post) {
results[id] = `Hacker News post not found.`;
continue;
}
if (post.deleted) {
continue; // if post is deleted, skip it
}
const interestedTeams = Array.from(scanner(post)); // get teams that are interested in this post
if (!equalsIgnoreOrder(fakeInterestedTeams[id], interestedTeams)) {
results[
id
] = `Interested teams don't match. Expected: ${fakeInterestedTeams[id]}, Actual: ${interestedTeams}`;
}
}
return {
message:
Object.keys(results).length > 0
? "Some tests failing"
: "All tests passed",
results,
};
}