Zia.
Google Apps Script & WorkspaceJune 30, 20265 min read

Getting Started with Google Apps Script: Automate Google Workspace

A hands-on introduction to Google Apps Script — write your first script, automate Google Sheets and Gmail, add custom menus, and run code on a schedule with triggers.

Getting Started with Google Apps Script: Automate Google Workspace

If your team lives in Google Sheets, Docs, and Gmail, Google Apps Script is the fastest way to automate the boring parts. It's JavaScript that runs on Google's servers with built-in access to the entire Workspace — no server to host, no API keys to juggle, no OAuth setup for your own account. You write a function, and it can already read your spreadsheet, send email as you, or create a calendar event.

This is a hands-on introduction. By the end you'll have written a script that reads a sheet, emailed from it, added a custom menu, and scheduled code to run automatically.

What is Google Apps Script?

Apps Script is a cloud-based scripting platform built on JavaScript. Google gives you:

  • Built-in service objectsSpreadsheetApp, GmailApp, DriveApp, DocumentApp, CalendarApp — that wrap each Workspace product.
  • Free hosting and execution on Google's infrastructure.
  • Triggers to run code on a schedule or in response to events (a form submit, a sheet edit).

There are two flavors: container-bound scripts (attached to a specific Sheet, Doc, or Form) and standalone scripts. We'll use a container-bound script because it's the most common starting point.

Step 1: Open the script editor

Create a new Google Sheet, then go to Extensions → Apps Script. A new tab opens with the editor and a default Code.gs file containing an empty myFunction. That's it — you're set up. No install, no local environment.

Replace the contents with a first script:

function hello() {
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange("A1").setValue("Hello from Apps Script 👋");
}

Click Run. The first time, Google asks you to authorize the script to access your spreadsheet — approve it. Switch back to your sheet and cell A1 now says hello. You just ran server-side code that edited your document.

Step 2: Read and process sheet data

Real automation reads data, does something with it, and writes results back. The key method is getValues(), which returns a 2D array of the range's contents.

Say you have a sheet of invoices with columns Client, Email, Amount, Status. This reads every row and collects the unpaid ones:

function getUnpaidInvoices() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const rows = sheet.getDataRange().getValues();
  const [header, ...data] = rows; // drop the header row

  const unpaid = data
    .filter((row) => row[3] === "Unpaid")
    .map((row) => ({ client: row[0], email: row[1], amount: row[2] }));

  Logger.log(unpaid);
  return unpaid;
}

getDataRange() grabs everything with content, so you don't hardcode row counts. Use View → Logs (or Logger.log) to inspect output while developing.

Performance note: Apps Script is slow when you call the Sheets API in a loop. Read once with getValues(), process in memory, then write once with setValues(). Reading a cell per row will crawl on large sheets.

Step 3: Send email from a sheet

Now make it useful. GmailApp (or the lighter MailApp) sends email as you. Loop over the unpaid invoices and send a reminder:

function sendPaymentReminders() {
  const unpaid = getUnpaidInvoices();

  unpaid.forEach(({ client, email, amount }) => {
    GmailApp.sendEmail(
      email,
      "Payment reminder",
      `Hi ${client},\n\nOur records show an outstanding balance of ` +
        `$${amount}. Could you let us know when we can expect payment?\n\nThank you.`,
    );
  });

  SpreadsheetApp.getActiveSpreadsheet().toast(
    `Sent ${unpaid.length} reminders`,
  );
}

Run it once and check your Gmail Sent folder. This single function replaces a weekly manual chore — the kind of Google Apps Script automation that quietly saves teams hours every month.

Step 4: Add a custom menu

You don't want to open the script editor every time you run a function. Apps Script can add your own menu to the Sheet's toolbar using the special onOpen trigger, which runs automatically whenever the document opens:

function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu("Invoice Tools")
    .addItem("Send payment reminders", "sendPaymentReminders")
    .addSeparator()
    .addItem("Refresh unpaid list", "getUnpaidInvoices")
    .addToUi();
}

Reload the spreadsheet and a new Invoice Tools menu appears next to Help. Now a non-technical colleague can trigger your automation with a click — no code in sight.

Step 5: Run code on a schedule with triggers

The real power move is running scripts without anyone present. Apps Script triggers fire code on a schedule or on events. You can add them in the UI (the clock icon → Triggers) or in code:

function createDailyTrigger() {
  ScriptApp.newTrigger("sendPaymentReminders")
    .timeBased()
    .everyDays(1)
    .atHour(9)
    .create();
}

Run createDailyTrigger once, and from then on Google runs sendPaymentReminders every morning at 9 a.m. — even when your laptop is off. Other trigger types include onEdit (react to cell changes) and onFormSubmit (process new form responses).

Step 6: Call an external API

Apps Script isn't limited to Google's own services. UrlFetchApp makes HTTP requests, so you can pull data from any API and drop it into a sheet:

function fetchExchangeRate() {
  const response = UrlFetchApp.fetch(
    "https://api.exchangerate.host/latest?base=USD&symbols=EUR",
  );
  const data = JSON.parse(response.getContentText());

  SpreadsheetApp.getActiveSheet()
    .getRange("A1")
    .setValue(`1 USD = ${data.rates.EUR} EUR`);
}

Pair this with a time-based trigger and you have a self-updating dashboard — currency rates, inventory levels, or metrics from your own backend refreshed on a schedule.

Quotas and limits to know

Apps Script is free, but it has daily quotas to prevent abuse:

  • Email: 100 recipients/day on consumer accounts, 1,500 on Workspace accounts.
  • Script runtime: each execution is capped at 6 minutes.
  • UrlFetch: 20,000 calls/day on Workspace.

For most internal automation these are generous. If you hit the runtime cap, split the work into batches and use triggers to process a chunk at a time.

Deploying beyond your own account

Everything above runs under your login. To share automation across a team or publish it, you have options:

  • Share the container document — colleagues get the custom menu and can run the functions themselves (each authorizes once).
  • Publish as a Workspace Add-on to the Google Workspace Marketplace, so it installs cleanly across a domain.
  • Deploy as a web app to expose an HTML interface or an endpoint other systems can call.

Where to go next

Apps Script is deceptively powerful — I've built full approval workflows, document generators, and Sheets ↔ database sync tools on it. The pattern is always the same: read data, transform it, act, and let triggers run it unattended.

If you have a repetitive Workspace process you'd like turned into a reliable, shareable tool — or a Marketplace add-on built and published — that's the Google Apps Script development work I do for clients worldwide.

Related services

Need this built for you? Here's where I can help.

Zia ul Qamar

Written by

Zia ul Qamar

Full-stack developer specializing in React, Next.js, and Node.js, with a rare focus on Microsoft Office & Google Workspace add-ins. I build production tools and automations for international clients.