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 { 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 { const posts = await fetchRedditPosts('hot'); const filteredPosts = filterPostsByFlair(posts, ['roleplay', 'announcement']); return getRandomPost(filteredPosts); } export async function getRoleplayPost(): Promise { const posts = await fetchRedditPosts('hot'); const filteredPosts = filterPostsByFlair(posts, [], ['roleplay']); return getRandomPost(filteredPosts); } export async function getNSFWPost(): Promise { const posts = await fetchRedditPosts('hot'); const filteredPosts = filterPostsByFlair(posts, [], ['nsfw']); return getRandomPost(filteredPosts); } export async function getTopPost( time: TimePeriod = 'day', ): Promise { const posts = await fetchRedditPosts('top', time); const filteredPosts = filterPostsByFlair(posts, ['roleplay', 'announcement']); return getRandomPost(filteredPosts); }