Guest User

Untitled

a guest
Sep 25th, 2025
18
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. javascript:(function() {    
  2.     var isXstalk = window.location.hostname.includes('xstalk.com') || window.location.hostname.includes('twstalker.com');
  3.     var tweetSelector = isXstalk ? '.tweet-container' : '.timeline-item';
  4.     var contentSelector = isXstalk ? '.tweet-body' : '.tweet-content';
  5.     var usernameSelector = isXstalk ? '.tweet-container .profile-link a span' : '.username';
  6.     var tweetLinkSelector = isXstalk ? '.tweet-container .profile-link a[href*="/status/"]' : '.tweet-link';
  7.     var authorSelector = isXstalk ? '.tweet-container .profile-link span' : '.username';
  8.     var imageSelector = isXstalk ? '.tweet-images img, .tweet-video video[poster]' : '.attachment.image img';
  9.     var videoSelector = isXstalk ? '.tweet-video video' : 'video';
  10.    
  11.     var tweets = Array.from(document.querySelectorAll(tweetSelector));
  12.     if (tweets.length === 0) {
  13.         tweets = Array.from(document.querySelectorAll('.timeline-item, .tweet-container'));
  14.         if (tweets.length === 0) return;
  15.     }
  16.    
  17.     var username = document.querySelector(usernameSelector);
  18.     if (!username) {
  19.         username = document.querySelector('.username, .tweet-container .profile-link span');
  20.         if (!username) return;
  21.     }
  22.     username = username.textContent.replace('@', '').trim();
  23.    
  24.     var userTweets = [];
  25.     var tweetTexts = [];
  26.     var imgCounter = 0;
  27.     var outputChains = [];
  28.     var totalTweetCount = 0;
  29.     var globalTweetCount = 0;
  30.    
  31.     function replaceDomain(url) {
  32.         return url.replace('nitter.poast.org', 'twitter.com').replace('xcancel.com', 'twitter.com').replace('xstalk.com', 'twitter.com').replace('twstalker.com', 'twitter.com');
  33.     }
  34.    
  35.     var currentUrl = replaceDomain(window.location.href);
  36.     if (currentUrl.includes('/status/')) {
  37.         currentUrl = currentUrl.split('?')[0];
  38.         userTweets.push(currentUrl);
  39.     }
  40.    
  41.     tweets.forEach(tweet => {
  42.         var tweetLink = tweet.querySelector(tweetLinkSelector);
  43.         var tweetAuthor = tweet.querySelector(authorSelector);
  44.        
  45.         if (tweetLink && tweetAuthor) {
  46.             var tweetLinkHref = new URL(tweetLink.href, window.location.href);
  47.             var newUrl = replaceDomain(tweetLinkHref.href);
  48.             if (newUrl && newUrl.includes('/status/')) {
  49.                 newUrl = newUrl.split('?')[0];
  50.             }
  51.             var authorName = tweetAuthor.textContent.replace('@', '').trim();
  52.             if (newUrl && newUrl.includes('/status/') && authorName === username) {
  53.                 userTweets.push(newUrl);
  54.             }
  55.         }
  56.        
  57.         var tweetContent = tweet.querySelector(contentSelector);
  58.         if (!tweetContent && isXstalk) {
  59.             tweetContent = tweet.querySelector('.tweet-body');
  60.         }
  61.        
  62.         if (tweetContent) {
  63.             var tweetText = tweetContent.innerHTML;
  64.            
  65.             var quotedTweets = Array.from(tweet.querySelectorAll('.quote.quote-big, .quote'));
  66.             var quotedTextForThisTweet = quotedTweets.map(quotedTweet => {
  67.                 var quoteTextElement = quotedTweet.querySelector('.quote-text, .tweet-body');
  68.                 var quoteUrlElement = quotedTweet.querySelector('.quote-link, a[href*="/status/"]');
  69.                 if (quoteTextElement && quoteUrlElement) {
  70.                     var quoteText = quoteTextElement.textContent;
  71.                     var quoteUrl = quoteUrlElement.href;
  72.                     var quoteUrlObj = new URL(quoteUrl, window.location.href);
  73.                     quoteUrlObj.hostname = 'twitter.com';
  74.                     return `[Quoted tweet]\n${quoteText}\n[U][URL]${quoteUrlObj.href}[/URL][/U]`;
  75.                 }
  76.                 return '';
  77.             }).filter(text => text !== '').join('\n\n');
  78.            
  79.             tweetText += `\n\n${quotedTextForThisTweet}`;
  80.             tweetText = tweetText.replace(/<a href="([^"]+)">[^<]+<\/a>/g, (match, p1) => `[U][URL]${p1}[/URL][/U]`);
  81.             tweetText = tweetText.replace(/<br[^>]*>/g, '\n');
  82.             tweetText = tweetText.replace(/<[^>]+>/g, '');
  83.             tweetText = tweetText.replace(/Β /g, ' ');
  84.             tweetText = tweetText.trim();
  85.            
  86.             var images = Array.from(tweet.querySelectorAll(imageSelector));
  87.             var imageUrlsForThisTweet = images.map(img => {
  88.                 var src = decodeURIComponent(img.src || img.getAttribute('poster') || '');
  89.                 if (!src) return '';
  90.                
  91.                 var url = new URL(src, window.location.href);
  92.                
  93.                 if (url.hostname.includes('xcancel.com') && url.pathname.includes('/pic/')) {
  94.                     var pathParts = url.pathname.split('/');
  95.                     var mediaPart = pathParts[pathParts.length - 1];
  96.                     var decodedMedia = decodeURIComponent(mediaPart);
  97.                     var filename = decodedMedia.split('?')[0];
  98.                     var match = filename.match(/([^\/]+)$/);
  99.                     if (match) {
  100.                         return `[img]https://pbs.twimg.com/media/${match[1]}[/img]`;
  101.                     }
  102.                 }
  103.                
  104.                 if (src.includes('pbs.twimg.com') && (src.includes('ext_tw_video_thumb') || src.includes('media'))) {
  105.                     var posterMatch = src.match(/\/([^\/]+)\.(jpg|png|webp)/);
  106.                     if (posterMatch) {
  107.                         return `[img]https://pbs.twimg.com/media/${posterMatch[1]}.${posterMatch[2]}[/img]`;
  108.                     }
  109.                 }
  110.                
  111.                 url.hostname = 'pbs.twimg.com';
  112.                 url.pathname = url.pathname.replace('/pic/', '/media/').replace('/media/media/', '/media/');
  113.                 url.search = '';
  114.                 return `[img]${url.href}[/img]`;
  115.             }).filter(url => url !== '').join('\n');
  116.            
  117.             if (imgCounter + images.length > 20 && tweetTexts.length > 0) {
  118.                 createChain();
  119.             }
  120.            
  121.             imgCounter += images.length;
  122.             if (imageUrlsForThisTweet) {
  123.                 tweetText += `\n\n${imageUrlsForThisTweet}`;
  124.             }
  125.            
  126.             var videos = Array.from(tweet.querySelectorAll(videoSelector));
  127.             var videoUrlsForThisTweet = videos.map(video => {
  128.                 var source = video.querySelector('source');
  129.                 var src = source ? source.src : video.src;
  130.                 if (!src) return '';
  131.                
  132.                 if (src && (src.startsWith('https://video') && (src.includes('twimg.com/ext_tw_video/') || src.includes('twimg.com/amplify_video/')))) {
  133.                     src = src.split('?')[0];
  134.                     return `[U][URL]${src}[/URL][/U]`;
  135.                 }
  136.                 return '';
  137.             }).filter(url => url !== '').join('\n');
  138.            
  139.             if (videoUrlsForThisTweet) {
  140.                 tweetText += `\n\n${videoUrlsForThisTweet}`;
  141.             }
  142.            
  143.             globalTweetCount++;
  144.             totalTweetCount++;
  145.             var authorName = tweetAuthor ? tweetAuthor.textContent.replace('@', '').trim() : username;
  146.             tweetTexts.push({ text: tweetText.trim(), author: authorName, index: globalTweetCount });
  147.         }
  148.     });
  149.    
  150.     if (tweetTexts.length > 0) {
  151.         createChain();
  152.     }
  153.    
  154.     function createChain() {
  155.         if (userTweets.length === 0) return;
  156.        
  157.         var firstNewChainUrl = userTweets.shift();
  158.         var formattedText = `\n` + [
  159.             firstNewChainUrl,
  160.             `[SPOILER="thread continued"]\n${userTweets.map(url => replaceDomain(url)).map(url => {
  161.                 return url.includes('/status/') ? url.split('?')[0] : url;
  162.             }).join('\n')}\n[/SPOILER]`,
  163.             `[SPOILER="full text & large images"]\n\n${tweetTexts.map((tweet, index) =>
  164.                 `${index + 1}/${tweetTexts.length}\n@${tweet.author}\n${tweet.text}\n`).join('\n')}\n\n` +
  165.             `[COLOR=rgb(184, 49, 47)][B][SIZE=5]To post tweets in this format, more info here: ` +
  166.             `[URL]https://www.thecoli.com/threads/tips-and-tricks-for-posting-the-coli-megathread.984734/post-52211196[/URL][/SIZE][/B][/COLOR]\n[/SPOILER]`
  167.         ].join('\n');
  168.        
  169.         formattedText = formattedText.replace(/(\d+\/\d+)\s@/g, '$1\n@');
  170.         outputChains.push(formattedText);
  171.        
  172.         imgCounter = 0;
  173.         tweetTexts = [];
  174.         totalTweetCount = 0;
  175.     }
  176.    
  177.     var finalFormattedText = outputChains.join('\n\n[threads continued]\n\n');
  178.    
  179.     var textArea = document.createElement('textarea');
  180.     textArea.value = finalFormattedText;
  181.     document.body.appendChild(textArea);
  182.     textArea.select();
  183.     document.execCommand('copy');
  184.     document.body.removeChild(textArea);
  185.    
  186.     var notificationBox = document.createElement('div');
  187.     notificationBox.style.position = 'fixed';
  188.     notificationBox.style.bottom = '20px';
  189.     notificationBox.style.left = '20px';
  190.     notificationBox.style.padding = '10px';
  191.     notificationBox.style.backgroundColor = 'white';
  192.     notificationBox.style.border = '1px solid black';
  193.     notificationBox.innerText = `Copied: ${globalTweetCount} tweets`;
  194.     document.body.appendChild(notificationBox);
  195.    
  196.     setTimeout(function() {
  197.         notificationBox.style.opacity = '0';
  198.         setTimeout(function() {
  199.             document.body.removeChild(notificationBox);
  200.         }, 1000);
  201.     }, 2000);
  202.    
  203.     console.log('Tweet collection process completed and copied to clipboard.');
  204. })();
Advertisement
Add Comment
Please, Sign In to add comment