Home Archives Search About

(Java)Scripting Google Drive

May 10, 2019

a beautiful, intensely complicated way not to write a bash script”
David

I do a podcast with a friend. For simplicity, everything is stored in a Team Drive within Google Drive. For episodes, the folder structure looks like:

Episodes
├── Ep. <x> - <title>
│   ├── EP<x> Notes.gdoc
│   └── Raw
│       ├── ep<x>-person1-raw.mp3
│       └── ep<x>-person2-raw.mp3

Where <x> is the episode #, which starts at 0 and increments by 1 for each episode. Instead of manually creating folders & copying files around, I wanted a way to scaffold out each new episode—the episode folder, episode notes template, and Raw folder.

Given the succinct naming conventions this is pretty easily automate-able. Since Google Drive can mount to your local filesystem, I could’ve made this a shell script using mkdir and cp in a few lines. However, I wanted a way to abstract it out via Google Apps Script which would allow me to run it from any computer & not have any dependencies with it mounted to my filesystem.

After a few hours of hacking away, here’s what I came up with:

var FOLDER_ID = "xxx"
var TEMPLATE_ID = "yyy"

function doGet () {
  return main()
}

function main () {
  
  Logger.log("Getting next episode number...")
  
  var root    = DriveApp.getFolderById(FOLDER_ID),
      episode = getNextEpisodeNumber(root.getFolders())
  
  Logger.log(episode)
  Logger.log("Creating folder...")
  
  var folder = root.createFolder("Ep. " + episode + " - TBD")
  
  Logger.log("Copying template and creating 'Raw' folder...")
  DriveApp.getFileById(TEMPLATE_ID).makeCopy("EP" + episode + " Notes", folder)
  folder.createFolder("Raw")
  
  return HtmlService.createHtmlOutput("Created new episode: #" + episode)
}

function getNextEpisodeNumber (folders) {
  
  var max = 0
  
  while (folders.hasNext()) {
    var folder = folders.next(),
        match  = /^Ep\. ?(\d+)/i.exec(folder.getName())
    
    if (match !== null)
      max = Math.max(max, parseInt(match[1], 10))
  }
  
  // Return a string w/ decimal truncated
  return (max + 1).toFixed(0)
}

The logic is pretty simple:

  1. Iterate over all folders within Episodes/
  2. Parse the episode # from the folder name
  3. Find the largest one to get the next episode #
  4. Create the new folders & copy over the file

The FOLDER_ID and TEMPLATE_ID are grabbed from the URLs for each: https://drive.google.com/drive/u/<index>/folders/<id> and https://docs.google.com/document/d/<id>/edit, respectively.

There were a few weird gotchas:

After publishing the script as a web app”, I got a unique URL that I can hit with a GET request—that’s what the doGet function is for. After bookmarking the page, I can scaffold out a new episode with the click of my mouse.

Sure, it’s an entirely convoluted solution to a problem that could be solved in a much simpler fashion. However, it’s nice to have a chance to take a peek at some other APIs & have a very portable tool.

Posted on May 10, 2019   #js     #dev     #hack  


← Newer post  •  Older post →