hide-reply.js
1 import { CommandExecutionError } from '@jackwener/opencli/errors'; 2 import { cli, Strategy } from '@jackwener/opencli/registry'; 3 cli({ 4 site: 'twitter', 5 name: 'hide-reply', 6 description: 'Hide a reply on your tweet (useful for hiding bot/spam replies)', 7 domain: 'x.com', 8 strategy: Strategy.UI, 9 browser: true, 10 args: [ 11 { name: 'url', type: 'string', required: true, positional: true, help: 'The URL of the reply tweet to hide' }, 12 ], 13 columns: ['status', 'message'], 14 func: async (page, kwargs) => { 15 if (!page) 16 throw new CommandExecutionError('Browser session required for twitter hide-reply'); 17 await page.goto(kwargs.url); 18 await page.wait({ selector: '[data-testid="primaryColumn"]' }); 19 const result = await page.evaluate(`(async () => { 20 try { 21 let attempts = 0; 22 let moreMenu = null; 23 24 while (attempts < 20) { 25 moreMenu = document.querySelector('[aria-label="More"]'); 26 if (moreMenu) break; 27 await new Promise(r => setTimeout(r, 500)); 28 attempts++; 29 } 30 31 if (!moreMenu) { 32 return { ok: false, message: 'Could not find the "More" menu on this tweet. Are you logged in?' }; 33 } 34 35 moreMenu.click(); 36 await new Promise(r => setTimeout(r, 1000)); 37 38 // Look for the "Hide reply" menu item 39 const items = document.querySelectorAll('[role="menuitem"]'); 40 let hideItem = null; 41 for (const item of items) { 42 if (item.textContent && item.textContent.includes('Hide reply')) { 43 hideItem = item; 44 break; 45 } 46 } 47 48 if (!hideItem) { 49 return { ok: false, message: 'Could not find "Hide reply" option. This may not be a reply on your tweet.' }; 50 } 51 52 hideItem.click(); 53 await new Promise(r => setTimeout(r, 1500)); 54 55 return { ok: true, message: 'Reply successfully hidden.' }; 56 } catch (e) { 57 return { ok: false, message: e.toString() }; 58 } 59 })()`); 60 if (result.ok) 61 await page.wait(2); 62 return [{ 63 status: result.ok ? 'success' : 'failed', 64 message: result.message 65 }]; 66 } 67 });