Get all the Channels + Tags + Statuses in a Marketo instance

As long as I’m publishing crazy stuff like Get all the Roles + Permissions defined in a Marketo instance, might as well do it again for Admin » Tags, right?

Like in the other post, go to Tags, open up your browser’s F12 Console and paste in the code below. By default, it only gets the Channels and one Tag as a sample. Once you’ve checked out the downloaded JSON, set getJustOne = false and run it again to get ’em all.

And also as before, this is only tested in late-model Firefox and Chrome, since it’s not something for public consumption, and there are nasty nested Promises that could use refactoring if I had the time:

var getJustOne = true;

var exportedProps = [
   "genericTags",
   "appliesTo",
   "channelTags",
   "name",
   "type",
   "typeName",
   "value",
   "values",
   "description",
   "typeId",
   "progression",
   "steps",
   "order",
   "success",
   "hidden",
   "deleted",
   "system",
   "isEventCapSet",
   "isUsed"
];

var genericTags;

fetch("/marketingEvent/getAllDescriptors", 
  Object.assign( 
    commonFetchOptions, 
    { body: "start=0&hideSky=true&xsrfId=" + MktSecurity.getXsrfId() } 
  ) )
  .then( resp => resp.json() )
  .then( respJ => {
     genericTags = respJ.data.descriptors.filter( descriptor => descriptor.type == null );
     genericTags.forEach( descriptor => { descriptor.appliesTo = JSON.parse( descriptor.appliesToJson ) });

     return respJ.data.descriptors.find( descriptor => descriptor.type == "channel" );
  })
  .then( channelTags => 
     Promise.all(
        channelTags.values
          .slice(getJustOne)
          .map( value =>
            fetch("/marketingEvent/getDescriptorValue",
              Object.assign(
                commonFetchOptions,
                { body: "ajaxHandler=mktSession&_json=" + encodeURIComponent(JSON.stringify({descriptorValueId:value.id})) + "&xsrfId=" + MktSecurity.getXsrfId() }
            ) )
          )
     )
  )
  .then( allChannelResps =>
     Promise.all( allChannelResps.map( resp => resp.json() ) )
  )
  .then( allChannelRespJ => 
     allChannelRespJ.map( respJ => respJ.JSONResults.descriptorValue )
  )
  .then( trimmedChannelRespJ => {
     const downloadable = JSON.stringify({ genericTags : genericTags, channelTags : trimmedChannelRespJ }, exportedProps, 2);
     const downloader = document.createElement("a");
     downloader.href = window.URL.createObjectURL( 
       new Blob( [downloadable],{ type:"application/json" } ) 
     );
     downloader.download = "tags.json";
     document.body.appendChild(downloader);
     downloader.click();
  });

Downloaded JSON file looks like: