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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
import type { TimePeriod } from './commands.js';
export interface RedditPost {
id: string;
title: string;
author: string;
score: number;
num_comments: number;
created_utc: number;
permalink: string;
url: string;
selftext: string;
is_gallery?: boolean;
over_18: boolean;
link_flair_text?: string;
media?: {
reddit_video?: {
fallback_url: string;
};
};
secure_media?: {
reddit_video?: {
fallback_url: string;
};
};
}
export interface RedditResponse {
data: {
children: Array<{
data: RedditPost;
}>;
};
}
type SortType = 'hot' | 'top';
async function fetchRedditPosts(
sort: SortType = 'hot',
time: TimePeriod = 'day',
): Promise<RedditPost[]> {
const url = `https://www.reddit.com/r/okbuddyumamusume/${sort}.json${sort === 'top' ? `?t=${time}` : ''}`;
const response = await fetch(url, {
headers: {
'User-Agent': 'UmaBot/0.1.0',
},
});
if (!response.ok) {
let errorText = `Error fetching ${response.url}: ${response.status} ${response.statusText}`;
try {
const error = await response.text();
if (error) errorText = `${errorText} \n\n ${error}`;
} catch {
//
}
throw new Error(errorText);
}
const data: RedditResponse = await response.json();
return data.data.children.map((post) => post.data);
}
function filterPostsByFlair(
posts: RedditPost[],
excludedFlairs: string[] = [],
includedFlairs: string[] = [],
): RedditPost[] {
return posts.filter((post) => {
if (post.is_gallery) return false;
const hasMedia =
post.media?.reddit_video?.fallback_url ||
post.secure_media?.reddit_video?.fallback_url ||
post.url;
if (!hasMedia) return false;
const postFlair = post.link_flair_text?.toLowerCase() || '';
const isNSFW = post.over_18 || postFlair.includes('nsfw');
if (
includedFlairs.length > 0 &&
includedFlairs.some((flair) => flair.toLowerCase() === 'nsfw')
)
if (includedFlairs.some((flair) => flair.toLowerCase() === 'nsfw'))
return isNSFW;
if (isNSFW) return false;
if (includedFlairs.length > 0)
return includedFlairs.some((flair) =>
postFlair.includes(flair.toLowerCase()),
);
if (excludedFlairs.length > 0)
return !excludedFlairs.some((flair) =>
postFlair.includes(flair.toLowerCase()),
);
return true;
});
}
function getRandomPost(posts: RedditPost[]): RedditPost {
if (posts.length === 0)
throw new Error('No posts found matching the criteria');
const randomIndex = Math.floor(Math.random() * posts.length);
return posts[randomIndex];
}
export async function getCutePost(): Promise<RedditPost> {
const posts = await fetchRedditPosts('hot');
const filteredPosts = filterPostsByFlair(posts, ['roleplay', 'announcement']);
return getRandomPost(filteredPosts);
}
export async function getRoleplayPost(): Promise<RedditPost> {
const posts = await fetchRedditPosts('hot');
const filteredPosts = filterPostsByFlair(posts, [], ['roleplay']);
return getRandomPost(filteredPosts);
}
export async function getNSFWPost(): Promise<RedditPost> {
const posts = await fetchRedditPosts('hot');
const filteredPosts = filterPostsByFlair(posts, [], ['nsfw']);
return getRandomPost(filteredPosts);
}
export async function getTopPost(
time: TimePeriod = 'day',
): Promise<RedditPost> {
const posts = await fetchRedditPosts('top', time);
const filteredPosts = filterPostsByFlair(posts, ['roleplay', 'announcement']);
return getRandomPost(filteredPosts);
}
|