Add Custom Queryable Properties to Any File in Google Drive with Apps Script

I recently needed a way to easily search for files in Google Drive related to specific projects, the file template version, and whether it was an archived file or a live file with Google Apps Script.

In most cases, I needed to reference a bunch of Google Sheets built upon a template Google Sheet that was generated for a project, but also other Google files and non-Google file types in Google Drive.

The problem is that sometimes files can be edited by mischievous little imps 👿 that can mess with naming conventions and even administrative sections in files while the user is away 😉.

This means that titles and file data can be an unreliable way of searching for files. Further, searching within files for target text, especially over a large list of files, can be incredibly time-consuming programmatically.

There is an excellent way of managing this with Google’s Drive Labels API. Unfortunately, as of the writing of this tutorial, label creation is only available to Google Admins. However, there may be a change to this in the future with access to label creation at the Shared Drive level – take a look at this screenshot:

Google Labels may be available for creation at the Shared Drive level in the near future
Google Labels may be available for creation at the Shared Drive level in the near future

So what’s the alternative?

After sifting through the deepest darkest reaches of Google Drive API documentation, I stumbled across adding custom file properties to any file in your Google Drive.

Custom File Properties

Custom File Properties allow us to add our own searchable or queryable key-value pairs as metadata to any file in our Google Drive. It can only be edited programmatically, preventing these little imps mentioned above from messing with them.

There are two types of properties:

  • properties: Visible to all applications.
  • appProperties: Visible only to the app using the file (Great for Google Workspace Add-ons and Google Workspace Editor Add-ons for file tracking).

Custom file properties are limited to:

  • A maximum of 100 custom properties per file from all sources.
  • A maximum of 30 appProperties per file for per application and
  • 30 properties per file.
  • A maximum of 124 bytes per property. This is the combined total of both the key and value of each property.

The Example

We’ll be following an example of generating and querying a set of properties for a number of files.

To play along, you can set up your Google Apps Script file by:

  1. https://script.new/  : Create a new Apps Script File
  2. Add Drive API Advanced Service Version 3:
    1. Click Services
    2. Select Drive API
    3. Select version: v3
    4. Click Add

      Add Drive API Advanced Service V3 to Google Apps Script Project
      Add Drive API Advanced Service V3 to Google Apps Script Project

       

  3. Create a file called Setup.gs.
  4. Paste the following:

  5.  In your main Code.gs file add the global REF constant variable:

  6. Create a test folder and replace the ID in the FOLDER_ID with its ID.
  7. Create a template file (I am using a blank Google Sheet here) and replace the TEMPLATE_FILE_ID with your newly minted template file ID.
  8. Go back to your Setup.gs file and run the function setupDemoFiles()

This will generate 7 files that we can add our property data to.

Update & Create Custom Google Drive File Properties with Apps Script

We can update a single file in Google Drive by providing the file ID and an object of key-value pairs and passing it through the Drive Files update method.

This approach will either update or add new properties to a file. Any existing property with the same name as the new property key will be replaced.

The Test Function

Lines 1-7

In our test function, test_updateCustomFileProperties() we are providing a properties object containing 3 properties that we want to add to our file.

We are also referencing our template file global variable for this example.

updateCustomFileProperties()

Lines 13 – 36

The function

The updateCustomFileProperties() function takes a file ID string and a properties object of key-value pairs as its two arguments. Line 21

The Resource Object

Next, we create a resource object containing our properties. You may also wish to update other metadata items of the file or even the data of the file during this process.  Lines 23-25

Executing the ‘Update’ Method

In our try-catch statement, we then make a call to the Drive.Files.update() method to update our metadata properties.

The updates() method requires 4 arguments:

  1. Resource: The target resource object to change any metadata items in the file, including our custom parameters.
  2. File ID: The file ID of the file to update.
  3. File content blob: For us, this is set to null because we do not wish to change the content of the file. However, you can create blob data to update the file contents here.
  4. Optional parameters: Here, you can add optional parameters. For us, we want to see both the id and the properties of the file returned after we update the file. To do this, we use the ‘fields’ property.
    Commonly, you may need to update a shared drive and will need your optional parameters object to look a little more like this:

     

If successful, the update will return the file’s ID and the full properties object, including the properties that you just added or updated.

Here is an example response:

Search Files By Custom File Properties in Google Drive with Apps Script

Now that we have created our first custom file property, we want to be able to query it. Fortunately, the Google Drive API allows us to do this with the Drive.Files.list() method.

Google Drive API Files list comes packed with a lot of options, which can make things a little confusing to set up for your needs. For this tutorial, we are going to keep things simple to focus on working with properties, but if you want to dive into queries, you should check out this tutorial:

List all files and folders in a selected folder’s directory tree in Google Drive: Apps Script

On with the code…

The Test Function

Lines 1-10

The function, test_searchFilesByCustomFileProperties(),  sets the properties to be queries. 

In the example, we are querying all properties by both their key and value pairs. However, we could just query by any one of these properties on their own. For example, we may wish to find all the files under the project, ‘metadata Test’, that have the status ‘live’ and not care about the version.

searchFilesByCustomFileProperties()

Lines 12 – 55

The Function

The searchFilesByCustomFileProperties() function takes a single object of properties to query as its argument.

You can provide some or all properties as your query to either broaden or narrow in your search query.

Generate the query string

Lines 20-33 and line 43

We can create a basic search query for the custom file properties in our Google Drive with the following query string:

properties has {key='project' and value='metadata Test'}

Here, we are searching for any file that contains the key, ‘project,’ that also contains the value ‘metadata Test’. To broaden your search query, you can also omit the and and value data to only look for files that contain the property key.

To search by multiple property queries, we need to join them with an and.

Our first task is to convert our searchQueries object to a 2d array of key-value pairs (line 20). We will also grab the length while we are here (line 21). So our example data would look like this:

Next, we will use a JavaScript reduce method to iterate over each query array item and generate a string of search queries for each one, adding AND between each query except for the last one (lines 23-35).

Finally, we should probably ensure that we are not searching for trashed files with trashed=false (line 43).

Our query string would then look like this:

Generate the Payload

lines 37-44

The Drive Files list() method takes a payload of arguments. In our example, we are including:

  1. fields: Setting the fields to return the file ID, properties object and the name of the file. You can also display other file data like the creation date, edit date, the creator of the file, next page token if you expect a large array of results and a whole lot more.
  2. supportAllDrives: Setting this to true allows us to access shared drives so long as we …
  3. includeItemsFromAllDrives: to ensure we query data from all drives.
  4. corpora: Setting this to allDrives allows us to not only see the files we created in a shared drive but also those created by others.
  5. q: The query.

You can modify these arguments to better match your needs by looking at the documentation.

Executing the list request

Finally, we call Drive.Files.list() with our payload.

If successful, this will return an object that includes a files property containing an array of files that match the query.

It should look a little like this:

Keep in mind that if you expect a larger number of files, then you should also set a field to display the next page token and then make another request for the next page.

If you have found the tutorial helpful, why not shout me a coffee ☕? I'd really appreciate it.

Batch Updating Custom File Properties for Multiple Files with Apps Script

Now, if you are setting up a bunch of files to contain custom file properties or updating the files you found from your properties search query, you will want to update them quickly.

Clearly, iterating over each target file to run Drive.Files.update() when you have thousands of files is going to take way too long.

Fortunately, the paragon of Google Apps Script development, Kanshi Tanaike, has created a helper function that allows us to batch update our update requests all in one batch or a chunk of batches at a time.

We will need to change the request type from a Drive API request to a HTML request with URL FetchApp but this is relatively simple for our purposes.

The Test Function

Lines 3-13

Our test function hasn’t changed all that much from our single-item update. We will be setting the properties that we want to add, and then updating all files in our target folder to have the same properties.

createBatchUpdateObject_CustomFileProperties()

Lines 15-58

This function will update each file in a target folder to contain the properties provided to it.

You may wish to tweak this function to do some other things:

  • Change the property values based on some other factor. Say, if any files have a last edit date longer than 90 days, then set status to archive.
  • Change the payload to how you draw the files. You may wish to extract all the files from an entire shared drive or traverse a particular directory.

We’ll keep things simple here and update all files in our target folder.

The function

The function, createBatchUpdateObject_CustomFileProperties(), takes two arguments:

  • folderId: the folder ID of the directory that you want to get your files from. Note that this will only extract files from one level of folders.
  • properties: The properties object that you will be updating.

The function will then return a string receipt of what was returned and updated from the batch request.

Extracting the Files from the Folder

Lines 24 – 26

Here we use the Drive.Files.list() method again and ensure that we are also looking in Shared Drives, just in case.

Our query this time is set to query and retrieve any file that has the parent folder of our target folder and is not a trashed file.

This will return an array of files containing the file name and ID of the found files using the fields property. Again, you may also need to get the next page token field to iterate over larger files.

Creating the Batch Request

Lines 41 – 49

Now that we have our list of files to update, we need to build our batch request HTML object.

We can build this by demoing a build in the documentation API build too to the right of the documentation reference. Line 41

First, we set our base URL and then add our optional arguments starting with a question mark, with each argument separated by an ampersand.  Line 43

Now we can iterate over our list of files and map an arrange of requests feeding in our payload. Here, we add an HTML method of PATHCH with an endpoint URL generated with our base URL, file ID and optional arguments. This will then return an array of requests for the batch update function. Line 41 – 49

Sending and retrieving the batch request

Lines 51 – 57

Finally, we can send off our batch request object. We will first create an object variable containing our batch path for Google Drive and our array of requests.

Then we will call Tanaike’s batchRequests() as the object of the argument. This object returns a URL Fetch App HTTP Response from the function, where we can check if an error occurred from the getResponseCode() method and display the receipt string from the request with get ConentText().

batchRequest()

This glorious function, created by Kanshi Tanaike, sends a batch request for any Google API type. It is best suited for post requests, and you will need to be mindful of managing large requests yourself, where you may exceed the batch request limitations:

  • Batch Request Limit: Exceeding 100 calls in a single batch request may lead to errors.
  • Inner Request URL Length: Each individual request URL within a batch must not exceed 8,000 characters.
  • No Batch Media Operations: Google Drive does not support batch operations for uploading or downloading media files.
  • No Batch File Exports: Batch processing is not available for exporting files from Google Drive.

Here is Tanaike’s guide for more information on this function, along with some benchmarks and samples.

Efficient File Management using Batch Requests with Google Apps Script

Conclusion

As you can see, using custom file properties in Google Drive with Drive API advanced service and Google Apps Script can be an extremely handy way of storing metadata for your files for better file querying and management.

I would love to see how you would use this in your own project, and it would provide a great deal of inspiration for other users. Please consider commenting below.

If you have found the tutorial helpful, why not shout me a coffee ☕? I'd really appreciate it.

~ Yagi

 

List all files and folders in a selected folder’s directory tree in Google Drive: Apps Script

If you have ever tried to get a list of all the child files and folders of a parent folder in Google Drive, you’ve no doubt discovered that it is a slow old process. Iterating over each item in a folder and then reading the metadata of that file or folder before calling the next one can take forever!

The built-in DriveApp Class for Google Apps Script is great for working on a small number of files and folders but it just doesn’t have the functionality to retrieve specific fields in your metadata, nor does the searchFiles method or searchFolders method have the ability to isolate just the fields that you want to retrieve. Subsequently, your processing time increases significantly as it ships junk data.

This tutorial is my attempt at, as the kiddies say today, creating a ‘blazingly fast’  file and folder iterator with Google’s Drive API v2 for Apps Script.

Continue reading “List all files and folders in a selected folder’s directory tree in Google Drive: Apps Script”

How to Automatically Share Teachable Students to Google Drive Files and Folders when they Enroll in your Course

Not only are Google Workspaces, Google Sheets, Docs, Forms and Slide great to work in and look awesome, but the convenience of collaborating and sharing your Google Drive Files and Folders is also super useful. So much so that many course creators share their documents with their students all the time.

The problem that course creators have is that they are generally stuck with two options when sharing their Google Drive files and folders:

  1. Set sharing to Anyone with Link can view. And hope other freeloading students don’t find and share their course material.
  2. Manually share each student as they enrol. Which is time-consuming for the course creator and annoying for the student who needs to wait to be shared before they can get their hands on your awesome course content.

Both options are really terrible.

I reluctantly chose option one for my first Google Sheets Essentials Teachable Course and it really bothered me. I needed to find a way to share my Google Drive course content with only those students who signed up for my course.

In this tutorial, I will guide you through creating a Google Apps Script web app that receives a webhook notification when a student enrols onto one of my Teachable courses. If a student enrolled with a non-Gmail or non-Google Workspace domain email account, they will be sent an email with an attached form to add a Google-friendly email.

If you want a copy of the Google Sheet with the Apps Script attached, without coding it all yourself, plus written-visual tutorials on how to quickly set up your sheet head over to my teachable page now and purchase the sheet and instructions for just $2.95. Yeap not even the price of a cuppa.

The fun thing is that you will experience how the whole process works, because…well…that’s how I am going to share the Google Sheets file with you when you enrol. Neat, hey?

As a part of your purchase you will also get a few other perks:

  • Set files or folders for ‘view’, ‘comment’ or ‘edit’ access. 
  • Add existing students to your selected course Google Drive Files and Folders.
  • Get your full course list from your Teachable site right in your Sheet. 
  • A choice to bulk set your files and folders to:
    • prevent downloads, copying and print.
    • Prevent sharing by any documents you have provided ‘edit’ permission to.

If you want to understand how it all works and build your own, read on, you can always throw a couple of coins at me and enrol to run the workflow just for fun.

Instantly share ONLY Teach:able Students to selected Google Drive Files and Folders

 

If you are looking to build your own Teachable Course you can check out a how-to guide here:

How to launch an online course—and craft your email strategy

Continue reading “How to Automatically Share Teachable Students to Google Drive Files and Folders when they Enroll in your Course”

Get a list of Google Shared Drives by ID and Name in Google Apps Script [updated 16 Dec 2022]

If your organisation is using Google Workspace Business Standard, Business Plus, Enterprise, or one of the other supported plans, you are likely taking advantage of the power of Google’s Shared Drives.

If you have decided to create a Google Apps Script project that needs to get a list of your Shared Drive (or a user’s shared drives in the case of a WebApp), then you might be scratching your head right now wondering how to get this list using the built-in DriveApp class.

Whelp, unfortunately, at the time of writing this article the DriveApp class does not have this functionality. However, it is pretty easy to access in a single line of code using an Advance API.

Here’s what you need to do:

As always, read what you need and skip the rest. 

Continue reading “Get a list of Google Shared Drives by ID and Name in Google Apps Script [updated 16 Dec 2022]”

Google Apps Script: Extract Specific Data From a PDF and insert it into a Google Sheet (Updated Feb 2024)

Google Apps Script: DriveApp, Advanced Drive Service, SpreadsheetApp,  DocumentApp Javascript: spread operator, map, regex

Ah, bureaucracy at its finest.  Have you ever asked for a list from a client, another department or agency and instead of saving into a file that might even be considered marginally useful, they give it to you as a pdf. A… p…d…f.

Gee, thanks.

After some prostrations to the great Google Apps Script gods, I had a though.

“Hey, can’t we convert a PDF to a Google Doc with just a click of the button? Surely the great Google Apps Script devs have made it so we can do it programmatically too.”

And you know what? They bloody well did. The big legends.

The Scenario

I’ve just received a bunch of PDFs. The PFDs are all labelled by the class number. Take a look at the files in my Google Drive:

PDFs of sections in Google Drive

Each PDF file contains a list of student IDs that I need to extract and put into a Google Sheet.

PDF file with student IDs

The aim is to have a list of student IDs in column A and their corresponding sections in column B.

As you can see, we have some pretty standard text in the PDF that should be easy for Google to recognise so that we can extract the IDs.

The list of names in the demo sheets were randomly generated by AI!

NOTE! As always, I have tried to create this tutorial for varying levels. Feel free to follow along, or just grab what you need and get stuck into your own project.

If you are playing along, you can find a copy of the PDF files below. Simply add them to your own Drive before you get started:

PDF files by Section.

Continue reading “Google Apps Script: Extract Specific Data From a PDF and insert it into a Google Sheet (Updated Feb 2024)”