Joshua's Docs - Google Apps Script (GAS) and Clasp Cheatsheet
Light

Resources

What & Link Type
Apps Script Homepage Homepage
Gettings Started with CLASP (Command Line Apps Script Platform) Guide
My post - Using TypeScript with Google Apps Script Guide

Using clasp

Reference material:

Quick reference:

  • One time setup

    • Install

      • yarn global add @google/clasp
      • npm install @google/clasp
    • Grant credentials

      • clasp login
  • Project setup

    • cd {projectDir}
    • If...

      • ... starting from scratch

        • clasp create {scriptTitle}
      • ... project started already in web UI

        • clasp clone {scriptId}
  • While working

    • Download: clasp pull
    • Upload: clasp push
    • Open in browser: clasp open

Ignoring files

You can create and use a .claspignore file to ignore files from being uploaded, just like how .gitignore works.

By default, if no file is provided, it will only look for matching source code files (.js, .ts, .gs, .html), and blocks anything in .git or node_modules.


Using type definitions

You can find the types in @types/google-apps-script and @types/google-adwords-scripts.

If you are using straight TS, you can just install and then use as normal.

If you are using JS and want typed intellisense, you can install and then use the triple slash directive trick, or setup a tsconfig file.

If you don't want to have a package.json file, you could globally install types, and then pull in via symlink with npm link @types/google-apps-script. Just make sure you don't have clasp auto-upload!

...Or, you could also be lazy and use a triple slash directive with a global install location, like /// <reference path="C:/laragon/bin/nodejs/node-v12/node_modules/@types/google-apps-script/index.d.ts" />


Common Coding Challenges

How to respond to GET / POST

In order to respond to incoming requests, you simply declare a top level function that matches the magic function name the docs indicate:

HTTP Method Matching function
GET doGet(e)
POST doPost(e)

For those looking for what e, or event looks like and its properties, this table in the docs has you covered. Or, if you are using types, the explicit type of e is GoogleAppsScript.Events.DoGet or GoogleAppsScript.Events.DoPost, depending on the matching function.

Reminder: For accessing a JSON POST body, you can use JSON.parse(e.postData.contents)

How to serve a redirect from a request

You basically can't serve a redirect, at least not directly via standard status and location headers.

Instead, the only workaround is to return an HTML document (via HtmlService), and in it, add JavaScript that redirects by using window.open(REDIRECT_URL, 'top');

Details:

How to make web requests (GET, POST, etc.)

Because GAS does not run in the browser, you don't have access to window.fetch() or even XMLHttpRequest; both of those are web APIs. You do however have a GAS provided service and set of methods - "Url Fetch".

NOTE: GAS's method fetch() is not the same as the web API fetch() that most people are used to. To start with, GAS fetch(), like pretty much everything in GAS, is synchronous, not async!

How to persist values across runs

As you start building more complex scripts, a common requirement that you run into is the need to "persist" a value across script runs, which is something that you cannot do with plain JavaScript / GAS variables.

There are tons of options on how you can save and retrieve a value when executing Google Apps Script code, but I'll break them down into categories.

  1. External Services (Non-Google)

    • Since Apps Scripts can make network requests, there is nothing preventing you from wiring up your script to a non-GAS backend somewhere else.

      • GAS also has built-in support for remote database connections, via JDBC. You can find docs for that here.
    • Here are some examples of non-Google external services you could wire up in order to persist data

      • MySQL Database (via JDBC)
      • External API (PHP, NodeJS, etc.)
      • POST endpoint for form collection
      • Another cloud DB: AWS, Azure, etc.
  2. Native Services (Google)

    • Since you are using GAS, there is a good chance you have a preference for staying in the Google ecosystem.

      • As an added bonus, most of these options are free and easier to setup
    • Native options include:

      • The "Properties Service"

        • Simple string key-value store, stored with the script
      • Google Sheets (very common approach)

        • Good for small pieces of data, especially when allowing user configuring
        • starter guide
      • Google Drive

      • Google Cloud SQL (via JDBC)
      • Google Big Query (docs)
      • ... probably at least one more I'm missing, given how often Google changes their product lineup.

How to log and debug in Google Apps Script

Debugging and logging in GAS can be a little complicated, especially if you mix in deployed versions, connections to Google Cloud Platform (GCP), and exception handling.

The debugging section of the GAS troubleshooting page is a good starting point for learning about all the debugging and logging methods available to you.

General Logging Rules

As a general rule of thumb, if...

  • You are executing code manually, via the online IDE Run menu

    • You can use Logger.* for output to the IDE's log output
    • You can use the Debug menu options to debug functions
    • You can use console.* for BOTH IDE logging and Stackdriver logging
  • You are executing code via triggers (time based, doGet, etc.)

    • You can only use Stackdriver logging (console.*) and exception recording

      • This is because the IDE logs (via Logger.*) are not persisted

Read more: Google Apps Script - Logging Guide

Where to find Logs and Exceptions

Again, depends on your use case:

  • Online IDE Logs:

    • Menu -> View -> Logs
  • Stackdriver logs and executions - any of the below options:

Advanced Stackdriver Logging

To enable more advanced Stackdriver logging (filtering, advanced views, etc.), you have to change the GCP project that your script is attached to from a "Default GCP Project", to a "Standard GCP Project".

This is the warning text from the docs about this:

You can view a simplified version of Stackdriver logs in the Apps Script dashboard. However, to make the most of Stackdriver logging and error reporting you must have access to the GCP project of the script. This is only possible if your script project is using a standard GCP project.

There are other reasons why a standard project might be preferred anyways, and you can find those reasons as well as instructions for converting to standard in this doc page.

Alternative Logging Methods

There are many other alternative ways you could log output somewhere:

  • Save to a Google Spreadsheet (just append a new row each time)
  • Integrate with a third party logger (Sentry, Rollbar, etc.)
  • Email yourself a report, text yourself, etc.
  • Save to Google Drive
  • ... and many other options

How to Deal With Configurable Secrets and Passwords

There are many different approaches for how to deal with configurable secrets and passwords in GAS, and the best option really depends on your specific use-case. Here are some to consider:

For user-configurable secrets (where you are publishing your script, and want users to be able to modify their password / secret)

  • Using the Properties Service

    • Since there is no longer a visual editor for these properties, you would need to do something like:

      • Code your own simple editor

        • Or
      • Prompt users to run a one-time script that sets the value based on their input

        • Or
      • Something else...
  • Spreadsheet Scripts: Store value directly in sheet

    • For example, the user could store their secret value in a named range of SecretKey, and then you could use:

      const userSecretRange = SpreadsheetApp.getActiveSpreadsheet().getRangeByName('SecretKey');
      const userSecret = userSecretRange ? userSecretRange.getValue() : undefined;

For secrets that are hardcoded into your script, there are still some related approaches:

  • If you are checking auth input against an expected value, you could use:

    • Private/Public Key Pairs

      • The published script would use a public key, requests to the script would have to be signed with the private key, and your script would check that these match.
    • Standard (strong) Hashing

      • Instead of storing the expected value directly as a plain-text string, you would store the SHA256 hash, as a base64 encoded string. Requests to the script would provide the plain-text password, which would then be hashed and checked against the stored hash.

Deprecated Visual Properties Editor

Apps Script used to have a really easy way to allow for configurable hidden script properties, where you could quickly edit a hidden key-value store that was accessible from the script code, but stored with the user. The scoped key-value backing system still exists, but they removed the visual editor:

Removed visual user properties editor

This a giant bummer, because this used to be a great way to be able to share the source code of a script that requires authentication, and just tell people they need to plug their key into that tab.

Markdown Source Last Updated:
Tue Dec 29 2020 03:56:20 GMT+0000 (Coordinated Universal Time)
Markdown Source Created:
Sat Nov 23 2019 21:50:40 GMT+0000 (Coordinated Universal Time)
© 2021 Joshua Tzucker, Built with Gatsby
Feedback