unlike.js
1 import { cli } from '@jackwener/opencli/registry'; 2 cli({ 3 site: 'tiktok', 4 name: 'unlike', 5 description: 'Unlike a TikTok video', 6 domain: 'www.tiktok.com', 7 args: [ 8 { name: 'url', required: true, positional: true, help: 'TikTok video URL' }, 9 ], 10 columns: ['status', 'likes', 'url'], 11 pipeline: [ 12 { navigate: { url: '${{ args.url }}', settleMs: 6000 } }, 13 { evaluate: `(async () => { 14 const url = \${{ args.url | json }}; 15 const btn = document.querySelector('[data-e2e="like-icon"]'); 16 if (!btn) throw new Error('Like button not found - make sure you are logged in'); 17 const container = btn.closest('button') || btn.closest('[role="button"]') || btn; 18 const aria = (container.getAttribute('aria-label') || '').toLowerCase(); 19 const color = window.getComputedStyle(btn).color; 20 const isLiked = aria.includes('unlike') || aria.includes('取消点赞') || 21 (color && (color.includes('255, 65') || color.includes('fe2c55'))); 22 if (!isLiked) { 23 const count = document.querySelector('[data-e2e="like-count"]'); 24 return [{ status: 'Not liked', likes: count ? count.textContent.trim() : '-', url: url }]; 25 } 26 container.click(); 27 await new Promise(r => setTimeout(r, 2000)); 28 const count = document.querySelector('[data-e2e="like-count"]'); 29 return [{ status: 'Unliked', likes: count ? count.textContent.trim() : '-', url: url }]; 30 })() 31 ` }, 32 ], 33 });