Skip to content

Instantly share code, notes, and snippets.

@spf13
Forked from danmactough/script.js
Last active April 2, 2025 08:03
Show Gist options
  • Save spf13/1fee1eb88d65aca34272c99e4d68689d to your computer and use it in GitHub Desktop.
Save spf13/1fee1eb88d65aca34272c99e4d68689d to your computer and use it in GitHub Desktop.

Revisions

  1. spf13 revised this gist Feb 18, 2025. 1 changed file with 49 additions and 32 deletions.
    81 changes: 49 additions & 32 deletions script.js
    Original file line number Diff line number Diff line change
    @@ -3,42 +3,59 @@
    // 3. Open your browser's Javascript console
    // 4. For each page of books, paste this script into the console

    function closeNotification() {
    document.querySelector('span#notification-close').click();
    }
    (async function () {
    // Close the notification if it appears
    function closeNotification() {
    const notifClose = document.querySelector("span#notification-close");
    if (notifClose) {
    notifClose.click();
    }
    }

    function pause(duration = 1000) {
    return new Promise((resolve) => {
    setTimeout(resolve, duration);
    });
    }
    // Pause for a given duration (in milliseconds)
    function pause(duration = 1000) {
    return new Promise(resolve => setTimeout(resolve, duration));
    }

    menus = Array.from(
    document.querySelectorAll('div[id*="DOWNLOAD_AND_TRANSFER_ACTION_"]')
    ).filter((el) => !el.id.endsWith('CONFIRM') && !el.id.endsWith('CANCEL'));
    // Select all buttons that open the "Download & transfer via USB" dialog.
    // Note: This uses the DOWNLOAD_AND_TRANSFER prefix.
    const menus = Array.from(
    document.querySelectorAll('div[id*="DOWNLOAD_AND_TRANSFER_ACTION_"]')
    ).filter(el => !el.id.endsWith("CONFIRM") && !el.id.endsWith("CANCEL"));

    inputs = Array.from(
    document.querySelectorAll(
    // If you have multiple Kindles, I think you're going to need to tweak this selector or add a filter like the menus selector
    // to restrict your result to just the one Kindle that you are targeting
    "ul[id^='download_and_transfer_list_'] > li[class^='ActionList-module_action_list_item__'] > div > label"
    )
    );
    for (let menu of menus) {
    // Extract the ASIN from the menu's id.
    // E.g. "DOWNLOAD_AND_TRANSFER_ACTION_B07HYK662L" -> "B07HYK662L"
    const parts = menu.id.split("_");
    const asin = parts[parts.length - 1];
    console.log(`Processing book with ASIN: ${asin}`);

    // Click the menu to open the dialog
    menu.click();
    await pause(500);

    buttons = Array.from(
    document.querySelectorAll(
    "div[id^='DOWNLOAD_AND_TRANSFER_DIALOG_'] div[class^='DeviceDialogBox-module_button_container__'] > div[id$='_CONFIRM']"
    )
    );
    // Within the dialog, select the first radio button (device) to download.
    // This selector targets the list for this ASIN.
    const inputSelector = `ul#download_and_transfer_list_${asin} li[class^='ActionList-module_action_list_item__'] > div > label`;
    const input = document.querySelector(inputSelector);
    if (!input) {
    console.warn(`No download option found for ASIN ${asin}`);
    continue;
    }
    input.click();
    await pause(500);

    (async function () {
    for (let i = 0; i < 25; i++) {
    if (menus[i]) {
    menus[i].click();
    inputs[i].click();
    buttons[i].click();
    await pause();
    closeNotification();
    // Find the confirm button within the dialog for this ASIN.
    const buttonSelector = `div[id^='DOWNLOAD_AND_TRANSFER_DIALOG_${asin}'] div[class^='DeviceDialogBox-module_button_container__'] > div[id$='_CONFIRM']`;
    const button = document.querySelector(buttonSelector);
    if (!button) {
    console.warn(`No confirm button found for ASIN ${asin}`);
    continue;
    }
    button.click();
    await pause(1000);

    closeNotification();
    await pause(500);
    }
    })();
    })();
  2. @danmactough danmactough revised this gist Feb 17, 2025. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions script.js
    Original file line number Diff line number Diff line change
    @@ -19,6 +19,8 @@ menus = Array.from(

    inputs = Array.from(
    document.querySelectorAll(
    // If you have multiple Kindles, I think you're going to need to tweak this selector or add a filter like the menus selector
    // to restrict your result to just the one Kindle that you are targeting
    "ul[id^='download_and_transfer_list_'] > li[class^='ActionList-module_action_list_item__'] > div > label"
    )
    );
  3. @danmactough danmactough created this gist Feb 17, 2025.
    42 changes: 42 additions & 0 deletions script.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,42 @@
    // 1. Log in to your Amazon account
    // 2. Go to your Content Library > Books - https://www.amazon.com/hz/mycd/digital-console/contentlist/booksAll/dateDsc/
    // 3. Open your browser's Javascript console
    // 4. For each page of books, paste this script into the console

    function closeNotification() {
    document.querySelector('span#notification-close').click();
    }

    function pause(duration = 1000) {
    return new Promise((resolve) => {
    setTimeout(resolve, duration);
    });
    }

    menus = Array.from(
    document.querySelectorAll('div[id*="DOWNLOAD_AND_TRANSFER_ACTION_"]')
    ).filter((el) => !el.id.endsWith('CONFIRM') && !el.id.endsWith('CANCEL'));

    inputs = Array.from(
    document.querySelectorAll(
    "ul[id^='download_and_transfer_list_'] > li[class^='ActionList-module_action_list_item__'] > div > label"
    )
    );

    buttons = Array.from(
    document.querySelectorAll(
    "div[id^='DOWNLOAD_AND_TRANSFER_DIALOG_'] div[class^='DeviceDialogBox-module_button_container__'] > div[id$='_CONFIRM']"
    )
    );

    (async function () {
    for (let i = 0; i < 25; i++) {
    if (menus[i]) {
    menus[i].click();
    inputs[i].click();
    buttons[i].click();
    await pause();
    closeNotification();
    }
    }
    })();