How to update code changes automatically in google appscripts - google-apps-script

I am using a tracker for my team to track their progress. At the beginning, I make duplicates of a mastersheet which has a code already in it. But If i want anything to be changed in the code, I will have to manually go to all sheets and make the changes. Is there a work around where I can change the code in all sheet if I change the code in my mastersheet?

Have you looked into libraries? https://developers.google.com/apps-script/guides/libraries
Using these concepts, you could publish a library and give all of those people edit access, then in the original spreadsheet access the library through development mode (or head deployment for the new IDE), and then they can get real-time updates to the code implemented in their script. This is best if it's ok to give edit access to the library to everyone; if it's view access only it's more complicated but still possible. Can provide an edit if you need to give view access.

Answer:
You can make changes to Apps Script code in other files using the projects.updateContent method of the Apps Script API.
More Information:
As per the documentation:
[This method] Updates the content of the specified script project. This content is stored as the HEAD version, and is used when the script is executed as a trigger, in the script editor, in add-on preview mode, or as a web app or Apps Script API in development mode. This clears all the existing files in the project.
In order to update code in other projects you must provide the enire script of all files, and not just the newly updated functions.
The request needs to be to:
PUT https://script.googleapis.com/v1/projects/{scriptId}/content
and the request body takes the form:
{
"files": [
{
"name": string,
"type": enum (FileType),
"source": string,
"lastModifyUser": {
"domain": string,
"email": string,
"name": string,
"photoUrl": string
},
"createTime": string,
"updateTime": string,
"functionSet": {
"values": [
{
"name": string
}
]
}
}
]
}
Remember that you must inclide the appsscript.json manifest file when using this endpoint.
References:
Method: projects.updateContent | Apps Script API | Google Developers

Related

Transfer Ownership of Google Sheets from Service Account to General Account

I created a Google sheet using Google Sheets API which copied the content of spreadsheet present in one of my folder in Google Drive. Even the copied file did contain the code of App Script in it. So the file which was created using service account didn't allowed me to use the code of App Script. It throws the following error as shown in image below:
When I created the copy of this file from front end as shown in image below:
In this case owner was not service account so I was able to use the App Script.
Can any one help me with this?
You can programmatically make a Permissions.List using the service account credentials to make another user the owner of the file (the Spreadsheet in this case, you need its ID), you need to set the transferOwnership attribute to true and use a request body like this:
{
"role": "owner",
"type": "user",
"emailAddress": "new-owner#email.com"
}

Share Google Drive Folder via Zapier with Mailchimp trigger

I can't figure out how to format the "Custom Value for Sharing Preference" on this Zap I'm trying to create that will share a Google Drive folder with my new Mailchimp subscribers.
I've been able to get the File ID using the Drive API, but I'm not sure how to provide the Custom Value that should come from the New Mailchimp Subscriber Email.
If I simply choose the Email address from the Mailchimp dropdown provided by Zapier and test it, I get an error:
We had trouble sending your test through. The app returned "The
permission type field is required.". This usually happens when your
Zap is missing a required field or a field value isn't in a recognized
format.
EDIT: Success via the Google Drive API test.
Using the sandbox available here, I know that I need to:
POST https://www.googleapis.com/drive/v3/files/fileId/permissions
the following Request Body
{
"role": "reader",
"type": "user",
"emailAddress": "email#example.com"
}
I've been able to run that test a few times with Google's sandbox, so I know I can do it. I just don't know how to pull this into Zapier.

BigQuery: No OAuth token with Google Drive scope was found

I'm trying to replace the contents of a Google Sheet with a BigQuery query.
I'm in the Google Sheet and using a script based on these: https://greenido.wordpress.com/2013/12/16/big-query-and-google-spreadsheet-intergration/
Accessing BigQuery with Google Spreadsheet
All the script does is pull the info from a BigQuery query and write it to a Google Sheet. But if I just run the script, I end up getting an error: BigQuery: No OAuth token with Google Drive scope was found
What do I need to do to get this to work?
After a lot of Googling, I found the answer. Apparently, even though I need to give my script the authority to manage not just my Google Sheet, but also the authority to manage my Google Drive.
All I have to do is add a function to make Google ask me for permission for the script to manage my Drive.
Here's the function:
function usingAppsScriptsToken ()}
// we need to provoke a drive dialog
// DriveApp.getFiles()
}
Note that key ingredient is DriveApp.getFiles(), and it still works even though it's commented. When I run the function, I'll get a pop-up window that says "(your script) would like to View and manage the files in your Google Drive". When I allow it, the data import function works.
Source
No need to add anything to your code.
You simply need to add an additional scope to the dependencies part of the appscript.json file:
"dependencies": {
"enabledAdvancedServices": [{
"userSymbol": "BigQuery",
"serviceId": "bigquery",
"version": "v2"
},
{
"userSymbol": "Drive",
"serviceId": "drive",
"version": "v2"
}]
}
In the View menu you could select to Show the manifest file:
Just add
DriveApp.getFiles()
to any function in your project and run it. After your running, you see a window that asks permission to the Drive.
Afterall you can delete this row and everything is will be ok.

Google API Executable permission denied error

I have a small Google Apps Script that I have deployed as API executable.
Although I have made the call with a valid token for the scope I'm using (spreadsheets), I can't get past this 403 PERMISSION_DENIED error.
I'm now testing this on the API's Explorer with the same error.
Does anyone have any ideas of what I might be missing?
My script is simple (still incomplete, but it runs - which should be enough for these initial tests):
OAuth Scope required by script (copied from API's Explorer):
https://www.googleapis.com/auth/spreadsheets
function myFunction(get) {
var ss = SpreadsheetApp.openById("1axDlnPaoEwhlb_Vs5SLBvkGJrR-fSeOLuHEdSBXCTBg"); // I'm not getting anything from the sheet at this point, I included it just to make sure that the script requires the spreadsheets scope
get += " " + "success!";
return ContentService.createTextOutput(get);
}
The request (copied from API's Explorer):
POST https://script.googleapis.com/v1/scripts/1d1EKj7vi-gzC0gB02qjw_qBPE1zSrZtJp-YUWuKm3NL3-3t6Sixpm0TZ:run?key={YOUR_API_KEY}
{
"function": "myFunction",
"parameters": [
"Hello world!"
]
}
The response (copied from API's Explorer):
{
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}
You may want to check these 3 things:
Make sure that your app script is associated with the correct Dev Console Project.
Enable Apps Script Execution API.
If you're running a function in an Apps Script using Method: scripts.run, set devMode: true if you're the owner of the script. Otherwise, use the default value which is false.
Also, you should meet the listed requirements in Using the Execution API.
See this related SO post for additional insights.
The script should be associated with the developer console project id that corresponds with OAuth 2.0 client ID used (On the script editor of your current script: Resources > Cloud Platform Project, then enter your project id number)
This was the reason why my script wasn't working (yours may differ, see Teyam's answer which I've marked as the correct one).

Google Classroom Apps Script - CourseWork.list permission error

I am trying to access course work from my Google Classroom in a Google Apps Script using the Classroom API v1. I followed the steps in the Quickstart to successfully retrieve my course list, but when I tried to access the coursework in one of my classes using the following:
var coursework = Classroom.Courses.CourseWork.list('valid courseId');
I get a 'The caller does not have permission' error. I can successfully retrieve the coursework list using the APIs Explorer, though.
From playing with the APIs Explorer, it looks like the "classroom.coursework.students.readonly" scope is needed for this command. However, that scope doesn't get added to my project when I hit the 'Allow' button in the permission dialog. Is there a way to add it to the scope list for the project? I've searched SO and have seen mention of setting scopes in other languages (python, for instance), but not in Apps Script. I've also seen mention of someone authorizing a scope manually in an Apps Script, but with no explanation on how to do that.
I've hit a wall on this, so if anyone has a suggestion, I'd really appreciate it. Thanks.
Originally addressed by me on this SO thread.
The appropriate Classroom API reference for this task is here.
Looks like even after enabling Advanced Google services..., you only get the following OAuth Scopes added -
https://www.googleapis.com/auth/classroom.courses
https://www.googleapis.com/auth/classroom.coursework.me.readonly
https://www.googleapis.com/auth/classroom.profile.emails
https://www.googleapis.com/auth/classroom.profile.photos
https://www.googleapis.com/auth/classroom.rosters
You can view these by navigating to File > Project properties > Scopes.
However, when you try the API from the documentation link, under the Credentials > Google OAuth 2.0 tab, it shows 4 more completely different OAuth scopes; those are as follows -
https://www.googleapis.com/auth/classroom.coursework.me
https://www.googleapis.com/auth/classroom.coursework.me.readonly
https://www.googleapis.com/auth/classroom.coursework.students
https://www.googleapis.com/auth/classroom.coursework.students.readonly
You need to add all 8 of these manually in your Apps script manifest file. To do that, navigate to View & check the Show manifest file. There you need to add this code, perhaps below dependencies -
"oauthScopes": [
"https://www.googleapis.com/auth/classroom.courses",
"https://www.googleapis.com/auth/classroom.coursework.me.readonly",
"https://www.googleapis.com/auth/classroom.profile.emails",
"https://www.googleapis.com/auth/classroom.profile.photos",
"https://www.googleapis.com/auth/classroom.rosters",
"https://www.googleapis.com/auth/classroom.coursework.me",
"https://www.googleapis.com/auth/classroom.coursework.me.readonly",
"https://www.googleapis.com/auth/classroom.coursework.students",
"https://www.googleapis.com/auth/classroom.coursework.students.readonly"
],
Note1: Only adding the newer 4 will not do the trick as the script would assume only these and not the original 5 there were auto-populated when your script ran for the first time.
Note2: The blank line is simply to differentiate between the scopes that get generated automatically vs. the ones you need to add manually (its redundant).
My appsscript.json file looks like this; yours might differ -
{
"timeZone": "Asia/Kolkata",
"dependencies": {
"enabledAdvancedServices": [{
"userSymbol": "Classroom",
"serviceId": "classroom",
"version": "v1"
}]
},
"oauthScopes": [
"https://www.googleapis.com/auth/classroom.courses",
"https://www.googleapis.com/auth/classroom.coursework.me.readonly",
"https://www.googleapis.com/auth/classroom.profile.emails",
"https://www.googleapis.com/auth/classroom.profile.photos",
"https://www.googleapis.com/auth/classroom.rosters",
"https://www.googleapis.com/auth/classroom.coursework.me",
"https://www.googleapis.com/auth/classroom.coursework.me.readonly",
"https://www.googleapis.com/auth/classroom.coursework.students",
"https://www.googleapis.com/auth/classroom.coursework.students.readonly"
],
"exceptionLogging": "STACKDRIVER"
}
I was getting this error repeatedly running the code as both a domain admin and as a teacher of the course I was testing with (i.e. I really should have had access).
In trying to ferret out the permissions issues, I tried making a call to Classroom.Courses.CourseWork.create, which triggered another authorization dialog that included additional permissions for accessing coursework. Even though my create call failed (I was still playing w/ the API and hadn't gotten the syntax right), the permissions it triggered were what I needed to get the course listing correct.
In short, here's the code that initially failed with the permission error you describe:
function getCoursework(id) {
var resp = Classroom.Courses.CourseWork.list(id);
work = resp.courseWork
if (work && work.length > 0) {
for (var i=0; i< work.length; i++) {
piece = work[i]
Logger.log('Work: %s (%s)',piece.title,JSON.stringify(piece));
}
}
}
That code did not trigger a permissions dialog, as it should have. However, once I ran the following (broken) code, I did get a permissions dialog, and then the above code worked:
function createCoursework (id) {
Classroom.Courses.CourseWork.create(id,
{ // doesn't work but triggers permissions correctly
"courseId": id,
"title": 'foo',
"description": 'desc',
});
}
As stated in this thread, make sure that the app script is associated with correct dev console project.
The script should be associated with the dev console project id that corresponds with OAuth 2.0 client ID used (this dev console project should also have "Apps Script Execution API" enabled).
To change the developer console project for an app script select the following menu item: Resources > Developer Console Project...
On this screen enter the project number for your dev console.
You must supply a valid OAuth token to use the API, and this requires a Developer Console Project.
I ahve the same issue - when running a Google Apps script add-on as a teacher of the project, the call to Courses.CourseWork.list works fine.
As soon as I switch to running the same script add-on as a student in the course, I get the 'The caller does not have permission' error.
This is not controllable by the developer of the add-on as beyond turning on the Classroom API, the scopes are not controllable by the developer.
The core issue is - code works for teachers of a course. Code fails for students of the course.
All this while the Classroom APi reference itself works fine. https://developers.google.com/classroom/reference/rest/v1/courses.courseWork/list
This is most likely a bug - at the very least, nothing to do with the generic catch-all answer given by #abielita above.
I see this bug is old so I have little hopes of an answer but here's hoping.