{"id":24529467,"url":"https://github.com/sangnandar/apps-script-management","last_synced_at":"2025-03-15T17:47:11.933Z","repository":{"id":272157327,"uuid":"915685470","full_name":"sangnandar/Apps-Script-Management","owner":"sangnandar","description":"This Google Apps Script solution simplifies managing Apps Script projects for multiple clients. This solution is especially useful for scenarios where you provide Apps Script solutions to clients.","archived":false,"fork":false,"pushed_at":"2025-02-25T00:12:40.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-25T01:20:22.901Z","etag":null,"topics":["google-apps-script"],"latest_commit_sha":null,"homepage":"https://script.google.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sangnandar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-12T14:37:39.000Z","updated_at":"2025-02-25T00:12:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"50da6467-d11c-4e91-aedc-32a1101ffa59","html_url":"https://github.com/sangnandar/Apps-Script-Management","commit_stats":null,"previous_names":["sangnandar/apps-script-management"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FApps-Script-Management","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FApps-Script-Management/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FApps-Script-Management/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sangnandar%2FApps-Script-Management/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sangnandar","download_url":"https://codeload.github.com/sangnandar/Apps-Script-Management/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243769950,"owners_count":20345215,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google-apps-script"],"created_at":"2025-01-22T07:37:35.338Z","updated_at":"2025-03-15T17:47:11.926Z","avatar_url":"https://github.com/sangnandar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Apps Script Management\n\n## Overview\nThis Google Apps Script solution simplifies managing Apps Script projects for multiple clients. This solution is especially useful for scenarios where you provide Apps Script solutions to clients. When you update the script in master file, changes can be propagated to all clients with a single click.\n\nThis project uses Google Sheets as an example of a master file. To work with other file types, change `mimeType` in `createNew` function.\n\n### Key features\n- **Create client file:** Generate client-specific files based on a master template.\n- **Manage updates:** Propagate script updates from the master file to all client files.\n\n## How it works\n1. Master file is the template. Master script is Apps Script bound to master file.\n2. The Apps Script:\n    - When create new client:\n      - Create a new file and share it to client as editor.\n      - Create a new apps script project and binds it to the newly created file.\n      - Copy sheets from master file to client's file.\n      - Copy scripts from master script to client's file.\n    - When update client's file:\n      - Propagates latest-script from master script to client's file (all clients or selected clients).\n    - When delete client's file:\n      - Delete client's file (all clients or selected clients).\n\n## Installation\n\n### GCP Project configuration\nEnable the following API in your GCP project:\n- Apps Script API.\n\n### Apps Script configuration\n- Turn on **Google Apps Script API** at [Apps Script -\u003e Settings](https://script.google.com/home/usersettings).\n- Link Apps Script to GCP Project at **Apps Script -\u003e Project Settings -\u003e Google Cloud Platform (GCP) Project**.\n- Set up Script Properties in **Apps Script -\u003e Project Settings -\u003e Script Properties**:\n   ```\n   {\n     FOLDER_ID: \u003cwhere the copied file go\u003e,\n     MASTER_FILE_ID: \u003cfile to be copied\u003e,\n     MASTER_SCRIPT_ID: \u003capps script bound to the master file\u003e\n   }\n   ```\n- Configure the `appsscript.json` file:\n   ```json\n  {\n    \"dependencies\": {\n      \"enabledAdvancedServices\": [\n        {\n          \"userSymbol\": \"Drive\",\n          \"version\": \"v3\",\n          \"serviceId\": \"drive\"\n        }\n      ]\n    },\n    \"oauthScopes\": [\n      \"https://www.googleapis.com/auth/spreadsheets\",\n      \"https://www.googleapis.com/auth/script.external_request\",\n      \"https://www.googleapis.com/auth/script.projects\",\n      \"https://www.googleapis.com/auth/drive\"\n    ]\n  }\n  ```\n\n### Sheets configuration\n**DO NOT** change sheets name, delete columns, or re-arrange columns for the following ranges:\n- Read\n  ```\n  'Updater'!A2:E\n  ```\n- Write\n  ```\n  'Updater'!A2:E\n  ```\n\nSheets layout:\n\n![image](https://github.com/user-attachments/assets/1fe96c11-4c9e-4692-9875-ea126a97a240)\n\n## Usage\n1. Access the **Custom Menu** located in the toolbar.\n    - **Custom Menu -\u003e Create new:** create new client's file.\n    - **Custom Menu -\u003e Update:** propagates latest-script from master file to client's file.\n    - **Custom Menu -\u003e Delete:** delete client and their related file.\n2. When **Create new** Col-A and Col-B should NOT empty, while Col-C and Col-D should empty.\n3. Strikethrough in Col-B means email address cannot be associated with a google account, meaning: files (docs, sheets, etc) cannot be shared to that email address.\n\n## Caveats\nAt the current state, there are no functions/methods to get *ScriptID* from *SpreadsheetID*. The feature has been requested [here](https://issuetracker.google.com/issues/111149037). To workaround this the script has to call APIs back-and-forth between Sheets and Projects. This caused the script consumes ~20s to create new file for each client. Under normal circumstances this shouldn't be a problem. If you need to add hundreds of new clients daily, consider revising the `createNew` function to execute tasks in parallel using `UrlFetchApp.fetchAll()`. See [this example workflow](https://github.com/sangnandar/Load-CSVs-from-GCS-to-BigQuery).\n\nUpdate client's file already run in paralel.\n\n## Future enchancements\n- For scenario where provided solution has webapp deployment, include re-deployment after committing update.\n- For scenario where each client has unique variables, include `PropertiesService` setup using `scripts.run` method.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsangnandar%2Fapps-script-management","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsangnandar%2Fapps-script-management","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsangnandar%2Fapps-script-management/lists"}