// Name: Cloudinary Saver // Description: Saves Reddit posts to Cloudinary // Author: johnlindquist import "@johnlindquist/kit" import cloudinary from 'cloudinary' // Get Reddit username and Cloudinary credentials from environment variables const username = await env('REDDIT_USERNAME', { placeholder: 'Your Reddit username', }) cloudinary.v2.config({ cloud_name: await env('CLOUDINARY_CLOUD_NAME'), api_key: await env('CLOUDINARY_API_KEY'), api_secret: await env('CLOUDINARY_API_SECRET'), }) /** * Fetches saved posts from Reddit for the specified user. * @returns {Promise<any[]>} A promise that resolves to an array of Reddit post objects. */ const fetchRedditPosts = async () => { const savedPostsUrl = `https://www.reddit.com/user/${username}/saved/.json` const response = await get(savedPostsUrl) if(!response.data || !response.data.data || !response.data.data.children) { throw new Error(`Invalid response from Reddit API: ${JSON.stringify(response)}`); } return response.data.data.children } /** * Uploads content to Cloudinary and returns a markdown link. * @param {string} content The content to upload (text or image URL). * @param {string} title The title to use in the markdown link. * @returns {Promise<string>} A promise that resolves to a markdown image link. */ const uploadToCloudinary = async (content: string, title: string) => { const options = { public_id: `reddit_posts/${Date.now()}`, unique_filename: true, use_filename: true, overwrite: true, filename_override: true, resource_type: 'auto', }; try { const uploadResponse = await cloudinary.v2.uploader.upload(content, options); return ``; } catch (error) { console.error("Cloudinary upload failed:", error); throw new Error(`Failed to upload to Cloudinary: ${error}`); } }; /** * Processes Reddit saved posts, uploads their content to Cloudinary, and displays markdown links in an editor. */ const processPosts = async () => { const posts = await fetchRedditPosts() if(!posts || posts.length === 0) { console.warn("No saved posts found for user:", username); await editor("No saved posts found."); return; } const savedPostLinks: string[] = [] for (const post of posts) { if (!post?.data) { console.warn("Skipping post with invalid data:", post); continue; } const title = post.data.title; const url = post.data.url; let content:string; if (post.data.selftext) { content = post.data.selftext; } else if (url?.startsWith('https://i.redd.it/')) { content = url; } else { content = url } try { const cloudinaryLink = await uploadToCloudinary(content, title); savedPostLinks.push(cloudinaryLink) } catch (error) { console.error(`Error processing post: ${title}`, error) } } if (savedPostLinks.length === 0) { console.warn("No posts were successfully processed."); await editor("No posts were successfully processed."); return; } await editor(savedPostLinks.join('\n\n')) } await processPosts()