DtrollMC

Untitled

Jul 15th, 2025
445
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. }
  2.  
  3. /**
  4.  * Fetches all comments for a specific user from the Reddit API.
  5.  * Handles pagination by making multiple requests until all comments are retrieved.
  6.  * @param username The Reddit username.
  7.  * @returns A promise that resolves to an array of comment objects.
  8.  */
  9. async function fetchAllComments(username: string): Promise<RedditComment[]> {
  10.   const allComments: RedditComment[] = [];
  11.   let after: string | null = null;
  12.   let pageCount = 0;
  13.  
  14.   console.log(`Starting to fetch comments for user: ${username}`);
  15.  
  16.   do {
  17.     // Construct the URL with the 'after' parameter for pagination
  18.     const url = new URL(`${REDDIT_API_BASE}/user/${username}/comments.json`);
  19.     url.searchParams.set("limit", "100"); // Max limit is 100 per page
  20.     if (after) {
  21.       url.searchParams.set("after", after);
  22.     }
  23.  
  24.     console.log(`Fetching page ${++pageCount}...`);
  25.  
  26.     const response = await fetch(url, {
  27.       headers: { "User-Agent": USER_AGENT },
  28.     });
  29.  
  30.     if (!response.ok) {
  31.       if (response.status === 404) {
  32.         throw new Error(`User "${username}" not found. (Status: ${response.status})`);
  33.       }
  34.       throw new Error(`Failed to fetch data from Reddit. Status: ${response.status}`);
  35.     }
  36.  
  37.     const data = await response.json();
  38.     const children = data?.data?.children;
  39.  
  40.     if (!children || children.length === 0) {
  41.       // No more comments to fetch
  42.       break;
  43.     }
  44.  
  45.     for (const child of children) {
  46.       if (child.kind === "t1") { // 't1' is the Reddit API's kind for a comment
  47.         const commentData = child.data;
  48.         allComments.push({
  49.           subreddit: commentData.subreddit,
  50.           created_utc: commentData.created_utc,
  51.           score: commentData.score,
  52.           // Prepend the base URL to make the permalink a full, clickable URL
  53.           permalink: `${REDDIT_API_BASE}${commentData.permalink}`,
  54.           // Clean up the body text by replacing newlines with spaces for better CSV compatibility
  55.           body: commentData.body.replace(/(\r\n|\n|\r)/gm, " "),
  56.         });
  57.       }
  58.     }
  59.  
  60.     // Get the 'after' token for the next page
  61.     after = data.data.after;
  62.    
  63.     // Be a good API citizen and wait a moment between requests
  64.     await new Promise(resolve => setTimeout(resolve, 1000));
  65.  
  66.   } while (after);
  67.  
  68.   console.log(`\nFinished fetching. Found a total of ${allComments.length} comments.`);
  69.   return allComments;
  70. }
  71.  
  72. /**
  73.  * Main execution function
  74.  */
  75. async function main() {
  76.   const username = Deno.args[0];
  77.  
  78.   if (!username) {
  79.     console.error("Error: Reddit username is required.");
  80.     console.error("Usage: deno run --allow-net --allow-write download_comments.ts <username>");
  81.     Deno.exit(1);
  82.   }
  83.  
  84.   try {
  85.     const comments = await fetchAllComments(username);
  86.  
  87.     if (comments.length === 0) {
  88.       console.log(`No comments found for user "${username}".`);
  89.       return;
  90.     }
  91.  
  92.     const outputFilename = `${username}_comments.csv`;
  93.    
  94.     // Define the headers and the order of columns in the CSV
  95.     const headers = [
  96.       "created_utc",
  97.       "subreddit",
  98.       "score",
  99.       "permalink",
  100.       "body",
  101.     ];
  102.  
  103.     // The `stringify` function converts an array of objects into a CSV string.
  104.     // The `columns` option ensures the columns are in the correct order.
  105.     const csvString = await stringify(comments, {
  106.       headers: true, // Include the header row
  107.       columns: headers,
  108.     });
  109.  
  110.     console.log(`Writing ${comments.length} comments to ${outputFilename}...`);
  111.     await Deno.writeTextFile(outputFilename, csvString);
  112.  
  113.     console.log(`✅ Success! File saved as ${outputFilename}`);
  114.   } catch (error) {
  115.     console.error(`\nAn error occurred: ${error.message}`);
  116.     Deno.exit(1);
  117.   }
  118. }
  119.  
  120. // Run the main function
  121. main();
  122.  
Advertisement
Add Comment
Please, Sign In to add comment