Heimdall

Pro
Joined
Dec 13, 2019
Messages
348
Reputation
211
Daps
830
:whoo: this thread tho

It's still wild to me that you can generate whole userscripts like that
 

bnew

Veteran
Joined
Nov 1, 2015
Messages
48,128
Reputation
7,631
Daps
141,262
:whoo: this thread tho

It's still wild to me that you can generate whole userscripts like that
just start out small and when it gives you code that works, just iterate over it with more modification requests.

people absolutely have a need for this but they don't even know yet, it's like how when a lot more people started going online and doing online shopping when the iphone came out. knew the power of the internet way before that.:wow:
 

Heimdall

Pro
Joined
Dec 13, 2019
Messages
348
Reputation
211
Daps
830
just start out small and when it gives you code that works, just iterate over it with more modification requests.

people absolutely have a need for this but they don't even know yet, it's like how when a lot more people started going online and doing online shopping when the iphone came out. knew the power of the internet way before that.:wow:
I actually hadn't tried any AI tools yet, I had been avoiding them :hamster: until yesterday - I used ChatGPT to help me write part of my LinkedIn profile - and... it was even easier than I expected it to be 😅 (though I'm not sure how much I actually used, it generated some good content)

This is really potent. :lupe:
 

Dwayne_Taylor

Superstar
Joined
Aug 6, 2015
Messages
6,850
Reputation
571
Daps
29,344
y0X5D6y38Nm6
[/URL]
Meme Drop
 

bnew

Veteran
Joined
Nov 1, 2015
Messages
48,128
Reputation
7,631
Daps
141,262
made another bookmarklet to speed up posting multiple tweets and images from tweets. the bookmarklet will only work on tweet urls. like https://twitter.com/username/status/1234567890123456


A.I. Generated summary:
##
This code is a bookmarklet that can be used to copy the links of a user’s tweets and images from Twitter. Here is a summary of what it does:
  • It gets the username from the current window location and selects all the links that start with the user’s status.
  • It filters out the links that contain analytics or photo parameters and stores the unique tweet URLs in an array called userTweets.
  • It also selects all the images that are attached to the tweets and gets their URLs. It stores them in an array called imageUrls.
  • It then selects all the images that are hosted on pbs.twimg.com and gets their direct URLs. It adds them to the imageUrls array with
    tags around them.
  • It creates a textarea element and sets its value to a string that contains the first tweet URL, followed by a spoiler tag with the rest of the tweet URLs, followed by another spoiler tag with the image URLs.
  • It appends the textarea to the document body, selects its content, and copies it to the clipboard. It then removes the textarea from the document body.
  • It creates a notification box element and sets its text to the number of links copied. It appends it to the document body and fades it out after 2 seconds. It then removes the notification box from the document body.
##
2nd summary:
###
This JavaScript code is designed to extract tweet URLs and image URLs from a Twitter user's profile page. Here's a summary of what it does:

1. It first extracts the username from the current URL.
2. It then finds all the tweet links on the page and filters out any links that include '/analytics' or '/photo/'.
3. It collects all the image URLs from the tweets, which are identified by the class 'attachment.image' and the tag 'a.still-image'.
4. It also collects all the image URLs that are directly linked to from 'img' tags with a source starting with 'https://pbs.twimg.com/media/'.
5. It modifies these image URLs to include the '
' tags that are commonly used in forums to display images.
6. It creates a textarea element, populates it with the tweet URLs and image URLs, and copies the content to the clipboard.
7. After copying, it creates a notification box that appears at the bottom of the page for 2 seconds, informing the user about the number of links copied.
8. Finally, it removes the textarea and the notification box from the page.

Please note that this code is designed to be run in a browser's developer console or as a bookmarklet. It may not work correctly if run in a different context.
###

instructions to use it:
Sure, here are the steps to add a bookmarklet to your browser:

1. **Open your browser**: You can use any browser like Google Chrome, Firefox, Safari, etc.

2. **Create a new bookmark**:

- **Google Chrome**: Click on the three dots in the top-right corner of your browser, then select "Bookmarks" > "Bookmark Manager". Click on "Bookmark Bar" at the bottom of the bookmark manager, then click on the three dots again and select "Add new bookmark".

- **Firefox**: Click on the three lines in the top-right corner of your browser, then select "Bookmarks" > "Bookmark This Page".

- **Safari**: Click on "Safari" in the top-left corner of your browser, then select "Preferences". Go to the "Advanced" tab and check "Show Develop menu in menu bar". Now, click on the "Develop" menu in the menu bar, then select "Show Bookmarks Bar". Right-click on the bookmarks bar and select "Add Page".

3. **Name your bookmark**: Name your bookmark something like "Twitter Image Extractor".

4. **Edit the bookmark**: Click on the "Edit" button next to the bookmark you just created.

5. **Add the bookmarklet code**: In the "Location" field, paste the following code:



6. **Save the bookmark**: Click on "Done" or "Save" to save the bookmark.

### you can also highlight the code and DRAG & DROP it into your browsers bookmarks toolbar.

Now, whenever you visit a Twitter profile page, you can click on this bookmarklet to extract the tweet URLs and image URLs, and copy them to your clipboard.



I went to this link https://twitter.com/vangeorgh/status/1759168160052162682 and clicked the bookmarklet, the contents copied to clipboard will look like this:

Code:
https://twitter.com/vangeorgh/status/1759168160052162682
[SPOILER="thread continued"]
https://twitter.com/vangeorgh/status/1759168173264224631
https://twitter.com/vangeorgh/status/1759168181795520605
https://twitter.com/vangeorgh/status/1759168195196248237
https://twitter.com/vangeorgh/status/1759168210039976426
https://twitter.com/vangeorgh/status/1759168216025248071
https://twitter.com/vangeorgh/status/1759168228989751460
https://twitter.com/vangeorgh/status/1759168243086897355
https://twitter.com/vangeorgh/status/1759168256655462721
[/SPOILER]
[SPOILER="larger images"]
[img]https://pbs.twimg.com/media/GGnSHRCXUAAFuib.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSIBTXwAAqxN4.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSIBPXsAAjTey.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSIBTWkAAEoQs.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSIBOX0AAAmCA.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSJRBXsAAPBfw.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSJRAW4AAuqG1.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSJRVXsAACRCJ.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSKKkWsAAcfRJ.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSKKbXMAENx9z.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSKKZXMAMJYJm.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSLS9WoAAow1K.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSLTCXEAARPsw.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSLS-XMAANhxo.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSLTEWMAA8rsK.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSMGdXoAAYO-Q.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSMGaWAAAkK2j.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSMGhWEAAgGrC.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSMGcWoAA80kq.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSM7CXkAAm5Es.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSM7DW4AAC9Sd.jpg[/img]
[img]https://pbs.twimg.com/media/GGnSM7CWUAA3EnS.jpg[/img]
[/SPOILER]
** side note : the forum won't accept some types of code being posted through the form so i have to use pastebin.
 
Last edited:

bnew

Veteran
Joined
Nov 1, 2015
Messages
48,128
Reputation
7,631
Daps
141,262
new and improved script which took longer than the original to create because of twitter's complex code.

what's new:
text from the main users{OP) tweet is extracted and put inside a spoiler tag.



the code isn't perfect because the text it extracts doesn't have properly formatted urls but i'll try to get that fixed eventually. some of the tweets must be visible when you click the bookmarklet otherwise it might not grab all the tweet links and images if it's a really long twitter thread like 10+ tweets. you might have to run the bookmarklet twice in that instance.

### you can also highlight the code and DRAG & DROP it into your browsers bookmarks toolbar.


code output example:
Code:
https://twitter.com/bindureddy/status/1730248977499762740
[SPOILER="thread continued"]
https://twitter.com/bindureddy/status/1730248977499762740
https://twitter.com/bindureddy/status/1730370773242757463
https://twitter.com/bindureddy/status/1730607977294627299
[/SPOILER]
[SPOILER="full text"]
1/3
A day doesn't go by without a powerful open-source AI model drop.

DeepSeek (67B) makes up for the open-source shortcomings - math and coding!!

It beats Claude-2, scoring 65 on a National High School Exam.

DeepSeek is from China and is proof that the Chinese don't need our LLM tech; they can develop their own and are enlightened enough to open-source it!!

We are taking a look this week and will make it available in the Abacus AI platform next.

2/3
Can you elaborate more?

3/3
Thanks, I will dive into the details of the eval today - on first glance the model seems pretty good and is much faster than Llama-2
[/SPOILER]
[SPOILER="larger images"]
[img]https://pbs.twimg.com/media/GAMUJ5TbEAAE7hp.jpg[/img]
[/SPOILER]
 

bnew

Veteran
Joined
Nov 1, 2015
Messages
48,128
Reputation
7,631
Daps
141,262
created with Claude 3 Sonnet / claude-3-sonnet-20240229
A.I generated explanation..

This userscript adds a handy character counter next to the "Post Reply" button when you're writing a new post or reply on a forum thread. The character counter shows you how many characters you've typed in the message box, and it has a limit of 5000 characters (excluding spaces).

As you're typing your message, the character counter will display the current number of characters you've typed, followed by the maximum limit of 5000. For example, if you've typed 250 characters, the counter will show "250/5000".

If you go over the 5000 character limit, the character counter will turn red and bold, and a warning message will appear next to it, saying "Character limit exceeded". This way, you'll know that you've exceeded the character limit and need to shorten your message.

However, if you delete some characters and bring the count back within the 5000 character limit, the character counter will return to its normal style, and the warning message will disappear.

This userscript is designed to work on any forum thread page that has ".com/threads/" in the URL. Once you install it in your browser, it will automatically add the character counter to the post thread form, making it easier for you to keep track of your message length and avoid going over the character limit.

userscript:
Code:
// ==UserScript==
// @name         Add Live Character Counter to Post Form
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Adds a live character counter next to the "Post Reply" button in the post thread form on websites with ".com/threads/*" in the URL. The counter has a limit of 5000 characters (excluding spaces) and displays a warning message if the limit is exceeded. Works with both HTML and BBCode editor modes.
// @author       Your Name
// @match        *://*.com/threads/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function addCharacterCounter() {
        var postForm = document.querySelector('.message-editorWrapper');
        if (postForm) {
            var textarea = postForm.querySelector('textarea.input[name="message"]');
            var richTextEditor = postForm.querySelector('.fr-element.fr-view');
            if (textarea || richTextEditor) {
                var formButtonGroup = postForm.querySelector('.formButtonGroup');
                if (formButtonGroup) {
                    var counterContainer = document.createElement('div');
                    counterContainer.classList.add('character-counter');
                    counterContainer.style.display = 'flex';
                    counterContainer.style.alignItems = 'center';
                    counterContainer.style.marginRight = '10px';

                    var counterLabel = document.createElement('span');
                    counterLabel.style.marginRight = '5px';
                    counterLabel.textContent = '0/5000';

                    var warningMessage = document.createElement('span');
                    warningMessage.style.color = 'red';
                    warningMessage.style.fontWeight = 'normal';
                    warningMessage.textContent = 'Character limit exceeded';
                    warningMessage.style.display = 'none';

                    counterContainer.appendChild(counterLabel);
                    counterContainer.appendChild(warningMessage);
                    formButtonGroup.insertBefore(counterContainer, formButtonGroup.firstChild);

                    var updateCounter = function() {
                        var inputText = '';
                        if (textarea && textarea.style.display !== 'none') {
                            inputText = textarea.value;
                        } else if (richTextEditor && richTextEditor.style.display !== 'none') {
                            inputText = richTextEditor.textContent;
                        }
                        var nonSpaceChars = inputText.replace(/\s/g, '').length;
                        var charCount = nonSpaceChars + '/5000';

                        if (nonSpaceChars > 5000) {
                            counterLabel.style.color = 'red';
                            counterLabel.style.fontWeight = 'bold';
                            warningMessage.style.display = 'inline';
                        } else {
                            counterLabel.style.color = '';
                            counterLabel.style.fontWeight = 'normal';
                            warningMessage.style.display = 'none';
                        }

                        counterLabel.textContent = charCount;
                    };

                    var handleInputChange = function() {
                        updateCounter();
                    };

                    if (textarea) {
                        textarea.addEventListener('input', handleInputChange);
                    }

                    if (richTextEditor) {
                        var observer = new MutationObserver(handleInputChange);
                        observer.observe(richTextEditor, { childList: true, characterData: true, subtree: true });
                    }

                    updateCounter(); // Call updateCounter initially

                    var editorModeObserver = new MutationObserver(function(mutations) {
                        mutations.forEach(function(mutation) {
                            if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                                updateCounter();
                            }
                        });
                    });

                    var editorContainer = document.querySelector('.fr-box');
                    if (editorContainer) {
                        editorModeObserver.observe(editorContainer, { attributes: true, attributeFilter: ['class'] });
                    }
                }
            }
        }
    }

    window.addEventListener('load', addCharacterCounter);
})();

bookmarklet
Code:
javascript:(function() {
    function addCharacterCounter() {
        var postForm = document.querySelector('.message-editorWrapper');
        if (postForm) {
            var textarea = postForm.querySelector('textarea.input[name="message"]');
            var richTextEditor = postForm.querySelector('.fr-element.fr-view');
            if (textarea || richTextEditor) {
                var formButtonGroup = postForm.querySelector('.formButtonGroup');
                if (formButtonGroup) {
                    var counterContainer = document.createElement('div');
                    counterContainer.classList.add('character-counter');
                    counterContainer.style.display = 'flex';
                    counterContainer.style.alignItems = 'center';
                    counterContainer.style.marginRight = '10px';

                    var counterLabel = document.createElement('span');
                    counterLabel.style.marginRight = '5px';
                    counterLabel.textContent = '0/5000';

                    var warningMessage = document.createElement('span');
                    warningMessage.style.color = 'red';
                    warningMessage.style.fontWeight = 'normal';
                    warningMessage.textContent = 'Character limit exceeded';
                    warningMessage.style.display = 'none';

                    counterContainer.appendChild(counterLabel);
                    counterContainer.appendChild(warningMessage);
                    formButtonGroup.insertBefore(counterContainer, formButtonGroup.firstChild);

                    var updateCounter = function() {
                        var inputText = '';
                        if (textarea && textarea.style.display !== 'none') {
                            inputText = textarea.value;
                        } else if (richTextEditor && richTextEditor.style.display !== 'none') {
                            inputText = richTextEditor.textContent;
                        }
                        var nonSpaceChars = inputText.replace(/\s/g, '').length;
                        var charCount = nonSpaceChars + '/5000';

                        if (nonSpaceChars > 5000) {
                            counterLabel.style.color = 'red';
                            counterLabel.style.fontWeight = 'bold';
                            warningMessage.style.display = 'inline';
                        } else {
                            counterLabel.style.color = '';
                            counterLabel.style.fontWeight = 'normal';
                            warningMessage.style.display = 'none';
                        }

                        counterLabel.textContent = charCount;
                    };

                    var handleInputChange = function() {
                        updateCounter();
                    };

                    if (textarea) {
                        textarea.addEventListener('input', handleInputChange);
                    }

                    if (richTextEditor) {
                        var observer = new MutationObserver(handleInputChange);
                        observer.observe(richTextEditor, { childList: true, characterData: true, subtree: true });
                    }

                    updateCounter(); // Call updateCounter initially

                    var editorModeObserver = new MutationObserver(function(mutations) {
                        mutations.forEach(function(mutation) {
                            if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                                updateCounter();
                            }
                        });
                    });

                    var editorContainer = document.querySelector('.fr-box');
                    if (editorContainer) {
                        editorModeObserver.observe(editorContainer, { attributes: true, attributeFilter: ['class'] });
                    }
                }
            }
        }
    }

    addCharacterCounter();
})();

screenshot example
Byk5QL3.png
 
Last edited:

Yehuda

Veteran
Supporter
Joined
Dec 24, 2014
Messages
29,225
Reputation
10,431
Daps
119,128
Why is the site down for hours? Find a trick for that shyt
 

bnew

Veteran
Joined
Nov 1, 2015
Messages
48,128
Reputation
7,631
Daps
141,262
new and improved script which took longer than the original to create because of twitter's complex code.

what's new:
text from the main users{OP) tweet is extracted and put inside a spoiler tag.



the code isn't perfect because the text it extracts doesn't have properly formatted urls but i'll try to get that fixed eventually. some of the tweets must be visible when you click the bookmarklet otherwise it might not grab all the tweet links and images if it's a really long twitter thread like 10+ tweets. you might have to run the bookmarklet twice in that instance.

### you can also highlight the code and DRAG & DROP it into your browsers bookmarks toolbar.


code output example:
Code:
https://twitter.com/bindureddy/status/1730248977499762740
[SPOILER="thread continued"]
https://twitter.com/bindureddy/status/1730248977499762740
https://twitter.com/bindureddy/status/1730370773242757463
https://twitter.com/bindureddy/status/1730607977294627299
[/SPOILER]
[SPOILER="full text"]
1/3
A day doesn't go by without a powerful open-source AI model drop.

DeepSeek (67B) makes up for the open-source shortcomings - math and coding!!

It beats Claude-2, scoring 65 on a National High School Exam.

DeepSeek is from China and is proof that the Chinese don't need our LLM tech; they can develop their own and are enlightened enough to open-source it!!

We are taking a look this week and will make it available in the Abacus AI platform next.

2/3
Can you elaborate more?

3/3
Thanks, I will dive into the details of the eval today - on first glance the model seems pretty good and is much faster than Llama-2
[/SPOILER]
[SPOILER="larger images"]
[img]https://pbs.twimg.com/media/GAMUJ5TbEAAE7hp.jpg[/img]
[/SPOILER]



new and improved bookmarklet modified using claude-3-opus-20240229 which is a beast. the previous bookmarklet has issues with url formatting that this one slightly improves upon and doesn't duplicate urls and

A.I generated explanation..

Changelog:
Code:
diff
- var tweets = Array.from(document.querySelectorAll(`a[href^='/${username}/status/']`));
+ var tweets = Array.from(document.querySelectorAll(`a[href^='/${username}/status/']`));

- if (!tweetUrl.includes('/analytics') && !tweetUrl.includes('/photo/') && !userTweets.includes(tweetUrl)) {
+ if (tweetUrl.match(/\/status\/\d+$/) && !userTweets.includes(tweetUrl)) {

- var tweetText = spans.map(span => span.innerText).join('');
+ var tweetText = div.innerText;
- tweetText = tweetText.replace(/https:\/\/<\/span>/g, 'https://');
+ var urls = Array.from(div.querySelectorAll('a[href]')).map(a => a.href);
+ urls.forEach(url => {
+     var truncatedUrl = url.replace(/…$/, '');
+     tweetText = tweetText.replace(url, truncatedUrl);
+ });

- tweetTexts = [firstTweetText].concat(tweetBodies.filter(tweet => userTweets.includes(tweet.url)).map(tweet => tweet.text));
+ tweetTexts = [firstTweetText].concat(tweetBodies.filter(tweet => userTweets.includes(tweet.url) && tweet.url !== userTweets[0]).map(tweet => tweet.text));

- [window.location.href, `[SPOILER="thread continued"]\n${userTweets.join('\n')}\n[/SPOILER]`, `[SPOILER="full text"]` + tweetText + '[/SPOILER]', `[SPOILER="larger images"]\n${imageUrls.join('\n')}\n[/SPOILER]`].join('\n');
+ [window.location.href, `[SPOILER="thread continued"]\n${userTweets.slice(1).join('\n')}\n[/SPOILER]`, `[SPOILER="full text"]` + tweetText + '[/SPOILER]', `[SPOILER="larger images"]\n${imageUrls.join('\n')}\n[/SPOILER]`].join('\n');

Summary:

The changes made in the new bookmarklet aim to improve the handling of URLs and images in tweets. Here are the key modifications:

1. **URL Filtering**: Instead of excluding tweets with specific URL patterns like `/analytics` or `/photo/`, the new version checks if the URL matches the pattern `/status/\d+$`, which represents a regular tweet URL.

2. **Tweet Text Extraction**: The new version extracts the tweet text directly from the `innerText` property of the `div` element, instead of joining the text from individual `span` elements. This simplifies the extraction process.

3. **URL Handling**: The new version identifies all URLs within the tweet text and replaces them with a formatted version surrounded by [U][URL] and [/URL][/U]. It also removes any trailing ellipsis (`...`) from the URLs.

4. **Image URL Extraction**: The image URL extraction logic remains the same as in the previous version.

5. **Tweet Text Filtering**: When constructing the `tweetTexts` array, the new version excludes the first tweet's text (assuming it's already included in `firstTweetText`).

6. **Thread Continued URL**: In the final output, the new version excludes the first tweet URL from the [SPOILER="thread continued" section, as it's already present in the main URL.

These changes aim to provide a more accurate and comprehensive representation of tweet texts, URLs, and images, improving the overall usability and functionality of the bookmarklet.









Example output from a tweet url:
Code:
https://twitter.com/matei_zaharia/status/1772972271721763199
[SPOILER="thread continued"]
https://twitter.com/matei_zaharia/status/1772972274053701799
https://twitter.com/matei_zaharia/status/1772972275899228255
https://twitter.com/matei_zaharia/status/1772974673816346840
[/SPOILER]
[SPOILER="full text"]
1/5
At Databricks, we've built an awesome model training and tuning stack. We now used it to release DBRX, the best open source LLM on standard benchmarks to date, exceeding GPT-3.5 while running 2x faster than Llama-70B. https://databricks.com/blog/introducing-dbrx-new-state-art-open-llm…

2/5
DBRX is a 132B parameter MoE model with 36B active params and fine-grained (4-of-16) sparsity and 32K context. It was trained using the dropless MoE approach pioneered by my student 
@Tgale96
 in MegaBlocks. Technical details: [U][URL]https://databricks.com/blog/introducing-dbrx-new-state-art-open-llm[/URL][/U]

3/5
You can try DBRX on Databricks model serving and playground today, with an OpenAI-compatible API! And if you want to tune, RLHF or train your own model, we have everything we needed to build this from scratch.

4/5
Lots more details on how this was built and why our latest training stack makes it far more efficient than what we could do even a year ago:

5/5
Meet DBRX, a new sota open llm from @databricks. It's a 132B MoE with 36B active params trained from scratch on 12T tokens. It sets a new bar on all the standard benchmarks, and - as an MoE - inference is blazingly fast. Simply put, it's the model your data has been waiting for.
[/SPOILER]
[SPOILER="larger images"]
[img]https://pbs.twimg.com/media/GJrISbEa4AAsTJz.jpg[/img]
[/SPOILER]
 
Last edited:

bnew

Veteran
Joined
Nov 1, 2015
Messages
48,128
Reputation
7,631
Daps
141,262
another small update...





The change is in the `tweetTexts` loop where we process each tweet body. I added an additional line to replace any occurrence of a URL ending with `…` with the same URL without the trailing ellipsis:

Code:
body = body.replace(/https?:\/\/[^ ]+…/g, function(url) {
    return url.replace(/…$/, '');
});

This modification ensures that the URLs in the textarea output will not have the trailing ellipsis, while keeping the rest of the bookmarklet functionality intact.


A.I generated explanation..

Changelog:

1. Removed the newline character after @Username mentions, keeping the username and the following text on the same line.
2. Truncated URLs by removing the trailing ellipsis (...) from the end of the URLs in the tweet text and the textarea output.

Layman's Terms Summary:

The Twitter thread bookmarklet is a handy tool that helps you easily gather information from a Twitter thread and format it in a specific way for sharing or posting elsewhere. Here's what it does:

1. It finds all the tweets in the thread and extracts their text and image URLs.
2. It cleans up the tweet text by removing any extra newline characters after @Username mentions, so the username and the following text stay on the same line.
3. It also fixes any broken URLs in the tweet text by removing the "..." at the end, ensuring the links work properly.
4. It organizes the gathered information into a nicely formatted text, including the thread's URL, a spoiler section with the continuation of the thread, a spoiler section with the full text of the tweets, and a spoiler section with larger image URLs.
5. Finally, it copies this formatted text to your clipboard, ready for you to paste and share wherever you like.
6. As a bonus, it displays a notification box telling you how many links and tweets were copied.

With these recent updates, the bookmarklet now provides a cleaner and more user-friendly output, making it even easier to share Twitter threads with others.



Example output:
Code:
https://twitter.com/matei_zaharia/status/1772972271721763199
[SPOILER="thread continued"]
https://twitter.com/matei_zaharia/status/1772972274053701799
https://twitter.com/matei_zaharia/status/1772972275899228255
https://twitter.com/matei_zaharia/status/1772974673816346840
[/SPOILER]
[SPOILER="full text"]
1/5
At Databricks, we've built an awesome model training and tuning stack. We now used it to release DBRX, the best open source LLM on standard benchmarks to date, exceeding GPT-3.5 while running 2x faster than Llama-70B. https://databricks.com/blog/introducing-dbrx-new-state-art-open-llm

2/5
DBRX is a 132B parameter MoE model with 36B active params and fine-grained (4-of-16) sparsity and 32K context. It was trained using the dropless MoE approach pioneered by my student 
@Tgale96  in MegaBlocks. Technical details: [U][URL]https://databricks.com/blog/introducing-dbrx-new-state-art-open-llm[/URL][/U]

3/5
You can try DBRX on Databricks model serving and playground today, with an OpenAI-compatible API! And if you want to tune, RLHF or train your own model, we have everything we needed to build this from scratch.

4/5
Lots more details on how this was built and why our latest training stack makes it far more efficient than what we could do even a year ago:

5/5
Meet DBRX, a new sota open llm from @databricks. It's a 132B MoE with 36B active params trained from scratch on 12T tokens. It sets a new bar on all the standard benchmarks, and - as an MoE - inference is blazingly fast. Simply put, it's the model your data has been waiting for.
[/SPOILER]
[SPOILER="larger images"]
[img]https://pbs.twimg.com/media/GJrISbEa4AAsTJz.jpg[/img]
[/SPOILER]
 
Last edited:

bnew

Veteran
Joined
Nov 1, 2015
Messages
48,128
Reputation
7,631
Daps
141,262
I updated it again, the old bookmarklet no longer works as expected since twitter changed something on their end which prevented the bookmarklet from extracting more than one tweet urls and text.

calling this version 3.3
used Claude 3 opus and haiku to generate the code.


protip: zoom out on the tweet page to capture more than 3 tweet replies.

Changelog from version 3.1 to version 3.3:

1. **Improved Logging and Debugging**:

- The bookmarklet now includes more detailed logging and debugging output, providing information about the number of tweets found, the identified username, the number of tweet texts and image URLs collected, and other relevant details.
- This can be helpful for troubleshooting and understanding the execution of the script.

2. **Handling of Missing Tweet Text**:
- In version 3.1, if the tweet text was not found, the script would skip that tweet.
- In version 3.2, the script now logs a message when the tweet text is not available, and it still includes the tweet in the final output, but with a placeholder text.
- In version 3.3, the script reverts to the behavior of version 3.1, skipping tweets where the text is not found.

3. **URL Formatting in Tweet Text**:
- In version 3.1, the URLs within the tweet text were truncated and wrapped in BBCode tags (`...`).
- In version 3.2, the URLs were left as the original full URLs, without any special formatting.
- In version 3.3, the URLs are again formatted with the BBCode tags, and the trailing ellipsis (`...`) is removed to ensure the URLs are properly enclosed.

4. **Handling of Ellipsis Character**:
- In version 3.2 and earlier, the code used a regular expression to match the trailing ellipsis, which did not work correctly as the ellipsis is a single Unicode character.
- In version 3.3, the code was updated to use a literal match for the Unicode ellipsis character, effectively removing it from the end of the URLs.

Layman's Terms Explanation:

The main differences between version 3.1, 3.2, and 3.3 of the bookmarklet are:

1. **Debugging Information**:
The newer versions 3.2 and 3.3 provide more detailed information about what the bookmarklet is doing, such as how many tweets it found and how many it was able to collect. This can be helpful if you ever run into any issues or problems with the bookmarklet.

2. **Handling Missing Information**: In the older version 3.1, if the bookmarklet couldn't find the text of a tweet, it would just skip that tweet. The newer version 3.2 would still include the tweet, but let you know the text couldn't be found. The latest version 3.3 has gone back to the original behavior of skipping tweets with missing text.

3. **URL Formatting**: The older version 3.1 would shorten the URLs in the tweet text and wrap them in special formatting. The newer version 3.2 left the URLs as-is, without any formatting. The latest version 3.3 has gone back to formatting the URLs, but it also fixes an issue with the way it was handling the ellipsis (the three dots) at the end of the URLs.

4. **Ellipsis Handling**: The previous versions of the bookmarklet had trouble dealing with the ellipsis character at the end of the URLs. Version 3.3 has been updated to properly remove the ellipsis, ensuring the URLs are correctly formatted.

Overall, the latest version 3.3 has a mix of features from the previous versions, with some additional improvements to make the bookmarklet more robust and reliable.
 
Last edited:

bnew

Veteran
Joined
Nov 1, 2015
Messages
48,128
Reputation
7,631
Daps
141,262
Bookmarklet to Extract twitter tweets and thread urls including text into neat spoilers

Twitter is officially moving to x.com so I updated the code so that 'x.com' in the output is replaced with 'twitter.com' and the embed continues to work seamlessly. it's now version 3.5



Changelog from the original code (v3.3) to the final code (v3.5):

1. **Replace "x.com" with "twitter.com" in the output**:
- In the `tweetText` variable assignment, the `replace()` function now replaces `x.com` with `twitter.com` in the URL.
- In the `textArea.value` assignment, the `window.location.href`, `userTweets.slice(1).join('\n')`, and `tweetText` variables are now replaced with their respective `.replace(/x\.com/, 'twitter.com')` versions.

2. **Simplified the solution**:
- The previous solution was overcomplicated, so the final version simplifies the code by only replacing "x.com" with "twitter.com" in the final output, without modifying the URLs or tweet URLs during the collection process.

The final code now consistently replaces "x.com" with "twitter.com" in the output, making the solution more straightforward and easier to understand.
 
Last edited:
Top