/ clis / twitter / unfollow.js
unfollow.js
 1  import { cli, Strategy } from '@jackwener/opencli/registry';
 2  import { CommandExecutionError } from '@jackwener/opencli/errors';
 3  cli({
 4      site: 'twitter',
 5      name: 'unfollow',
 6      description: 'Unfollow a Twitter user',
 7      domain: 'x.com',
 8      strategy: Strategy.UI,
 9      browser: true,
10      args: [
11          { name: 'username', type: 'string', positional: true, required: true, help: 'Twitter screen name (without @)' },
12      ],
13      columns: ['status', 'message'],
14      func: async (page, kwargs) => {
15          if (!page)
16              throw new CommandExecutionError('Browser session required for twitter unfollow');
17          const username = kwargs.username.replace(/^@/, '');
18          await page.goto(`https://x.com/${username}`);
19          await page.wait({ selector: '[data-testid="primaryColumn"]' });
20          const result = await page.evaluate(`(async () => {
21          try {
22              let attempts = 0;
23              let unfollowBtn = null;
24  
25              while (attempts < 20) {
26                  // Check if already not following
27                  const followBtn = document.querySelector('[data-testid$="-follow"]');
28                  if (followBtn) {
29                      return { ok: true, message: 'Not following @${username} (already unfollowed).' };
30                  }
31  
32                  unfollowBtn = document.querySelector('[data-testid$="-unfollow"]');
33                  if (unfollowBtn) break;
34  
35                  await new Promise(r => setTimeout(r, 500));
36                  attempts++;
37              }
38  
39              if (!unfollowBtn) {
40                  return { ok: false, message: 'Could not find Unfollow button. Are you logged in?' };
41              }
42  
43              // Click the unfollow button — this opens a confirmation dialog
44              unfollowBtn.click();
45              await new Promise(r => setTimeout(r, 1000));
46  
47              // Confirm the unfollow in the dialog
48              const confirmBtn = document.querySelector('[data-testid="confirmationSheetConfirm"]');
49              if (confirmBtn) {
50                  confirmBtn.click();
51                  await new Promise(r => setTimeout(r, 1000));
52              }
53  
54              // Verify
55              const verify = document.querySelector('[data-testid$="-follow"]');
56              if (verify) {
57                  return { ok: true, message: 'Successfully unfollowed @${username}.' };
58              } else {
59                  return { ok: false, message: 'Unfollow action initiated but UI did not update.' };
60              }
61          } catch (e) {
62              return { ok: false, message: e.toString() };
63          }
64      })()`);
65          if (result.ok)
66              await page.wait(2);
67          return [{
68                  status: result.ok ? 'success' : 'failed',
69                  message: result.message
70              }];
71      }
72  });