Is it possible to add an existing app script to a newly created googlesheet using app script? And automatically assigning it to a trigger?
For example I have a spreadsheet call spreedsheetA. Then my form will create spreedsheetB, is it possible to automatically add my app script to spreedsheetA to spreedsheetB with out copy + pasting it manually. All by using the appscript in my form.
As a workaround to what #Tanaike proposed you can use the Drive API to make the copy. Because bounded scripts are also copied when you perform a makeCopy() operation.
Steps:
Create a new sheet and add a bounded script via Extensions > Apss Script. Take note of the ID, in the example I will call it SSA_ID
Add your script. As probe of concept I just added this simple one:
function onOpen(e) {
SpreadsheetApp
.getUi().alert('Hi from bounded script')
}
Create a new script, and paste this code inside:
function copySpreadSheet() {
const file = DriveApp.getFileById(SSA_ID)
const newFile = file.makeCopy(`SpreadSheetCopy_${new Date().toISOString()}`)
Logger.log(newFile.getUrl())
}
Run the script, grab the url and copy paste it in your browser. You will see that it contains a copy of the bounded script.
From there you can manipulate the copy and add it to an Installable Trigger, for example:
ScriptApp.newTrigger('copySpreadSheet')
.timeBased()
.everyHours(6)
.create();
Documentation:
newTrigger(functionName)
ClockTriggerBuilder
Related
I have a spreadsheet that I share with other people trough a link to make a copy.
In that spreadsheet I have a script and I don't want that other people can see my script.
To protect my script from this spreadsheet I moved it to a standalone spreadsheet.
In my spreadsheet I use a Trigger.
My standalone script starts with:
function onEdit(e) {
...
This script changes some cells when cell G13 changes.
My script in my spreadsheet is:
function createSpreadsheetOpenTrigger() {
const ss = SpreadsheetApp.openById("1Ik3ywr00UIQH9lwvEPYI1wi6xVpBDN8QVtZabtG96gY");
ScriptApp.newTrigger('onEdit')
.forSpreadsheet(ss)
.onEdit()
.create();
}
If I change cell G13 in my spreadsheet, nothing happens.
What do I do wrong?
Documentation: https://developers.google.com/apps-script/guides/triggers/installable#managing_triggers_programmatically
In your script of createSpreadsheetOpenTrigger() in the container-bound script of Spreadsheet, onEdit is put in a standalone script. In this case, unfortunately, onEdit in the standalone script cannot be run from Spreadsheet. I think that this might be the reason for your current issue.
Pattern 1:
In this pattern, your showing script is modified. I thought that this pattern might be close to your expected situation.
1. Container-bound script side.
In this case, please remove your script from your container-bound script. In this pattern, only a standalone script is used.
Also, in this case, even when Spreadsheet has no container-bound script, this pattern can be used. Only the below standalone script can be used.
2. Standalone script side.
Please modify your standalone script as follows. Please set the spreadsheet ID of your Spreadsheet to spreadsheetId and save the script.
function createSpreadsheetOpenTrigger() {
const spreadsheetId = "###"; // Please set the spreadsheet ID of your Spreadsheet.
const ss = SpreadsheetApp.openById(spreadsheetId);
ScriptApp.newTrigger('installedOnEdit').forSpreadsheet(ss).onEdit().create();
}
// In this pattern, please set your script in this function.
function installedOnEdit(e) {
e.range.setValue(JSON.stringify(e));
}
3. Install OnEdit trigger.
In order to install OnEdit trigger, please run createSpreadsheetOpenTrigger. By this, the OnEdit trigger is installed.
4. Testing.
Please edit the cell in your Spreadsheet. By this, the script of the standalone script is run, and you can see the event object in the edited cell.
And, in this case, the other users cannot see your standalone script. I thought that this might be your expected situation.
Note:
As an important point, it supposes the following sample situation.
User "A" is the owner of Google Spreadsheet.
User "B" has the writer permission for the Spreadsheet of user "A".
Under this condition, when user "A" creates a standalone script including the following script. And, run createSpreadsheetOpenTrigger.
function createSpreadsheetOpenTrigger() {
const spreadsheetId = "###"; // Spreadsheet ID of the owner's spreadsheet.
const ss = SpreadsheetApp.openById(spreadsheetId);
ScriptApp.newTrigger('installedOnEdit').forSpreadsheet(ss).onEdit().create();
}
function installedOnEdit(e) {
e.range.setValue("ok1");
}
And, when user "B" creates a standalone script including the following script. And, run createSpreadsheetOpenTrigger.
function createSpreadsheetOpenTrigger() {
const spreadsheetId = "###"; // Spreadsheet ID of the owner's spreadsheet.
const ss = SpreadsheetApp.openById(spreadsheetId);
ScriptApp.newTrigger('installedOnEdit').forSpreadsheet(ss).onEdit().create();
}
function installedOnEdit(e) {
e.range.offset(0, 1).setValue("ok2");
}
In the above situation, when user "A" or "B" edit a cell of the Spreadsheet, the values of ok1 and ok2 are put into the edited cell and the right side of the edited cell. From this situation, it seems that both script are run to the same Spreadsheet. It is considered that when other users have the write permission, when the above method is used, the edited information can be retrieved.
Pattern 2:
In this pattern, a library is used.
From your situation, if you have both the standalone script and the container-bound script of Spreadsheet, how about using the standalone script as a library? When the standalone script is used as the library and it is loaded on the container-bound script of Spreadsheet, the script of the standalone script can be seen by only you. Other users cannot see it. I thought that this might be your expected situation.
When this is reflected in a sample script, please do the following flow.
1. Prepare a standalone script.
Please copy and paste the following script to the script editor of the standalone script.
function myFunction(e) {
return {message: "From hidden script.", object: e};
}
If you want to hide the script, please write it to this project.
2. Deploy standalone script as a library.
Please deploy the standalone script as a library. You can see the official document at here. In this case, it is not required to share the standalone script. I think that this point is for your goal.
3. Prepare a container-bound script.
Please copy and paste the following script to the script editor of the container-bound script of Spreadsheet. And, please install the library. Ref And, in this sample, please install the library as Lib. By this, the library is used.
And, please install the OnEdit trigger to the function installedOnEdit.
function installedOnEdit(e) {
const res = Lib.myFunction(e);
e.range.setValue(JSON.stringify(res));
}
4. Testing.
Please edit a cell of the Spreadsheet. By this, installedOnEdit is run by the installable OnEdit trigger, and you can see message: "From hidden script." in a cell. And, installedOnEdit uses the script of Lib. And, other users cannot see the library. I thought that this might be your expected situation.
References:
Installable Triggers
Libraries
I've set up a script that essentially copies the contents from a 'template' folder within my google drive and moves the copied contents to a newly created folder elsewhere. The 'Template' folder will always hold 9 individual spreadsheets, each with their own unique bounded script.
The problem I'm having is that every time I copy the spreadsheets over, I have to reauthorise access for each of the 9 scripts before I can start using the functionality I've created.
I'd like to be able to assign or grant permission for the bound script to access the services it needs to during the process I use to copy the spreadsheet to a new location.
Here is an example of the code I use to copy over the spreadsheets. Is there anyway to access the script to assign permissions here?
function copyContents(template_folder, new_folder){
var files = template_folder.getFiles();
while (files.hasNext()) {
var file = files.next();
var file_name = file.getName()
var copied_file = file.makeCopy(file_name,new_folder)
// Assign permissions here...
}
}
It's not possible to grant authorization programmatically as this implies a security risk. The alternative is to publish your bounded scripts as add-ons so you authorize them once and you will be able to use them on any spreadsheet.
Bear in mind that you still should have to enable the addons on each of the documents you want to use them but this usually as simple as having a an onOpen menu that runs with ScriptApp.authMode.NONE
Note: I'm pretty sure that this was already asked and answered on this site.
Similar questions without answers with positive score
Installable onEdit trigger in google spreadsheet script when copying a template spreadsheet script
Google Script Carrying over triggers when copying a spreadsheet
I would like to be able to run a script in another spreadsheet outside of the current spreadsheet I am in.
I tried the below script but the script is not in the current spreadsheet editor
function RunScriptInAnotherSpreadsheet() {
var target = SpreadsheetApp.openById("sheetID");
//runs the below script
relocationtomaster();
}
am I dreaming ?
I understand a trigger would do that in the target sheet - just wanted to do it manually
any help would be appreciated
Publish the main script(with implementation of relocationtomaster) as library. Then add this library as dependency to the script you want this code run.
Function relocationtomaster will be available in context of dependant script.
Example main script(publish as Library)
function relocationtomaster(id){
var ss = SpreadsheetApp.open(id);
Logger.log(ss.getActiveSheet().getDataRange().getValues())
}
Example dependant script(include above script as library)
function run(){
relocationtomaster('1MXsIX_SprLSimqNDUlDkEvWhtQp8Kz0By1IaA5JfkSA'); // Sheet id
}
You can pass spreadsheetid as parameter.
AFAIK you have to publish them as a Library and call it from there, you can have a look here how to run google app script function from another project
Mind that that id could affect to the performance of the script.
Using Google Apps Script, is there a way to have a Google Documents file update automatically whenever a Google Sheets file is edited?
I've got a Google DocumentApp file with a script that gets data from a Google SpreadsheetApp file. I'm looking to create a script to automatically update the DocumentApp file whenever the SpreadsheetApp file is edited.
This is the code I'm using currently:
function updateDocumentOnEditTrigger() {
var ss = SpreadsheetApp.openById(SheetID);
ScriptApp.newTrigger('UpdateDocument')
.forSpreadsheet(ss)
.onEdit()
.create();
}
Running the updateDocumentOnEditTrigger function doesn't seem to trigger the UpdateDocument function, which works as it should when manually run.
Answer:
In order to run a DocumentApp script on edit of a Spreadsheet, the On edit installable trigger attached to the Spreadsheet must be used.
More Information:
As per the Simple Triggers documentation, there are some restrictions which need to be taken into account. In particular:
They can modify the file they are bound to, but cannot access other files because that would require authorization.
As a result, the onEdit(e) trigger function can not be used. There is however an installable trigger which can be created, with settings set up such that it can fire on edit.
Code:
With the following function in the script bound to the Spreadsheet file:
function updateDocument() {
var doc = DocumentApp.openById('DOCUMENT_ID');
// here you can put your code that edits the document in the way you want.
}
You can create an installable trigger which runs on the edit of the Spreadsheet. You will need to run the code at least once before setting up the trigger however - this is because DocumentApp needs authorisation and you need to grant it!
###Setting up an Installable Trigger:
With the code set up, you can create the installable trigger by completing the following steps:
From the Apps Script editor view for the bound Spreadsheet script, follow the path Edit > Current project's triggers. This will open the triggers for the project in a new tab or window.
In the bottom left, click on the + Add Trigger button, bringing up the Add Trigger modal. From here, set up the trigger with the following properties:
Choose which function to run: updateDocument
Choose which deployment should run: Head
Select event source: From spreadsheet
Select event type: On edit
And click Save. This will set up the trigger such that your Document editing function will run each time the Spreadsheet is edited.
References:
Google Apps Script - Simple Triggers
Simple Triggers - Restrictions
Google Apps Script - Installable Triggers
I currently have a Google Sheet that I'm using as a master template. That is, I'm making a copy of this template for every request. I want to add a Google App Script (which onEdit POSTs to my server when the sheeting is completed) to my master template that will be duplicated and run for every copy of this template.
I've tried doing this from an admin account, however, the scripts don't seem to 'stick' with any of the templates. Is this possible?
Installable triggers can be attached to any spreadsheet (respecting sharing permissions) from any project. You can add a new trigger to your master sheets project for each copy that is made. In the second example here they suggest using SpreadsheetApp.openById() you could also use SpreadsheetApp.openByURL() or the Spreadsheet returned by Spreadsheet#copy() depending on how you are duplicating your spreadsheet.
Personally, what I do in 2022 is including something like this on the beginning:
function scriptSetup() {
createOnEditFunction();
}
function createOnEditFunction() {
const ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('onEdit')
.forSpreadsheet(ss)
.onOpen()
.create();
}
function onEdit(e) {
//your stuff here
}
This way, the scriptSetup() is located on the first line so when copying a spreadsheet I would ask them within Sheets to click on Extensions > Apps Script > Run.
As per Jared Pinkham's link referencing Developer documentation, there are a few things Apps Script can use as triggers other than onEdit.
There are several installable triggers for Google Workspace
applications:
An installable open trigger runs when a user opens a spreadsheet,
document, or form that they have permission to edit.
An installable edit trigger runs when a user modifies a value in a
spreadsheet.
An installable change trigger runs when a user modifies the structure
of a spreadsheet itself—for example, by adding a new sheet or removing
a column.
An installable form submit trigger runs when a user responds to a
form. There are two versions of the form-submit trigger, one for
Google Forms itself and one for Sheets if the form submits to a
spreadsheet.
An installable calendar event trigger runs when a user's calendar
events are updated—created, edited, or deleted.
You can refer to the following link for spreadsheet triggers.