I want to use 1 google apps script from multiple Google Spreadsheet files within my Google Drive.
I followed this answer: "you could use Libraries. The idea is that you create one script that you use as a library"
I deployed a library and tried to access it from the Google Apps Script editor. Indeed I can find the library when I enter the library ID (i.e. script ID from script settings), but it gives me a manifest error:
Die Manifestdatei "appsscript.json" enthält Fehler: Ungültige Dienst-ID: 20012023_sistrix_urlkeyword_standalone
Translated:
The appsscript.json manifest file contains errors: Invalid service ID: 20012023_sistrix_urlkeyword_standalone
The manifest file looks like this:
{
"timeZone": "Europe/Berlin",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
I was not able to find any hint on how to enter a valid service ID into the manifest file.
I'm writing this answer as a community wiki, since the issue was resolved from the comments section, in order to provide a proper response to the question.
According to s.Panse, the solution was to change the identifier of the script. It was changed from 30012023_sistrix_keywordabfrage to sisirix abfrage and after that it started to work correctly.
Related
I'm trying to create a Google Apps Script (GAS) library that I can reuse across my Google Sheets spreadsheets. Following these instructions, here's what I've done so far:
Created a new project in Google Cloud Platform
Enabled Google Sheets API for project in step 1
Set up OAuth 2.0 authentication for project in step 1
Credential type = User data
Scopes = https://www.googleapis.com/auth/spreadsheets (I cannot use spreadsheets.currentonly because one method in this library requires the full spreadsheets scope)
OAuth Client ID = Web application
Configured OAuth consent screen
Publishing status = Testing
User type = External
Test users = Gmail email I used to write the script
In Apps Script editor:
Set the Google Cloud Platform (GCP) Project to Standard by associating it with the Project Number from step 1
Updated appsscript.json to look like this:
{
"timeZone": "America/Los_Angeles",
"dependencies": {
"enabledAdvancedServices": [
{
"userSymbol": "Sheets",
"version": "v4",
"serviceId": "sheets"
}
]
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets"
]
}
Created a versioned deployment of my script following these instructions
Shared my GAS project as "Anyone on the internet with this link can view"
And here's the issue I'm facing:
Created a new Sheets using the same Google account that I used to create the GAS library
In the Scripts editor, I added my GAS library by entering the Script ID, then selected the HEAD version (it doesn't seem to matter -- all versions resulted in the same error)
In Code.js, wrote a test function that calls a function from my GAS library
Clicked the Run button to execute the test function; the following prompt appears:
Clicked "Review permissions" and selected the Google account I used to create the GAS library
ISSUE: This error page is displayed:
Now the strange part: if I repeat steps 1-5 above using a different Google account (i.e., not the same account I used to create the GAS library), then it works! I get the expected OAuth consent screen, and after granting permissions, I'm able to use my GAS library.
Has anyone figured out how to reuse a GAS library in a Sheets script that is under the same Google account as the one that was used to create the GAS library?
I just wrote about this here: https://aimanfikri.com/2022/05/09/this-app-is-blocked-error-on-google-apps-script-solution/
In summary:
Configure a 'standard project' on Google Cloud Platform.
Set user access under 'Scopes'
Add relevant user accounts (if you don't have an enterprise Google Workspace)
Change your Apps Script project to the newly configured project using the new 'project number'.
If the app is blocked for your account, there is an easy approach to allow it. Just keep in mind that you would need to be an admin in the domain in order to run these changes. Follow this guide on allowing apps and complete its steps. Feel free to leave a comment if you need more help.
For a script that documents all the spreadsheet files with references in formulas to another spreadsheet, I want to retrieve the last modifying user of a file.
This apps script is only being used within the domain I am owning; the spreadsheet documents exist both in MyDrive as in our shared drive.
I am using the following statement:
var docModifierEmail = Drive.Files.get(docId).lastModifyingUser.emailAddress
Documentation is very hard to find
The error I'm getting all the time is:
API call to drive.files.get failed with error: File not found: 1Nz0_Kme172EQXAwgW55d7H.....
The scope I am using:
> "oauthScopes": [
> "https://www.googleapis.com/auth/spreadsheets",
> "https://www.googleapis.com/auth/userinfo.email",
> "https://www.googleapis.com/auth/drive",
> "https://www.googleapis.com/auth/drive.activity" <--- not sure if this is needed
Questions that I have:
Am I using the right function call?
Am I using the right scope?
What should be the right statement to retrieve the last modifying user's
email address of the file with id docId?
The Drive API version 2 available in Apps Script needs at least one of the following scopes for Files.get():
Scope:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive.metadata.readonly
https://www.googleapis.com/auth/drive.appdata
https://www.googleapis.com/auth/drive.metadata
https://www.googleapis.com/auth/drive.photos.readonly
When trying to access a file from your shared drive/team drive, You need to set the optional query parameter supportsAllDrives to true
Drive.Files.get("file id",{supportsAllDrives:true}).lastModifyingUser.emailAddress;
Additional Reference:
File Resource Representation
The following line of codes work in ScriptA but not in ScriptB:
var folder = DriveApp.getFolderById(folderId);
The oAuth is the same in both script files' appsscript.json:
...
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/script.external_request"
],
...
What am I missing?
This can be solved by activating the Google Drive API Advanced Services in the script file by accessing the menu Resources > Advanced Google Services..., and then enable the Drive API, and then at the bottom click the link to Google Cloud Platform API Dashboard and enable the Drive API there as well.
I encountered a similar issue (though with the DriveApp.getFiles() and DriveApp.searchFiles() functions), I was seeing the "Something Went Wrong - Please reload the page to try again" error.
After over an hour investigating I've narrowed it down to the Google Cloud Project (GCP) that the problematic AppScript is associated with.
If you've selected a GCP project for the script, then that project must have the appropriate GCP API enabled. For the DriveApp SDK/library I had to enable the Google Drive API (see docs), which then fixed the issue for me.
If the script is still using the default project I found that no additional action was needed; it probably means the underlying GCP project already has all the needed APIs enabled for each supported AppScript integration.
Interestingly, this is mentioned under Advanced services requirements, but it's not clear why DriveApp functions are also affected, as they aren't listed under "advanced services" (we're not using Drive API after all). I created a bug ticket in google's issue tracker to try and get to the bottom of this one.
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.
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.