/ clis / reddit / saved.js
saved.js
 1  import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';
 2  import { cli, Strategy } from '@jackwener/opencli/registry';
 3  cli({
 4      site: 'reddit',
 5      name: 'saved',
 6      description: 'Browse your saved Reddit posts',
 7      domain: 'reddit.com',
 8      strategy: Strategy.COOKIE,
 9      browser: true,
10      args: [
11          { name: 'limit', type: 'int', default: 15 },
12      ],
13      columns: ['title', 'subreddit', 'score', 'comments', 'url'],
14      func: async (page, kwargs) => {
15          if (!page)
16              throw new CommandExecutionError('Browser session required');
17          await page.goto('https://www.reddit.com');
18          const result = await page.evaluate(`(async () => {
19        try {
20          // Get current username
21          const meRes = await fetch('/api/me.json?raw_json=1', { credentials: 'include' });
22          const me = await meRes.json();
23          const username = me?.name || me?.data?.name;
24          if (!username) return { error: 'Not logged in — cannot determine username' };
25  
26          const limit = ${kwargs.limit};
27          const res = await fetch('/user/' + username + '/saved.json?limit=' + limit + '&raw_json=1', {
28            credentials: 'include'
29          });
30          const d = await res.json();
31          return (d?.data?.children || []).map(c => ({
32            title: c.data.title || c.data.body?.slice(0, 100) || '-',
33            subreddit: c.data.subreddit_name_prefixed || 'r/' + (c.data.subreddit || '?'),
34            score: c.data.score || 0,
35            comments: c.data.num_comments || 0,
36            url: 'https://www.reddit.com' + (c.data.permalink || ''),
37          }));
38        } catch (e) {
39          return { error: e.toString() };
40        }
41      })()`);
42          if (result?.error) {
43              if (String(result.error).includes('Not logged in'))
44                  throw new AuthRequiredError('reddit.com', result.error);
45              throw new CommandExecutionError(result.error);
46          }
47          return (result || []).slice(0, kwargs.limit);
48      }
49  });