summaryrefslogtreecommitdiff
path: root/src/reddit.ts
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-09-07 03:26:30 -0700
committerFuwn <[email protected]>2025-09-07 03:26:30 -0700
commit087895920eb1610ab72c056138ef406e3f971044 (patch)
tree5e9d2be5cf8113aeab9fe98dcf85ab7e3d6fef92 /src/reddit.ts
parentbuild: Switch to TypeScript (diff)
downloadumabotdiscord-087895920eb1610ab72c056138ef406e3f971044.tar.xz
umabotdiscord-087895920eb1610ab72c056138ef406e3f971044.zip
fix: Add rate-limit mitigation
Diffstat (limited to 'src/reddit.ts')
-rw-r--r--src/reddit.ts52
1 files changed, 42 insertions, 10 deletions
diff --git a/src/reddit.ts b/src/reddit.ts
index 79475b1..5c5ae0b 100644
--- a/src/reddit.ts
+++ b/src/reddit.ts
@@ -1,4 +1,4 @@
-import type { TimePeriod } from './commands.js';
+import type { TimePeriod } from './commands.ts';
export interface RedditPost {
id: string;
@@ -35,26 +35,58 @@ export interface RedditResponse {
type SortType = 'hot' | 'top';
-async function fetchRedditPosts(
+async function fetchWithRetry(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 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',
- },
- });
+ 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 {
- //
+ } catch (err) {
+ if (err instanceof Error && err.message.includes('blocked by network security'))
+ throw err;
}
throw new Error(errorText);
@@ -65,7 +97,7 @@ async function fetchRedditPosts(
return data.data.children.map((post) => post.data);
}
-function filterPostsByFlair(
+export function filterPostsByFlair(
posts: RedditPost[],
excludedFlairs: string[] = [],
includedFlairs: string[] = [],