Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- }
- /**
- * Fetches all comments for a specific user from the Reddit API.
- * Handles pagination by making multiple requests until all comments are retrieved.
- * @param username The Reddit username.
- * @returns A promise that resolves to an array of comment objects.
- */
- async function fetchAllComments(username: string): Promise<RedditComment[]> {
- const allComments: RedditComment[] = [];
- let after: string | null = null;
- let pageCount = 0;
- console.log(`Starting to fetch comments for user: ${username}`);
- do {
- // Construct the URL with the 'after' parameter for pagination
- const url = new URL(`${REDDIT_API_BASE}/user/${username}/comments.json`);
- url.searchParams.set("limit", "100"); // Max limit is 100 per page
- if (after) {
- url.searchParams.set("after", after);
- }
- console.log(`Fetching page ${++pageCount}...`);
- const response = await fetch(url, {
- headers: { "User-Agent": USER_AGENT },
- });
- if (!response.ok) {
- if (response.status === 404) {
- throw new Error(`User "${username}" not found. (Status: ${response.status})`);
- }
- throw new Error(`Failed to fetch data from Reddit. Status: ${response.status}`);
- }
- const data = await response.json();
- const children = data?.data?.children;
- if (!children || children.length === 0) {
- // No more comments to fetch
- break;
- }
- for (const child of children) {
- if (child.kind === "t1") { // 't1' is the Reddit API's kind for a comment
- const commentData = child.data;
- allComments.push({
- subreddit: commentData.subreddit,
- created_utc: commentData.created_utc,
- score: commentData.score,
- // Prepend the base URL to make the permalink a full, clickable URL
- permalink: `${REDDIT_API_BASE}${commentData.permalink}`,
- // Clean up the body text by replacing newlines with spaces for better CSV compatibility
- body: commentData.body.replace(/(\r\n|\n|\r)/gm, " "),
- });
- }
- }
- // Get the 'after' token for the next page
- after = data.data.after;
- // Be a good API citizen and wait a moment between requests
- await new Promise(resolve => setTimeout(resolve, 1000));
- } while (after);
- console.log(`\nFinished fetching. Found a total of ${allComments.length} comments.`);
- return allComments;
- }
- /**
- * Main execution function
- */
- async function main() {
- const username = Deno.args[0];
- if (!username) {
- console.error("Error: Reddit username is required.");
- console.error("Usage: deno run --allow-net --allow-write download_comments.ts <username>");
- Deno.exit(1);
- }
- try {
- const comments = await fetchAllComments(username);
- if (comments.length === 0) {
- console.log(`No comments found for user "${username}".`);
- return;
- }
- const outputFilename = `${username}_comments.csv`;
- // Define the headers and the order of columns in the CSV
- const headers = [
- "created_utc",
- "subreddit",
- "score",
- "permalink",
- "body",
- ];
- // The `stringify` function converts an array of objects into a CSV string.
- // The `columns` option ensures the columns are in the correct order.
- const csvString = await stringify(comments, {
- headers: true, // Include the header row
- columns: headers,
- });
- console.log(`Writing ${comments.length} comments to ${outputFilename}...`);
- await Deno.writeTextFile(outputFilename, csvString);
- console.log(`✅ Success! File saved as ${outputFilename}`);
- } catch (error) {
- console.error(`\nAn error occurred: ${error.message}`);
- Deno.exit(1);
- }
- }
- // Run the main function
- main();
Advertisement
Add Comment
Please, Sign In to add comment