Skip to content

Instantly share code, notes, and snippets.

@clupasq
Last active April 23, 2024 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clupasq/290953d76e73dc41db98f2bb7e8d8095 to your computer and use it in GitHub Desktop.
Save clupasq/290953d76e73dc41db98f2bb7e8d8095 to your computer and use it in GitHub Desktop.
This is a small JS script that automatically downloads all the images in a WhatsApp conversation
// Script to download images from WhatsApp
//
// Steps to use:
// 1. Open up the conversation you want to download pics from
// 2. Open the leftmost image you want to download (the script
// will download and advance to the next image until the last
// image is reached.
// 3. Open the developer console and paste the script in it
// 4. Click OK on the "Download multiple files" browser prompt
// (if it appears)
//
// Tested in Chrome 124
(function () {
var dlTimeout = 1500;
var nextTimeout = 100;
var maxDownloads = 1306;
var downloadCount = 1;
var downloadMenu = document.querySelector('div[aria-label="Menu"]');
var download = function () {
if (downloadMenu) {
downloadMenu.click();
}
setTimeout(() => {
try {
var downloadBtn = document.querySelector('div[aria-label="Download"]');
var nextBtn = document.querySelector('div[aria-label="Next"]');
// console.log(downloadBtn, nextBtn);
if (downloadBtn) {
downloadBtn.click();
setTimeout(() => {
nextBtn.click();
console.log("downloadCount: = " + downloadCount);
downloadCount += 1;
if (downloadCount <= maxDownloads) {
download();
}
}, nextTimeout);
} else {
// if download button not available, continue with previous photo...
nextBtn.click();
download();
}
} catch (ex) {
console.error(ex);
var nextBtn = document.querySelector('div[aria-label="Next"]');
nextBtn.click();
}
}, dlTimeout);
};
download();
})();
@badkill23
Copy link

How can I add this code to make it more automatic, that is, to add a button in the conversion that says the "download all" button?

@clupasq
Copy link
Author

clupasq commented Jun 9, 2023

@badkill23 The easiest way I see is to add a browser bookmark with the URL value set to javascript:<paste here the code in the gist>.

When you press that bookmark, it will execute this code.
Note that you'll have to exclude the comments when you paste the code.

@KevinvBre
Copy link

KevinvBre commented Sep 19, 2023

Thanks for this concept. Was trying different methods but this is as easy as it gets. Made some changes to get it working:

  • The querySelectors you are using are no longer used by WhatsApp
  • The download button is now hidden behind a click and only then rendered in the DOM.
  • Added a max amount limiter to avoid infite loops of downloads (that happend)
  • Added a delay and changed another one to allow for DOM rendering and slower connections.
  • Didnt add any comments because then javascript: doenst work anymore.

Here's mine:

(function() {
var maxDownloads = 3;
var downloadCount = 1;
var nextBtn = document.querySelector('div[aria-label="Next"]');
var downloadmenu = document.querySelector('div[aria-label="Menu"]');

var download = function() {


    downloadmenu.click();

    setTimeout(() => {
      
        var downloadBtn = document.querySelector('div[aria-label="Download"]'); 
        downloadBtn.click();

        setTimeout(() => {
            nextBtn.click();


            console.log("downloadCount: = " + downloadCount);
            downloadCount += 1;
            if(downloadCount <= maxDownloads)download(); 
        }, "50");   

    }, "200");   
};

download();

}());

Edits: code section is kinda broken so also copy the last bit.

@clupasq
Copy link
Author

clupasq commented Sep 23, 2023

@KevinvBre Cool, thanks for sharing!
Yes, I expected my script to become obsolete, as it was created some years ago.

@z3nth10n
Copy link

z3nth10n commented Apr 18, 2024

This is my improved version of your scripts:

(function () {
  var dlTimeout = 1500;
  var nextTimeout = 100;
  var maxDownloads = 1306;
  var downloadCount = 1;
  var downloadMenu = document.querySelector('div[aria-label="Menú"]');

  var download = function () {
    if (downloadMenu) {
      downloadMenu.click();
    }

    setTimeout(() => {
      try {
        var downloadBtn = document.querySelector('div[aria-label="Descargar"]');
        var prevBtn = document.querySelector('div[aria-label="Anterior"]');

        // console.log(downloadBtn, prevBtn);

        if (downloadBtn) {
          downloadBtn.click();

          setTimeout(() => {
            prevBtn.click();

            console.log("downloadCount: = " + downloadCount);
            downloadCount += 1;
            if (downloadCount <= maxDownloads) {
              download();
            }
          }, nextTimeout);
        } else {
          // if download button not available, continue with previous photo...
          prevBtn.click();
          download();
        }
      } catch (ex) {
        console.error(ex);

        var prevBtn = document.querySelector('div[aria-label="Anterior"]');
        prevBtn.click();
      }
    }, dlTimeout);
  };

  download();
})();

The idea is that videos for example are skipped. But be careful with the timeouts if they are too quickly then "Download" button is not available.

Also, query selectors with aria-labels are language sensitive.

@clupasq
Copy link
Author

clupasq commented Apr 23, 2024

@z3nth10n Thanks! I've updated the gist based on your proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment