google takeout | | order google takeout | Search

This code snippet automates the creation and download of a Google Takeout archive for a specified product, handling navigation, login, size selection, archive creation, and download completion.

Run example

npm run import -- "download google takeout"

download google takeout

var importer = require('../Core');

function listTakeouts() {
    return client
        .url('https://takeout.google.com/settings/takeout')
        .loginGoogle()
        .pause(1000)
        .url('https://takeout.google.com/settings/takeout')
        .getAllXPath([
            '//*[@data-id]',
            {
                id: './@data-id',
                label: './/td[3]//text()'
            }
        ])
};

function takeoutProducts(product) {
    return client
        .url('https://takeout.google.com/settings/takeout/custom/' + product.id)
        .pause(500)
        .click('//*[contains(@role, "button")][contains(., "Next")]')
        .pause(500)
        .click('//*[contains(., "Archive size")]/parent::*/*[contains(@role, "listbox")]') // [contains(@aria-selected, "true")]
        .pause(500)
        // TODO: shorten this in to a utility command
        // doesn't work because of some weird css BS
        // .click('//*[contains(@role, "option")][contains(., "50")]')
        .click(
            '//*[contains(., "Archive size")]/parent::*//*[contains(@role,"option")][contains(.,"50")]')
        .pause(500)
        .click('//*[contains(@role, "button")][contains(., "Create archive")]')
        .waitUntil(
            () => client.isExisting('//tr[1]//*[contains(@href, "takeout/download")]'),
            120000,
            '')
        .isVisible('iframe[src*="settings"]')
        .then(is => is ? client.execute(() => {
            document.querySelector('iframe[src*="settings"]').remove();
        }) : [])
        .click('//tr[1]/td[last()]//*[contains(@href, "takeout/download")]')
        .pause(1000)
        .isVisible('#passwordNext')
        .then(is => is ? client
            .loginGoogle()
            .then(is => is ? client.execute(() => {
                const question = document.querySelector('iframe[src*="settings"]');
                if(question) {
                    question.remove();
                }
            }) : [])
             : [])
        // wait for download
        .pause(10000)
        .catch(e => console.log(e))
}

function downloadGoogleTakeout(products) {
    var regex = new RegExp(products, 'ig');
    return listTakeouts()
        .then(ids => {
            return ids
                .map(k => ({
                    id: k.id + '',
                    label: k.label + ''
                }))
                .filter(k => k.id != '_gd' && (products.indexOf('all') > -1
                    || k.id.match(regex) != null || k.label.match(regex) != null))
        })
        .then(selectedProducts => {
            console.log(selectedProducts);
            return importer.runAllPromises(selectedProducts
                .map(p => (resolve) => {
                    return takeoutProducts(p)
                        .then(r => resolve(r))
                        .catch(e => resolve(e))
                }))
        })
        .catch(e => console.log(e))
};
if (typeof client.downloadGoogleTakeout == 'undefined') {
    client.addCommand('downloadGoogleTakeout', downloadGoogleTakeout);
}
module.exports = downloadGoogleTakeout;

What the code could have been:

const { CommandBuilder } = require('../Core');

class GoogleTakeout {
  /**
   * Lists all available takeout products.
   * @returns {Array} A list of objects containing the product ID and label.
   */
  static listTakeouts() {
    return this.client
     .url('https://takeout.google.com/settings/takeout')
     .loginGoogle()
     .pause(1000)
     .url('https://takeout.google.com/settings/takeout')
     .getAllXPath([
        '//*[@data-id]',
        {
          id: './@data-id',
          label: './/td[3]//text()'
        }
      ]);
  }

  /**
   * Downloads a Google Takeout product.
   * @param {Object} product - The product to download.
   * @param {string} product.id - The ID of the product.
   * @returns {Promise} A promise resolving to the download result.
   */
  static takeoutProducts(product) {
    return this.client
     .url(`https://takeout.google.com/settings/takeout/custom/${product.id}`)
     .pause(500)
     .click('//*[contains(@role, "button")][contains(., "Next")]')
     .pause(500)
     .selectListbox('//*[contains(., "Archive size")]/parent::*/*[contains(@role, "listbox")]', '50')
     .pause(500)
     .click('//*[contains(@role, "button")][contains(., "Create archive")]')
     .waitUntil(
        () => this.client.isExisting('//tr[1]//*[contains(@href, "takeout/download")]'),
        120000,
        ''
      )
     .then(is => is? this.client.execute(() => {
        document.querySelector('iframe[src*="settings"]').remove();
      }) : [])
     .click('//tr[1]/td[last()]//*[contains(@href, "takeout/download")]')
     .pause(1000)
     .isVisible('#passwordNext')
     .then(is => is? this.client
       .loginGoogle()
       .then(is => is? this.client.execute(() => {
          const question = document.querySelector('iframe[src*="settings"]');
          if (question) {
            question.remove();
          }
        }) : [])
        : [])
      // wait for download
     .pause(10000)
     .catch(e => console.log(e));
  }

  /**
   * Downloads the specified Google Takeout products.
   * @param {string} products - The products to download (e.g. "email" or "all").
   * @returns {Promise} A promise resolving to the download results.
   */
  static downloadGoogleTakeout(products) {
    const regex = new RegExp(products, 'ig');
    return this.listTakeouts()
     .then(ids => {
        return ids
         .map(k => ({
            id: k.id + '',
            label: k.label + ''
          }))
         .filter(k => k.id!== '_gd' && (products.includes('all') ||
            k.id.match(regex)!== null || k.label.match(regex)!== null));
      })
     .then(selectedProducts => {
        console.log(selectedProducts);
        return this.client.runAllPromises(selectedProducts
         .map(p => (resolve) => {
            return this.takeoutProducts(p).then(r => resolve(r)).catch(e => resolve(e));
          }));
      })
     .catch(e => console.log(e));
  }
}

class CommandBuilder {
  constructor() {
    this.commands = {};
  }

  addCommand(name, method) {
    this.commands[name] = method;
  }

  getCommand(name) {
    return this.commands[name];
  }
}

const builder = new CommandBuilder();
if (typeof builder.getCommand('downloadGoogleTakeout') === 'undefined') {
  builder.addCommand('downloadGoogleTakeout', GoogleTakeout.downloadGoogleTakeout);
}
module.exports = builder;

This code snippet automates the process of creating and downloading a Google Takeout archive for a specific product.

Here's a breakdown:

1. listTakeouts Function:

2. takeoutProducts Function:

Overall:

This code snippet automates the process of creating and downloading a Google Takeout archive for a specific product. It handles navigation, login, selection of archive size, creation of the archive, and download.