0

I am trying to use chrome.download methods to download a CSV file type and change the name of the file upon download.

Currently, I am using

document.querySelectorAll("[file$='foo']").forEach(a=>a.click());

to simulate a click on each element to download. However, each filename upon download is foo.csv, foo(1).csv etc. Utimately I would like to download the file, and change the filename. Currently I am doing this through a content script, and from what I have read I cannot access the chrome.download API and will have to use messaging from my background.js.

Other posts similar to this one, from my understanding, involve creating a new element/content for download versus downloading content already on the site.

Example Example 2

Any help is greatly appreciated! Thank you!!

My background.js

function changeName(prevName){
    chrome.downloads.onDeterminingFilename.addListener((prevName, suggest) => {
        suggest({
            filename: 'new-name.csv'
          });
        });
    };

chrome.runtime.onMessage.addListener(function(msg, sender) {
    if ((msg.action === 'renameSave')
            && (msg.params !== undefined)) {
        changeName(msg.params);
    };
});

and my contentscript.js

 button.addEventListener('click', function() {
    var elems = document.getElementsByClassName("Stmt");
    var count = 1;


    var interval = setInterval(function(){
      elems[count].click();

      chrome.runtime.sendMessage({
        action: 'renameSave',
        params: ["statement.csv"]
      });

      count = count + 2;
      if(count > elems.length){
            clearInterval(interval);
        }

  },800);
}, false);
Tnellis
  • 1
  • 2
  • The link element should have a `download` attribute where the file name is specified. That's the only thing you might be missing, AFAIK. – wOxxOm Jul 18 '18 at 08:11

2 Answers2

0

It is not a problem. There is chrome.downloads event onDeterminingFilename, which helps to "suggest" a filename for the downloading item. This API is available for background pages:

  1. Create a file named "background.js"
  2. Put the reference to it in the manifest.
"background": {
    "scripts": ["background.js"],
}
  1. Add "downloads" permission to the manifest section
  2. This code is doing what you want:
chrome.downloads.onDeterminingFilename.addListener((item, suggest) => {
    // "item.filename" - the current filename
    suggest({
        filename: 'new-name.csv'
    });
});
Denis L
  • 3,209
  • 1
  • 25
  • 37
  • I used your suggestion with messaging passing, how does this look? – Tnellis Jul 18 '18 at 16:20
  • @Tnellis `onDeterminingFilename` is an event listener, once you run it - it listening for every new download action. You don't need to set it on each message from the content script. – Denis L Jul 18 '18 at 16:27
  • Each download name will be unique, and through message passing is how I plan to accomplish this. Is this correct logic, or am I over complicating it? – Tnellis Jul 18 '18 at 16:46
  • That's ok, but if you are setting a listener for each message, don't forget to remove it via `chrome.downloads.onDeterminingFilename.removeListener` – Denis L Jul 19 '18 at 08:18
0

You can put a variable inside listener function instead of a const string (filename: fileNameVar):

function changeName(prevName){
chrome.downloads.onDeterminingFilename.addListener((prevName, suggest) => {
    suggest({
        filename: fileNameVar
      });
    });
};

chrome.runtime.onMessage.addListener(function(msg, sender) {
    if ((msg.action === 'renameSave')
            && (msg.params !== undefined)) {
        changeName(msg.params);
    };
});

That way, you can change the fileName every time, using a global variable or chrome.storage API.