summaryrefslogtreecommitdiff
path: root/src/reddit.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/reddit.ts')
-rw-r--r--src/reddit.ts208
1 files changed, 0 insertions, 208 deletions
diff --git a/src/reddit.ts b/src/reddit.ts
deleted file mode 100644
index 5b4ded7..0000000
--- a/src/reddit.ts
+++ /dev/null
@@ -1,208 +0,0 @@
-import type { TimePeriod } from "./discord/types.ts";
-
-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;
- thumbnail?: string;
- preview?: {
- images: Array<{
- source: {
- url: string;
- width: number;
- height: number;
- };
- resolutions: Array<{
- url: string;
- width: number;
- height: number;
- }>;
- }>;
- enabled: boolean;
- };
- 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";
-
-const fetchWithRetry = async (
- url: string,
- maxRetries: number = 3,
-): Promise<Response> => {
- for (let attempt = 0; attempt < maxRetries; attempt++)
- try {
- await new Promise((resolve) =>
- setTimeout(resolve, Math.random() * 1000 + 500),
- );
-
- const response = await fetch(url, {
- headers: {
- "User-Agent":
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
- Accept:
- "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
- "Accept-Language": "en-US,en;q=0.5",
- "Accept-Encoding": "gzip, deflate, br",
- DNT: "1",
- Connection: "keep-alive",
- "Upgrade-Insecure-Requests": "1",
- },
- });
-
- return response;
- } catch (error) {
- if (attempt === maxRetries - 1) throw error;
-
- const delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
-
- console.log(`Attempt ${attempt + 1} failed, retrying in ${delay}ms ...`);
-
- await new Promise((resolve) => setTimeout(resolve, delay));
- }
-
- throw new Error("Max retries exceeded");
-};
-
-export const fetchRedditPosts = async (
- 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 fetchWithRetry(url);
-
- if (!response.ok) {
- let errorText = `Error fetching ${response.url}: ${response.status} ${response.statusText}`;
-
- try {
- const error = await response.text();
-
- if (
- error.includes("You've been blocked by network security") ||
- error.includes("blocked by network security")
- )
- throw new Error(
- "Reddit is blocking requests due to network security. This may be due to rate limiting or bot detection. Please try again later.",
- );
-
- if (error) errorText = `${errorText} \n\n ${error}`;
- } catch (err) {
- if (
- err instanceof Error &&
- err.message.includes("blocked by network security")
- )
- throw err;
- }
-
- throw new Error(errorText);
- }
-
- const data: RedditResponse = await response.json();
-
- return data.data.children.map((post) => post.data);
-};
-
-export const 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;
- });
-};
-
-const 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 const getCutePost = async (): Promise<RedditPost> => {
- const posts = await fetchRedditPosts("hot");
- const filteredPosts = filterPostsByFlair(posts, ["roleplay", "announcement"]);
-
- return getRandomPost(filteredPosts);
-};
-
-export const getRoleplayPost = async (): Promise<RedditPost> => {
- const posts = await fetchRedditPosts("hot");
- const filteredPosts = filterPostsByFlair(posts, [], ["roleplay"]);
-
- return getRandomPost(filteredPosts);
-};
-
-export const getNSFWPost = async (): Promise<RedditPost> => {
- const posts = await fetchRedditPosts("hot");
- const filteredPosts = filterPostsByFlair(posts, [], ["nsfw"]);
-
- return getRandomPost(filteredPosts);
-};
-
-export const getTopPost = async (
- time: TimePeriod = "day",
-): Promise<RedditPost> => {
- const posts = await fetchRedditPosts("top", time);
- const filteredPosts = filterPostsByFlair(posts, ["roleplay", "announcement"]);
-
- return getRandomPost(filteredPosts);
-};