1 | |
2 |
|
3 | import { |
4 | getState, |
5 | setState, |
6 | } from "windmill-client@1"; |
7 |
|
8 | |
9 | * @returns A list of posts that mentioned given phrases in ascending order |
10 | * of date of publication. |
11 | * |
12 | * @param mentions Case **insensitive** phrases that should be searched for. |
13 | */ |
14 | export async function main( |
15 | subreddit: string, |
16 | mentions: string[], |
17 | max_number_of_posts: number = 100, |
18 | ) { |
19 | mentions = mentions?.map((m) => m.trim().toLowerCase())?.filter(Boolean); |
20 | if (!mentions?.length) { |
21 | throw Error("\nAt least one mentioned phrase is needed to search for."); |
22 | } |
23 |
|
24 | const url = new URL(`https://www.reddit.com/r/${subreddit}/new.json`); |
25 | if (max_number_of_posts < 1) { |
26 | max_number_of_posts = 1; |
27 | } |
28 | const limit = max_number_of_posts < 100 ? max_number_of_posts : 100; |
29 | const processedPosts: Post[] = []; |
30 | let runLoop = true; |
31 |
|
32 | do { |
33 | const lastPostId = await getState(); |
34 | url.searchParams.append("limit", limit.toString()); |
35 | lastPostId && url.searchParams.append("before", lastPostId); |
36 | const result = await fetch(url); |
37 | if (!result.ok) { |
38 | throw Error("\n" + (await result.text())); |
39 | } |
40 | const data = (await result.json()).data; |
41 | const posts: Post[] = data.children.map( |
42 | ({ data: { name, title, selftext, url } }: { data: Post }) => { |
43 | return { name, title, selftext, url }; |
44 | }, |
45 | ); |
46 | if (!posts.length) { |
47 | return processedPosts; |
48 | } else if (posts.length < limit) { |
49 | runLoop = false; |
50 | } |
51 |
|
52 | await setState(posts[0].name); |
53 | const temp: Post[] = []; |
54 | for (let i = 0; i < posts.length; i++) { |
55 | const post = posts[i]; |
56 | const mention = |
57 | mentions.find((mention) => |
58 | post.title.toLowerCase().includes(mention), |
59 | ) || |
60 | mentions.find((mention) => |
61 | post.selftext.toLowerCase().includes(mention), |
62 | ); |
63 | mention && temp.push(post); |
64 | if (processedPosts.length + temp.length >= max_number_of_posts) { |
65 | break; |
66 | } |
67 | } |
68 | processedPosts.push(...temp.reverse()); |
69 | if (processedPosts.length >= max_number_of_posts) { |
70 | runLoop = false; |
71 | } |
72 | } while (runLoop); |
73 |
|
74 | return processedPosts; |
75 | } |
76 |
|
77 | interface Post { |
78 | name: string; |
79 | title: string; |
80 | selftext: string; |
81 | url: string; |
82 | } |
83 |
|