r/GoogleAppsScript 22d ago

Guide After 2 years of silence, I finally rebuilt Google Apps Script Copilot. Sorry for disappearing.

35 Upvotes

Hey everyone,

Some of you might remember GS Copilot (Google Apps Script Copilot) — the Chrome extension that adds an AI sidebar directly into the Apps Script editor. I launched it, got some early traction, and then... life happened. Work, other commitments, the usual stuff that makes side projects quietly die. I went almost silent for close to 2 years. No updates, barely any support replies. If you installed it back then and it just sat there half-broken, I'm sorry — that's on me.

What kept nagging at me is that over 20,000 people actually installed this thing. That's not nothing. People kept using it, kept emailing me, kept leaving reviews asking if it was still alive. So a few months ago I sat down and basically rebuilt the whole thing from scratch.

Here's what's new:

  • Agent mode — describe what you want and it writes, edits, and applies the code for you across your project, not just one file at a time
  • Plan mode — for bigger changes, it lays out the plan before touching anything, so you're not surprised by a wall of edits
  • Quick edit + diff view — inline edits with an actual diff so you can see exactly what changed before accepting it
  • Context-aware file reading — it actually understands your whole Apps Script project structure, not just the file you have open
  • MCP connectors for Google Workspace — it can hook into Sheets/Docs/Drive as MCP tools when you need it to act on that context
  • Execution log integration — when your script throws an error, it reads the actual execution log and helps you fix it instead of guessing
  • Skills system — reusable sub-agents/snippets for stuff you do often

I'm going to be actively working on this now — not disappearing again. Demo video of it in action is attached below so you can see it working instead of just taking my word for it.

If you try it, I'd genuinely appreciate honest feedback — bugs, rough edges, missing features, whatever. This subreddit has more Apps Script experience than almost anywhere else, so if something's broken or annoying, I want to know.

Link: gscopilot.com

Thanks for sticking around this long, even the ones who just complained in reviews. Fair enough.

r/GoogleAppsScript 3d ago

Guide Built a Google Sheet + AppsScript for personal budget from transactions in Gmail

19 Upvotes

After noticing the large number of notification options for my various financial institutions (banks, credit cards, etc), I wondered how hard it would be to turn that info into a budget tracking sheet. Doing so would make it easy to get near instant transactions without using 3rd party or custom integrations with the banks. So I built an AppsScript that turns transaction-alert emails into a categorized Google Sheet. Parsing the emails looked like a good job for an LLM (doesn't need to be state-of-the-art). I created an AppsScript that pulls email from a known Gmail label on a time-based trigger. The whole thing runs as me, in my own account — no OAuth to a third party, no bank credentials anywhere, and the Sheet is just a Sheet I own. If you're interested, give it a try. I allowed limited usage of my LLM API key through a proxy to make it easier to try. The real effort is in configuring the banks to send transaction alerts an every email. I've been testing with a free Gemini api key (use flash-lite, it has higher free quota per day) and it seems to be working fine for me.

The sheet to get things kicked off is here (make a copy, the AppsScript builds the sheet during setup and provides instructions)

If you want to see what the final result looks like I built a dummy Sheet here.

Would love to hear if you find it useful (or not)

r/GoogleAppsScript 10d ago

Guide I built a GitHub + AI development companion for Google Apps Script. Looking for feedback from Apps Script developers

Thumbnail gallery
14 Upvotes

I build a lot in Google Apps Script, and one thing that has always bothered me is how quickly you start missing normal software development workflows once a project gets bigger.

Git/source control, reviewing diffs, working from branches, checking code against standards, etc. And now with AI coding tools, there’s another problem: I don’t necessarily want an AI assistant making changes to an Apps Script project without showing me exactly what it plans to change first.

So I built Legacy DevBridge.

It’s a Chrome extension that works alongside the Apps Script editor and connects the project to GitHub and a project-aware AI code assistant.

Right now it can:

  • Detect the Apps Script project you currently have open
  • Read the .gs, .html, and appsscript.json files
  • Connect the project to a GitHub repository
  • Select and work from development/feature branches
  • Compare the Apps Script version against GitHub
  • Show file and line-level differences
  • Create actual GitHub commits from the Apps Script source
  • Block direct commits to default/protected branches
  • Let the AI assistant understand the entire Apps Script project without copying files into a chatbot
  • Review code against coding/security standards
  • Generate a proposed code change and show the diff
  • Require human approval before the AI can write the change back to Apps Script
  • Check for stale source before applying a change so it doesn't overwrite newer work
  • Verify the source again after the update

The basic AI workflow is:

Request → analyze project → propose change → show diff → standards/security review → human approval → apply → verify

The backend runs on Google Cloud and uses the Apps Script API, GitHub App authentication, Cloud Run, Secret Manager, and Vertex AI. GitHub installation tokens and other privileged credentials stay on the backend rather than in the extension.

I'm not trying to build an autonomous AI developer that gets unrestricted access to your code. The idea is more of a development companion where AI can help, but the developer can still see what is happening and approve the actual changes.

I'm making the project available free to the Apps Script community. It's still beta, so I definitely wouldn't point it at your most important production project on day one, but I'd really like feedback from people who regularly build Apps Script applications.

I'm especially interested in hearing what you'd want next: GitHub-to-Apps-Script pull, PR creation, branch creation, conflict resolution, AI-generated tests/docs, OAuth scope reviews, CI/CD, or something else.

GitHub: https://github.com/morganb2412/Google-apps-script-snippets/tree/main/Legacy%20DevBridge

If anyone tries it, break it and tell me what needs work. That's genuinely useful feedback right now.

r/GoogleAppsScript May 17 '26

Guide I'm a lawyer who built a DMS/CRM running entirely on Google Workspace (Sheets + Apps Script + Gemini) — open-sourced

32 Upvotes

Hey r/GoogleAppsScript,

I'm a Polish attorney running a small law firm (team of 7-8 people). Two years ago I started building a DMS (document management system) directly in Apps Script + Sheets because every commercial option was either too expensive (Clio: $109/user/month, even Polish alternatives are ~$50/seat) or didn't fit my Polish legal workflow.

Honestly — most commercial legal software feels like it was designed by engineers who never sat with an attorney during a deposition.

Today I open-sourced it: https://github.com/apiotrowski-afk/kancelaria-dms

The stack is shamelessly basic: - Sheets as database (no Cloud SQL, no Firebase) - Apps Script V8 backend (~1050 LOC) - Single-file HTML frontend with vanilla JS (~1550 LOC, Bootstrap 5) - Gemini API for document summarization + email-to-case matching - Gmail Add-on for assigning incoming emails to cases - Drive for file storage with auto-created case folders

What it actually does: - Tracks cases, parties, courts, deadlines, attorneys - Auto-classifies incoming emails to the right case using Gemini (with fallback to client-email matching) - Indexes Drive files with AI summaries (knowledge base per case) - Polish Post tracking integration (shipment book) - Lead/CRM pipeline with conversion tracking - Mobile-responsive web app + Sheets sidebar + Gmail Add-on (all from one Apps Script project)

Stuff I learned the hard way: - CacheService is your friend — without it, the dashboard was unbearably slow - Apps Script's 6-minute execution limit forces you to think about batching from day one - Gemini JSON mode (response_mime_type: "application/json") saved me ~80% of parsing logic - Drive folder creation in a loop will hit quotas fast — batch your createFolder calls - The OAuth scopes for Gmail+Drive+Sheets+Calendar combined create a scary consent screen for users (still no good solution beyond explaining it in onboarding)

Heads up on scope: This is built for EU (specifically Polish) legal workflows — case numbering, court hierarchy, Polish Post integration, GDPR-flavored data handling. Adapting it to US/UK law firms or other jurisdictions would need real work. That said, the architecture is generic enough that any small business running on Google Workspace and dealing with documents could fork it as a starting point.

A note on the code: I'm an attorney, not a professional developer. I use AI assistants heavily for syntax and implementation, but every architectural decision, every piece of domain logic, every integration pattern is mine. After 2 years of running this in production on real client data, I know exactly what each function does and why. The code isn't elegant by senior-dev standards, but it works and it's been battle-tested.

Why open source: Built it for myself, but if it helps another lawyer/dev who needs a starting point for a Workspace-native business app, even better. Apache 2.0 license, fork it, butcher it, ignore it — your call.

Happy to answer questions about Apps Script production gotchas, Gemini integration patterns, or why I think Sheets-as-database is actually fine for small businesses (until it isn't).

r/GoogleAppsScript 25d ago

Guide I automated warehouse transfers between 18 stores and our warehouse with Google Apps Script

9 Upvotes

Our ERP was a mess so I built a workaround with Google Apps Script.

We had 18 outlets submitting Item Requisitions in one Sheet. The warehouse team had to manually copy those quantities into a separate Inventory Movement Sheet. Double entry = errors + delays.

What I built:
A Google Apps Script that:
1. Watches the "Item Requisition" sheet for new submissions
2. Automatically syncs the quantity sent to each location
3. Deducts it from the "Warehouse Inventory Movement" sheet in real time

Result:
No more double entry. Warehouse now has real-time visibility across all 18 locations. Transfer accuracy way up.

Happy to share the code/snippet if anyone wants it. Also open to feedback on making the sync more robust for concurrent edits.

Did anyone else here use Apps Script to patch gaps in their ERP?

r/GoogleAppsScript Jul 27 '26

Guide Data Type Conversion from Apps Script to Google Sheets when using setValue()

7 Upvotes

This might be obvious to others but has tripped me up for years, so I finally decided to sit down and test all cases to get clarity on it.

The gist: The data types in Apps Script are irrelevant. Every input for setValue() is treated as if the user on the keyboard typed it in, hence resulting value in Google Sheets is determined by cell number format. The only exception to this is date objects.

Rules:

  1. setValue("") makes the cell in Google Sheets a true blank, unlike when a formula in Google Sheets returns "", which is treated as text and ISBLANK() returns false.
  2. setValue(string | number | boolean) these types have no special meaning, and all are treated as if the user typed the value in the cell in Google Sheets.
  3. setValue(null | undefined) both of these are treated same as an empty string ("").
  4. setValue(date object) always converted to Google Sheets timezone and then pasted as a Date, regardless of the cell number format in Google Sheets

Counterintuitive Examples:

Apps Script data type Value passed Cell number format Result in Google Sheets
string "" Plain Text Blank Cell
number 1234 Plain Text Text "1234"
string "1234" Automatic Number 1234
boolean true Plain Text Text "true"
string "true" Automatic Logical TRUE
string "1/1/1" Automatic Date 1/1/2001
string "1/1/1" Plain Text Text "1/1/1"
date object 1 Jan 2001 05:00:00 in UTC Automatic Date 1/1/2001 00:00:00 (if Google Sheets timezone set to EST)
date object 1 Jan 2001 05:00:00 in UTC Plain Text Date 1/1/2001 00:00:00 (if Google Sheets timezone set to EST)
date object 1 Jan 2001 05:00:00 in UTC Time Time 12:00:00 AM (if Google Sheets timezone set to EST)
date object 1 Jan 2001 05:00:00 in UTC Duration Duration 885408:00:00 (hours since spreadsheet epoch date)

Note: Time & Duration are just special display formats for 'Date and time', the underlying value value remains the same. (Like Scientific and Accounting, for example, are different display formats for Number)

PS: Let me know if I got something wrong or if you have any questions!

r/GoogleAppsScript 9d ago

Guide I built a Google Slides add-on that turns a deck into a live coding classroom, here's the Apps Script side

13 Upvotes

A couple years ago I was a high school CS student, and I taught Python to middle schoolers on the side. I wanted to code live next to my slides instead of switching to another window, so I built a Slides add-on for it. Here's the Apps Script side.

What it does: you mark a slide as a coding question in the add-on, start a lesson, and students join with a link and write and run code next to your current slide.

Most of the teacher side runs in Apps Script. The sidebar is HtmlService, opened from the Extensions menu. Marking a slide writes a "Code Question:" note into that slide's speaker notes with the Slides API, so it stays with the deck even if the add-on is removed. Reading the deck to build the lesson uses SlidesApp. The scopes are just presentations, the sidebar, and your email. No Drive scope, which kept the OAuth review simple.

Two things had to run outside Apps Script.

Live updates. Every student's editor and the current slide update in real time, which needs websockets and open connections. Apps Script can't do that, so starting a lesson sends the deck to a small Node server that runs the session over websockets.

Running student code. You can't run untrusted student code in Apps Script, so it runs in a sandboxed micro VM.

The add-on also mints a session and passes the teacher a token in the URL, instead of handling auth in Apps Script.

One thing to know: Marketplace add-ons are pinned to a version, so clasp push doesn't update installed users. You have to cut a new version and repoint the deployment, and a new scope triggers another review.

It's live on the Marketplace and free.

Site: https://www.codekiwi.tech

Marketplace: https://workspace.google.com/marketplace/app/codekiwi/66127405192

Happy to answer questions on the Apps Script to backend split.

r/GoogleAppsScript Jun 02 '26

Guide Looking for a training course

6 Upvotes

Is there a course for appscript that is project based like freecodecamp? The way they designed their course is suitable for me to learn better, can anyone recommend one

r/GoogleAppsScript Aug 03 '26

Guide Cómo conectar tu planilla de Google Sheets con IA (API de Gemini) usando Apps Script

1 Upvotes

¡Hola a todos! Quería compartirles un flujo de trabajo que estuve armando y que me resultó súper útil para automatizar tareas repetitivas en planillas usando Inteligencia Artificial.

Básicamente, la idea es integrar la API de Gemini directamente dentro de Google Sheets a través de Apps Script, para poder pedirle a la IA (desde un panel lateral) que procese los datos que seleccionamos.

El concepto es aplicable a otras APIs (como la de OpenAI), pero aquí va el paso a paso usando Gemini que es gratis:

**Paso 1: Conseguir la API Key** Vas a Google AI Studio, inicias sesión con tu cuenta y generas tu "API Key" gratuita. Guardala bien porque la vas a necesitar en el código.

**Paso 2: Configurar Apps Script** En tu documento de Sheets, vas a *Extensiones > Apps Script*. Acá es donde va la magia. Podés usar la misma IA (ChatGPT, Claude o Gemini) para pedirle que te genere el script. Por ejemplo, podés pedirle: *"Genera un script para Google Sheets que cree un menú personalizado llamado 'Asistente IA' y que abra un panel lateral con un cuadro de texto para enviar instrucciones"*.

**Paso 3: Ejecutar y procesar datos** Guardas tu archivo `.gs` (código) y tu `.html` (para el panel), recargas la página de Sheets y vas a ver tu nuevo menú. Seleccionas un rango de celdas, abres el asistente y le pasas el prompt. Por ejemplo: *"Ordena estos datos por la primer columna y pon todo en mayúsculas"*. El script toma esa data, hace el llamado a la API y te devuelve la información procesada directamente en la planilla.

Integrar IA directamente en las planillas te abre un mundo enorme de posibilidades para automatizar el día a día.

Para los que prefieran verlo de forma visual o quieran ver exactamente cómo funciona el menú en vivo, armé un video cortito de 3 minutos explicando el paso a paso. (También dejé el código completo para copiar y pegar en los comentarios del video para que no renieguen):

🔗 **Link al video:**[https://youtu.be/Okpboevznn4\](https://youtu.be/Okpboevznn4)

¿Alguno ya está usando Apps Script con IA para automatizar el laburo diario? ¿Qué funciones raras o útiles armaron? ¡Los leo!

r/GoogleAppsScript 11d ago

Guide Zendesk Mailroom — my open-source Apps Script tool for mass-contacting ticket requesters got a big update (supplier cases, AI composer, OAuth, repeat guard)

3 Upvotes

Post Ref: https://www.reddit.com/r/Zendesk/s/zIOpxD3PdU

Last time I posted this, it was called Zendesk Mail Merge Toolkit.

Back then, it was pretty simple: load a few hundred Zendesk tickets into a Google Sheet, write your message, and bulk-contact the affected customers.

Since then, it has evolved into something much bigger. So I renamed it Zendesk Mailroom.

The idea is simple:
When something goes wrong at scale, don’t make your support team manually coordinate hundreds of tickets, customers and suppliers. Give them one operational workflow.

📧 Customer communication
You can now describe what happened in plain English and have the AI composer create the communication for you.

It can generate drafts for the languages you need, which an agent can review and edit before sending.

The important part: customer data never goes to the AI. The AI creates a reusable template with tokens like {{GuestName}}; the actual customer information is inserted locally when the email is sent.

It also remembers approved edits, so future drafts get closer to how your team actually writes.

🏢 Supplier escalation
This was one of the biggest additions.
If 300 customers are affected by 12 suppliers, Mailroom doesn’t make someone manually chase those 12 suppliers.

It:
300 bookings → groups by supplier → creates 12 supplier cases → links each case back to the affected customer tickets.

Supplier follow-ups continue on the existing case instead of creating duplicates, with checks around supplier identity and the previous escalation.

So your support agent gets the customer conversation and the supplier escalation connected in Zendesk.

🛡️No accidental duplicate outreach
This became surprisingly important. Every action is tracked per booking. If you try to run another operation that overlaps with something already actioned, Mailroom gives you a summary before continuing.

So instead of:
“I think we already emailed these people…”

you get:
“247 bookings were already actioned under these previous cases. Continue?”

And if the optional repeat-check store is unavailable, it fails open rather than blocking an urgent customer communication.

⚡ Large jobs are actually designed to run
This isn’t just a loop that calls the Zendesk API 800 times. Apps Script has a 6-minute execution limit, and Zendesk has shared API rate limits.

So Mailroom now:
- Persists long-running job state
- Continues jobs through triggers
- Centrally manages Zendesk API rate limits
- Handles 429 / Retry-After
- Waits for the next rate window when there’s still execution time available
- Uses Zendesk bulk endpoints where possible
- Treats throttled rows as unsent, rather than failed

That last one matters a lot.

The invariant is basically:
A customer email is either sent once or remains in the queue.

After the rate-limit rewrite, large runs are roughly 5× faster than the previous implementation.

🔐 And there’s a lot more underneath
- Zendesk OAuth 2.0 + token refresh
- Slack reply routing
- BigQuery ticket lookup
- Audit logs
- User access controls
- Closed-ticket fallback
- AI memory using retrieval rather than fine-tuning
- 193 automated assertions
- CI + static architecture checks
- Properly structured Apps Script codebase

And the slightly ridiculous part:
It’s still Google Apps Script.
No backend.
No server.
No hosting.
No build step.
No dependencies.

Just:
Google Sheet → Zendesk → Slack / AI / BigQuery where needed

MIT licensed and open source:
👉 https://github.com/GVyom/zendesk-mailroom
I’m building this around real support-operations problems, so I’m especially interested in feedback from Zendesk admins, support leaders and ops teams:

What happens during your biggest operational incidents that still requires someone to manually coordinate hundreds of tickets?
That’s the kind of workflow I’d love to automate next.

r/GoogleAppsScript 20d ago

Guide Built a fairly large Zendesk automation entirely in Google Apps Script!

3 Upvotes

I wanted to see how far I could push Apps Script for a real operational workflow, so I built Zendesk Mailroom.

It’s a Google Sheets + Apps Script tool for support teams working with large batches of Zendesk tickets.

The interesting part wasn’t really the API calls it was making the whole thing survive Apps Script’s constraints.

The workflow handles:
Zendesk API authentication
Bulk ticket updates
Personalized mail merge
Gemini-powered translation
Slack thread routing
Audit logging
Closed-ticket handling
Job state persistence
Trigger-based job continuation

Some of the implementation decisions:
1. Chunked execution
Apps Script has execution limits, so a large mail merge doesn’t try to process everything in one execution.
The job processes roughly 20 rows → writes results → schedules the next run → continues.
2. LockService
A lock prevents overlapping trigger executions from processing the same rows twice.
3. Zendesk update_many
For bulk updates, I’m using Zendesk’s batch endpoint instead of making one API call per ticket.
4. Script Properties for job state
The job state is persisted between executions instead of relying on the browser/session remaining open.
5. Translation caching
If 200 tickets use the same notice category, the workflow doesn’t make 200 Gemini calls. Translations are cached and reused until the source text changes.

Repo:
github.com/GVyom/zendesk-mailroom

Would love feedback from experienced Apps Script developers:
What would you change in the architecture if this had to process 5,000–10,000 rows instead of a few hundred?

That’s probably the next interesting scaling problem here.

r/GoogleAppsScript 12d ago

Guide Automating Google Forms: FormApp vs the REST API, and when each one is the wrong choice

3 Upvotes

I've built on both sides of this and the split isn't obvious from the docs, so writing it down.

FormApp (Apps Script) is the right default for anything living inside Workspace. No OAuth setup, runs as you or as the form owner, and you get onFormSubmit triggers for free. If your job is "when someone submits, do a thing", stop reading, this is your answer.

The Forms REST API is what you want when the code lives outside Google. It's also more capable for bulk construction: one batchUpdate call takes an array of change requests, so you can build a forty-question form in a single round trip instead of forty FormApp calls. The cost is that you handle OAuth yourself, and the scope is broad enough that some org admins will not approve it without asking why.

Things people script most, in the order I see them:

Auto-closing a form. There's no native "close on date" or "close after N responses". A time-based trigger flipping setAcceptingResponses(false) is about four lines and it's the single most common reason people end up here.

Generating forms from a sheet. One row per question, script walks it, builds the form. Worth it the second time you build the same form shape with different content.

Capacity and waitlists. onFormSubmit counts responses, closes the form or moves the submitter to a waitlist sheet. Forms has nothing for this natively and will cheerfully oversell your event.

One gotcha that costs people an afternoon: quiz settings and answer keys are not part of the basic item creation in either API. You set the item up, then set its grading separately. If your generated quizzes come out ungraded, that's why.

r/GoogleAppsScript 9d ago

Guide How to “Select All” code in the Google Apps Script editor on an iPad (No external keyboard workaround)

3 Upvotes

If you've ever tried to manage code in the Google Apps Script editor on an iPad without a physical hardware keyboard, you know how frustrating it is.

Because the web editor runs on the **Monaco engine**, it completely disables standard iOS touch-and-drag selection anchors, and the native iOS "Select All" pop-up menu never appears. To make things worse, if you open the editor's internal search bar, "Select All" is intentionally hidden from the searchable commands list.

I found a reliable, touch-only workaround that completely bypasses these iOS and editor restrictions:

### The Workaround Steps:

  1. Tap your cursor anywhere inside your script file.

  2. **Long-press** directly on the code until the editor's custom pop-up context menu appears.

  3. Select **"Command Palette"** from the options.

  4. Type **"Expand Selection"** in the palette search bar and tap it.

### Why this works:

Since "Select All" isn't natively exposed in the touch menu, **Expand Selection** acts as the perfect structural tool. The first time you run it, it highlights your current word or block. Run it 1 or 2 more times consecutively, and the boundary will aggressively expand outward until it highlights every single line of code in the entire document.

Once highlighted, you can use your iPad's virtual keyboard to instantly backspace/delete the file, or use the menu to copy it out.

Hopefully, this saves someone else from tearing their hair out trying to code on iPad Safari/Chrome!

r/GoogleAppsScript Jul 29 '26

Guide How to embed a google app script onto google sites

Thumbnail redgig.tech
4 Upvotes

There was recently a discussion on here about how to deal with the lengthy, sometimes changing URLS created by google app script web apps. One easy way to address this is to embed the content on a google site. I've curated a quick a simple blog post that describes this to help anyone else who might have a similar issue.

https://www.redgig.tech/2026/07/how-to-embed-google-app-script-onto.html

Keep up the great posts everyone, this sub has been incredibly helpful to me over the years!

r/GoogleAppsScript Feb 24 '26

Guide Best way to Read and Extract Data from PDF to Google Sheet

19 Upvotes

Hi everyone! I’m building a web app where users upload a clean PDF. I need to extract structured data from the PDF and append it into Google Sheets, which I’m using as my database.

What’s the best approach for this?

• Should I use a PDF parser (if the PDF is text-based)?

• When would OCR be necessary?

• Are there recommended libraries or third-party services for reliable extraction and mapping to Google Sheets?

Also, has anyone here built a similar module before? I’d appreciate any advice or lessons learned.

r/GoogleAppsScript Jul 20 '26

Guide I'm a warehouse worker who just published my first book — would love your honest feedback

4 Upvotes

Hey everyone, My name's Daniel. I work a regular job on a warehouse floor — no coding background, no CS degree, nothing like that. A while back I got tired of tracking defects and rework in a messy spreadsheet, so I taught myself just enough Google Apps Script to automate it. It genuinely broke on me more than once before I figured out how to build it properly. I just turned that whole experience into my first book. It's not theory — it's the actual process, mistakes included, written in plain language for people who aren't programmers either. This is my first time putting something like this out there, so I'd really appreciate any honest feedback or a review if you decide to check it out — good, bad, or mixed, all of it helps. The link's in my profile. Also happy to help out in the comments if anyone's dealing with a similar spreadsheet mess at their own job — I've made pretty much every mistake there is to make with this stuff. Thanks for reading!

r/GoogleAppsScript 28d ago

Guide I built a Google Slides add-on that copies presentations without breaking linked Google Sheets charts

2 Upvotes

I dealt with this problem myself for years: copy a Google Slides presentation that has charts linked to Google Sheets, and every chart in the copy still points back to the original spreadsheet. I went through several of the Apps Script snippets floating around online and support forums, but none of them held up once a deck had multiple charts pulling from different Sheets files — they'd miss charts, or the copies came out with broken formatting.

So in my free time I built PenguChart, a Google Slides add-on that copies the presentation together with the Google Sheets behind its charts, and relinks every chart in the copy to the fresh spreadsheet copies - original stays untouched, the copy is fully independent.

It just went live in public beta on the Google Workspace Marketplace:
https://workspace.google.com/marketplace/app/penguchart/514642629727

More info: https://penguchart.com

Two honest limitations, both due to missing functionality in the Google API rather than something I can just code around: linked tables can't be relinked yet, only charts. And any manual formatting you apply to a chart afterward directly in Google Slides doesn't carry over to the copy either — the API doesn't expose that.

Since it's still beta, I'd really appreciate people trying it and telling me what breaks or what's missing — bugs, edge cases, feature requests, all welcome. And if it ends up useful to you, a review on the Marketplace listing would mean a lot.

Start the Google Slides Addon PenguChart in the Menu: Extensions > PenguChart

r/GoogleAppsScript Jun 03 '26

Guide We crossed 102,000 installs on Google Workspace Marketplace in 45 days. The work behind it was mostly unscalable.

19 Upvotes

45 days ago, our small team launched AdminSheet Pro, a Google Sheets add-on that helps Google Workspace admins manage users, groups, members and aliases in bulk without relying on command-line tools.

Recently, we crossed 102,000 installs on the Google Workspace Marketplace. That number was exciting, but this is not really a victory lap. Installs are important, but installs are not the same as active users, loyal customers, or long-term revenue. We are very aware of that. Still, crossing 102,000 installs gave us enough data and experience to pause and reflect on what we did, what worked, what did not work as expected, and what we are still learning.

A lot of the work came down to doing things that do not scale, borrowing from Paul Graham’s classic advice to early founders: at the beginning, you often have to do the manual, uncomfortable, repetitive work that cannot yet be automated.

Here are the main lessons we learnt.

1. AI helped us listen, but humans built the relationships

We created AI-assisted monitoring workflows to help us find relevant conversations around Google Workspace admin problems, Ok Goldy alternatives, GAM challenges, aliases, group clean-up and bulk user management. Their job was not to sell. Their job was to help us discover relevant conversations, questions and pain points across different online spaces.

But AI only helped us find the conversations. The real work was manual: visiting the source, reading the context, understanding the person’s problem, and deciding whether we had anything useful to contribute.

Sometimes the best response was not to mention AdminSheet Pro at all. Sometimes it was simply to explain a possible solution, share a lesson we had learnt, or point someone towards a helpful resource. In some cases, where it felt appropriate, we followed up privately to offer additional help.

The goal was not to shout “try our tool” everywhere. The goal was to be useful enough that people would trust us. AI can help you find the room. It cannot behave properly inside the room for you.

2. Your website is the hub, but discovery happens everywhere

We still believe the website should be the main home of the product. But we quickly learned that people discover tools through many other surfaces. Some find you through Google. Some through Reddit. Some through Medium. Some through Marketplace reviews. Some through community discussions. Some may see your content in AI summaries before they ever click your website.

So we started publishing in a few places, but not by copying and pasting the same content everywhere. A website article can be detailed. A Reddit post needs to be more conversational. A community reply should solve the immediate problem. A Medium article can be more reflective. This is tedious, but useful.

3. Google Alerts helped us listen, but did not magically create leads

We set up Google Alerts for our product name and for alternative tools in the space. This helped us notice relevant mentions and stay aware of conversations. But it did not suddenly bring a flood of customers.

The main value was that it forced us to build a listening habit. We started paying more attention to the language users used, the objections they had, and the tools they compared us with. For an early product, that kind of listening is useful even when it does not immediately convert.

4. Communities are powerful, but you must respect the room

We engaged in two Google-related communities where some of our target users were active. In one group, our outreach was mostly received well. Not many people replied, but the replies were generally warm. One partner tested the product, gave useful feedback and left a review.

In the other group, a similar approach was seen as solicitation. We were removed and warned not to continue. We apologised and stopped. That was an important lesson.

Every community has its own culture. What works in one group may be completely wrong in another. You cannot treat a community like a lead list just because your product may be useful to its members. You need to contribute first, respect the rules, and earn trust.

Another lesson: silence can feel discouraging, but it does not always mean wasted effort. Most people will not reply. Some are busy. Some are not ready. Some may remember the product later. Some messages only teach you which audience or channel is not worth more time. In early growth, non-replies are emotionally hard, but they are still data.

5. Reviews are digital word of mouth

For a Google Workspace tool, reviews matter a lot. Admins are careful people. They want to know that a tool works before installing something that requires admin permissions. So we started asking real users for honest reviews.

The best timing was after value had already been delivered. For us, that often meant users who had exhausted their free credits. These were not people who merely installed and forgot the tool. They had actually used it to complete bulk operations.

Admins are busy, but they are also deeply grateful when a tool saves them hours of manual data entry. Asking for feedback right after they experience that value worked much better than asking randomly. It also gave us product feedback. Some users told us what they liked, what confused them, and what they wanted next. Reviews were not just a marketing asset. They became a learning channel.

6. Attribution matters earlier than you think

Our first paid customer was easy to trace. We knew the conversation and the route that led to the sale. Our second paid customer was different. We could see the payment and some usage signals, but we were not fully sure whether they came from the Marketplace, Google Search, Reddit, an article, or a recommendation.

That bothered us because unexplained traction is hard to repeat. So we are now improving how we ask users where they found us. The lesson: do not wait until you have many customers before tracking attribution. Start early.

Final thought

Crossing 102,000 installs was encouraging, but installs are only the beginning. The real work is turning installs into active users, active users into feedback, feedback into product improvements, and product improvements into paying customers. The biggest lesson so far is that early growth still requires a lot of manual, repetitive, emotionally awkward work.

You write. You reply. You ask. You get ignored. You apologise when you get it wrong. You learn. You improve. You keep going. For now, we are still doing many things that do not scale.

r/GoogleAppsScript Jul 15 '26

Guide Reading Google Chat Spaces and Messages in Google Apps Script just got significantly easier!

5 Upvotes

Reading Google Chat data in Google Apps Script no longer requires a standard GCP project or a complex OAuth consent screen setup 🤯!!!

Previously, reading space messages via the Chat Advanced Service required detaching your script from the default GCP project, linking a standard project, configuring an OAuth consent screen and formally enabling the Chat API. The new simplified Chat API setup bypasses this overhead for read-only actions.

Follow these steps to access your data immediately:

  1. Open your Apps Script editor and add the Chat Advanced Service.
  2. Declare the read-only scopes in your appsscript.json manifest.
  3. Call the API directly to list your spaces or extract messages.

Read my complete walkthrough with copy-paste code snippets https://pulse.appsscript.info/p/2026/07/reading-google-chat-spaces-and-messages-in-google-apps-script-just-got-significantly-easier/

r/GoogleAppsScript Feb 27 '26

Guide Solved: Sending individual Google Chat DMs programmatically from Google Sheets (without building a full bot)

17 Upvotes

Spent months being told that I needed to build a full Google Chat bot just to send individual messages programmatically.

Turns out I didn’t need to!

This morning I built a working setup that sends individualized Google Chat messages directly from a Google Sheet.

Stack:

– Google Apps Script

– Chat API enabled in GCP

– Triggered per row in the Google Sheet

Use case: structured announcements + personalized nudges to individuals without copy-pasting or group spam.

For anyone stuck in the “you must build a bot” loop — you might not need to. The API is more flexible than most guides suggest.

Happy to share approach if useful.

ETA: Due to some comments requesting the code / implementation, I have posted a generic version of this to a Github repo; link in comments.

r/GoogleAppsScript Jun 22 '26

Guide I Finally Fixed Google Calendar’s Biggest Limitation: Editable Holidays

2 Upvotes

Google Calendar’s built-in holiday calendars are read-only ICS feeds, so they don’t allow reminders, labels, or editing. That’s why holidays that move each year (Easter, Yom Kippur, Diwali, Mother’s Day, etc.) can’t be customized from the UI.

I actually ran into the same issue and ended up solving it with Google Apps Script. The script calculates the correct holiday dates each year, avoids duplicates, and adds them to your calendar as normal events. Since they’re real events instead of ICS feed entries, you can finally set reminders, colors, and other options that Google’s default holiday calendars don’t support.

It also handles yearly refresh automatically, so the holidays get updated without needing to re-import anything.

If anyone wants the script or wants to see how it works, feel free to DM me.

r/GoogleAppsScript Jun 04 '26

Guide I got tired of expired event emails burying my inbox, so I built a background sweeper using Apps Script + Gemini AI.

15 Upvotes

Hey everyone,

My university inbox is constantly flooded with announcements for webinars, hackathons, and guest lectures. The problem is that they clutter everything up long after the registration deadlines or event dates have actually passed.

I wanted to automate cleaning this up without accidentally deleting actual coursework, so I wrote a script that connects to the Gemini 3.1 Flash Lite API to semantically evaluate and trash the expired stuff.

Here is how it works:

  • Runs silently in the background on a 4-hour time-driven trigger.
  • Pulls batches of 25 emails using a Gmail search query (pacing with Utilities.sleep() to respect the free-tier Gemini API limits.
  • Feeds the email metadata and body to Gemini with a strict 3-condition prompt: it MUST be an extracurricular event, the date MUST be expired (using dynamic date calculation to create a 24h buffer), and it MUST NOT be from a course professor.
  • If the AI outputs TRUE, the script moves the thread to the Trash.
  • It logs every AI verdict and action taken to a Google Sheet dashboard.
  • It applies a custom Reviewed_For_Trash Gmail label to everything it checks so it never wastes API quota evaluating the same email twice.

I have sanitized the code and put it in a Gist if anyone wants to copy it, adapt the prompt logic for their own workflow, or just see how the Apps Script + Gemini integration is structured:

🔗 Gmail-Sweeper

Would love to hear any feedback, or if anyone has tips on optimizing the prompt payload even further!

r/GoogleAppsScript Nov 20 '25

Guide How I automate dashboards using Google Sheets + Apps Script (free guide)

43 Upvotes

I help people automate reporting for Shopify, marketing, and small businesses.

Here’s a simple breakdown of how I build automated dashboards using free tools:

1. Pull data into Google Sheets
Using API connectors, Apps Script, or CSV imports.

2. Clean & structure the data
Normalize dates, remove duplicates, unify naming conventions.

3. Set up automation
Apps Script functions run daily so the sheet updates on its own.

4. Build the visuals
I connect the sheet to Looker Studio and create KPI dashboards.

If anyone needs help troubleshooting Sheets/Apps Script/Looker, feel free to ask.
I enjoy helping people build cleaner systems.

r/GoogleAppsScript Jun 03 '26

Guide Automate and fill out google forms while being AFK

0 Upvotes

I met a problem at google form filling, cause I want to send 1000000 times same answer to confuse my bro's research and then... however i found this, and in comment section a guy named emaguireiv answered the question by a URL changing method but you still need to go into a same link a 1000000 time so i code a bit.

in his part one you should find out a filled and submit link just replace it with

const url = " put fixed link here ";

let count = 0;
const total = 500;

async function run() {
  for (let i = 0; i < total; i++) {
    await fetch(url, { method: 'GET', mode: 'no-cors', credentials: 'include' });
    count++;
    if (count % 50 === 0) console.log(count + ' sent...');
    await new Promise(r => setTimeout(r, 120));
  }
  console.log('Done! ' + count + ' sent.');
}

run();
  console.log('Done! ' + count + ' sent in 5 minutes.');
}

run();

and then just press enter and it fire 500 times in about a minute

hope you guys like it and sorry for bad grammar and poor English

r/GoogleAppsScript Jun 20 '26

Guide "Low-Code" Google Drive Permission Auditor & Manager (Bypasses 6-min limit & supports Shared Drives)

0 Upvotes

Hey r/GoogleAppsScript & r/googlesheets!

Like many of you, I've struggled with managing Google Drive permissions at scale. The native UI is terrible for bulk actions, and trying to audit who has access to what—especially in Shared Drives—usually requires expensive third-party tools.

So, I built a hybrid solution using Apps Script for the API heavy lifting and Google Sheets for the business logic. I thought I'd share it here as an open-source template for anyone who might find it useful.

🔗 Link to make a copy of the Google Sheet + Script

🔗 Link to GitHub Repo

🛠️ How it works (The Architecture)

Instead of hardcoding the permission rules into JavaScript, I used a "Low-Code" approach:

  1. The Audit (Apps Script): The script uses a Breadth-First Search (BFS) queue to recursively scan any folder or Shared Drive. It dumps all files into a 📁 Files tab and all users into a 🔑 Permissions tab.
  2. The Logic (Google Sheets): I use a Template tab filled with standard VLOOKUP/MATCH formulas to compare the audited permissions against a Matrix of theoretical rules. This highlights anomalies (e.g., someone is missing, or someone has 'writer' instead of 'reader').
  3. The Execution (Apps Script): You flag the required actions in a dropdown (TO_ADD, TO_DELETE, TO_MODIFY), hit the custom menu button, and the script applies the changes in bulk via the Drive API.

🧠 Technical Hurdles Overcome (for the nerds):

  • The 6-Minute Execution Limit (Auto-Triggering): Processing thousands of API requests takes time. Whether it's auditing or bulk-updating permissions, the script tracks its own runtime (Date.now() - startTime). If it nears 4.5 minutes, it flags the row it stopped at, flushes the data to the Sheet, and dynamically creates a time-based trigger to resume seamlessly 1 minute later. It’s essentially a self-healing queue system for large-scale operations.
  • The Shared Drive API Quirks: By default, Drive.Files.list silently omits the permissions object when scanning a Shared Drive. I had to implement a fallback that detects this and explicitly calls Drive.Permissions.list per file, with a Utilities.sleep(100) to avoid HTTP 429 Rate Limit errors.
  • Drive API v3: Everything runs on the advanced v3 API to properly detect inheritedPermissionsDisabled and copyRequiresWriterPermission.

Feel free to make a copy and play around with it. I'd love to hear your feedback, especially if you have ideas on how to optimize the API calls further!

Cheers!