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