Skip to content

Instantly share code, notes, and snippets.

@rnjailamba
Last active February 26, 2024 07:36
Show Gist options
  • Save rnjailamba/f908cab7bc72b4476789455191764726 to your computer and use it in GitHub Desktop.
Save rnjailamba/f908cab7bc72b4476789455191764726 to your computer and use it in GitHub Desktop.
Export Slack Bookmarks (Now called Later, Previously called Saved Items)

General instructions

  1. Internet should be constantly atleast 1 mbps
  2. Use chrome and keep the slack bookmarks tab in focus (IMPORTANT or you'll else there can be loss of information) on your current chrome window. Leave the script running on your computer with this tab visible along with another chrome window if you want to work while this runs.
  3. It will take 10 seconds * number of bookmarks (duration) ex. for 100 bookmarks it will take ~15 minutes (if you're confident about very fast internet check the FAQ)
  4. Computer should not sleep while the script runs

Running the script

  1. Launch slack (https://app.slack.com/client/) in chrome, login, select the workspace you want to get the bookmarks from. Select "Later" (new name for bookmarks/ saved items) from the left side menu.
  2. You will automatically be on the "In Progress" tab within the "Later" page. The script is test for "In Progress", you may need to change it for "Archived"/ "Completed"
  3. Open the developer console on chrome via cmd + option + j (in mac)
  4. Paste the script, press enter and let it run for the duration calculated above
  5. Approximately after the duration go and copy a huge message towards the end, you may need to scroll up. You can also search for "Bookmarked Text" in the console and copy the huge message that shows up. If you come much after the duration, log will be lost. The size could be for example 120 kb for 100 bookmarks.
  6. Put this test in a test.csv file and then import it with google sheets.

About the script

  • It's a quick hack and it may not work reliably. Its been tested and worked well on 30 January, 2024 for 100 bookmarks.
  • Use case is to get bookmarks that are in a workspace for which you aren't an admin and can't get the token to export data via api.
  • The script only gives text as output. No images or files.

You want make it production ready

  1. Change all setTimeout's to promises or async/ await
  2. Handle network latency/ timeouts
  3. Convert to Clean Code
  4. Try to not hardcode all the class names in the first line
  5. Probably don't do this via the browser
  6. Find a way to export images/ files

FAQ

  • The slack webpage dissapeared or became small when I ran the script
    • The zoom is set to 5% (0.05) so that all bookmarks are downloaded.
    • document.body.style.zoom = parseFloat(0.05)
  • I got repeating bookmarked/ thread text
    • Run the script again or set the setTimeout times to 2x of what they are just now
  • I want to run a quick test to see if this works
    • Set the zoom to 100% (1) to run a quick test on less than 20 bookmarks. Will take around 10 minutes.
    • document.body.style.zoom = parseFloat(1)
  • My internet is slow and it takes time for bookmarks/ threads to load
    • Make below changes, increase further as needed
    • before_start = 20000;
    • before_loop = 20000;
    • It will take 40 seconds * number of bookmarks (duration). ex. for 100 bookmarks it will take ~70 minutes
  • My internet is very fast and reliable (10 mpbs)
    • before_start = 5000;
    • before_loop = 2000;
    • It will take 3 seconds * number of bookmarks (duration). ex. for 100 bookmarks it will take ~5 minutes
var before_start, after_finished, before_loop, after_element_clicked;
before_start = 10000;
after_finished = before_start;
before_loop = 5000;
after_element_clicked = before_loop - 1000;
var elementsToResize = ['body', 'html', '.p-client_container', '.p-ia4_client_container', '.p-ia4_client', '.p-theme_background', '.p-client_workspace_wrapper', '.p-client_workspace', '.p-client_workspace__layout', '.p-view_contents'];
for (var j = 0; j < elementsToResize.length; j++) {
var elementToResize = elementsToResize[j];
document.querySelector(elementToResize).style.setProperty('max-height', '100%', 'important');
document.querySelector(elementToResize).style.setProperty('height', '100%', 'important');
document.querySelector(elementToResize).style.setProperty('max-width', '100%', 'important');
document.querySelector(elementToResize).style.setProperty('width', '100%', 'important');
}
//var z = prompt('Set zoom level!');
document.body.style.zoom = parseFloat(0.05) // Set to 0.1 to get 100, Set to 0.001 to get 1000 and so on
var allBookmarks = [["Bookmarked Text", "Thread Text"]];
setTimeout(function() {
var targetClass = 'p-saved_item'; // Replace with actual class name
var targetParam = 'dir'; // Replace with actual parameter name
var targetParamValue = 'auto'; // Replace with actual parameter value
var divs = document.querySelectorAll(`.${targetClass}`);
var divsToBeClicked = document.querySelectorAll('div.c-message_kit__message');
console.log('Number of bookmarks: ', divs.length);
var index = 0;
function loopThroughBookmarks() {
setTimeout(function() { // call a setTimeout when the loop is called
var bookmark = [];
var node = divs[index];
var divVariable = node;
var messageSenderName = divVariable.querySelectorAll('span[data-qa="message_sender_name"]')[0].innerText
var targetSpan = divVariable.querySelectorAll('span[dir="auto"]');
if (targetSpan.length == 0) {
targetSpan = divVariable.querySelectorAll('span.c-truncate');
targetSpan = targetSpan[1];
}
else {
targetSpan = targetSpan[0];
}
//console.log(index);
//console.log(divVariable);
var bookmarkedMessage = messageSenderName + ": " + targetSpan.innerText;
bookmark.push(bookmarkedMessage);
console.table("BOOKMARKED MESSAGE(INFO) -> " + bookmarkedMessage); // Pretty print using console.table
//click above bookmark to view the thread
divsToBeClicked[index].click();
setTimeout(() => {
console.log('Element clicked and rendered:');
var isChannel = document.querySelectorAll('div.p-view_header').length ? true : false;
var thread = document.querySelectorAll('div.p-block_kit_renderer');
var threadSenders = document.querySelectorAll('button.c-message__sender_button');
for (var i = 0; i < thread.length; i++) {
node = thread[i];
var text = node.innerText;
if(isChannel) {
//console.log(text.includes((targetSpan.innerText).substring(0, targetSpan.innerText.length-1)));
if(text.includes((targetSpan.innerText).substring(0, targetSpan.innerText.length-1))){
//console.log(i);
bookmark.push(text);
console.log("THREAD MESSAGE(INFO) -> " + text);
break;
}
}
else {
//console.log(i);
var threadMessage = threadSenders[i].innerText + ": " + text;
bookmark.push(threadMessage);
console.log("THREAD MESSAGE(INFO) -> " + threadMessage);
}
}
}, after_element_clicked);
index++;
allBookmarks.push(bookmark)
if (index < divs.length) {
loopThroughBookmarks();
}
else {
setTimeout(() => {
function arrayToCsv(data){
return data.map(row =>
row
.map(String) // convert every value to String
.map(v => v.replaceAll('"', '""')) // escape double quotes
.map(v => `"${v}"`) // quote it
.join(',') // comma-separated
).join('\r\n'); // rows starting on new lines
}
console.log(arrayToCsv(allBookmarks));
}, after_finished);
}
}, before_loop)
}
loopThroughBookmarks();
}, before_start); // Adjust delay as needed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment