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
import { fetchJSON } from "https://esm.town/v/stevekrouse/fetchJSON?v=41";
export let redditMatches = async ({ username, filters, current_state, options }) => {
let matches = {};
let new_state = current_state ? current_state : {};
current_state = current_state || {};
for (const subreddit in filters) {
console.log(`processing subreddit ${subreddit}`);
let subreddit_filters = filters[subreddit];
let state = current_state[subreddit] ? current_state[subreddit] : {};
if (state.disabled) {
if (!options.force) {
console.log(`subreddit ${subreddit} is disabled by state, skipping`);
continue;
} else {
console.log(
`subreddit ${subreddit} is disabled by state, processing because options.force == true`
);
}
}
let last = state.last;
let params = last ? `?before=${last}` : "";
let subreddit_matches = [];
let data = await fetchJSON(
`https://www.reddit.com/r/${subreddit}/new/.json${params}`
);
console.log(`got https://www.reddit.com/r/${subreddit}/new/.json${params}`);
let new_posts = 0;
let count = data.data.dist;
let patterns = [];
if (!subreddit_filters) {
console.log(`missing patterns for subreddit ${subreddit}`);
continue;
}
for (const pattern_def of subreddit_filters) {
let pattern_str, mode;
if (typeof pattern_def === "string") {
pattern_str = pattern_def;
mode = "gi";
} else {
pattern_str = pattern_def.pattern;
if (pattern_def.strategy == "wordmatch") {
pattern_str = `\\b${pattern_str}\\b`;
}
mode = pattern_def.mode || "gi";
}
patterns.push(RegExp(pattern_str, mode));
}
while (count > 0) {
new_posts += count;
for (const post of data.data.children) {
let post_data = post.data;
let pattern_idx = 0;
for (const pattern of patterns) {
if (
post_data.title.match(pattern) ||
post_data.selftext.match(pattern)
) {
subreddit_matches.push({
url: post_data.url,
title: post_data.title,
pattern_idx: pattern_idx,
});
console.log(`found match ${post_data.url}`);
break;
}
pattern_idx += 0;
}
}
last = data.data.children[0].data.name;
data = await fetchJSON(
`https://www.reddit.com/r/${subreddit}/new/.json?before=${last}`
);
console.log(
`got https://www.reddit.com/r/${subreddit}/new/.json?before=${last}`
);
count = data.data.dist;
}
console.log(`processed ${new_posts} posts`);
state.last = last; // mutates argument, is that bad?
new_state[subreddit] = state;
if (subreddit_matches.length) {
matches[subreddit] = subreddit_matches;
}
}
let text = [];
let total_matches = 0;
let first = true;
for (let subreddit in matches) {
if (!first) {
text.push("\n\n");
}
text.push(`${subreddit}`);
text.push(`found ${matches[subreddit].length} matches`);
👆 This is a val. Vals are TypeScript snippets of code, written in the browser and run on our servers. Create scheduled functions, email yourself, and persist small pieces of data — all from the browser.