Reputation: 13
I am trying to create an extension to google classroom using google-apps-script but I seem to be running into permission problems- "the caller does not have permission". Can someone tell me why this is happening and what I need to do
I have tried accessing all the libraries provided by google cloud platform hoping that one of them gives the permission that is required all to no avail.
function listCourses() {
var optionalArgs = {
pageSize: 10
};
var response = Classroom.Courses.list(optionalArgs);
var courses = response.courses;
if (courses && courses.length > 0) {
for (i = 0; i < courses.length; i++) {
var course = courses[i];
Logger.log('%s (%s)', course.name, course.id);
var submissions = Classroom.Courses.CourseWork.list(course.id, optionalArgs);
for (i = 0; i < submissions.length; i++) {
var submission = submissions[i];
Logger.log('%s', submission);
}
}
} else {
Logger.log('No courses found.');
}
}
The code is meant to list out the course ids of courses in a particular class
Upvotes: 1
Views: 2360
Reputation: 2331
This solution involves doing 2 things -
appsscript.json
)Code.gs
fileappsscript.json
)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 -
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 -
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 that 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"
}
Code.gs
fileOnce you have the right permissions, you're then free to play around with the actual code - the one you've originally shared lacks a few components and I've modified the same to get it working here -
function listCourses() {
var optionalArgs = {
pageSize: 10
};
var response = Classroom.Courses.list(optionalArgs);
var courses = response.courses;
if (courses && courses.length > 0) {
for (var i = 0; i < courses.length; i++) {
var course = courses[i];
Logger.log('%s (%s)', course.name, course.id);
var submissions = Classroom.Courses.CourseWork.list(course.id, optionalArgs);
for (var j = 0; j < submissions.courseWork.length; j++) {
var submission = submissions.courseWork[j];
Logger.log('%s', submission);
}
}
} else {
Logger.log('No courses found.');
}
}
Hope this helps :) but I don't actually know why these scopes are not added automatically, perhaps open up an issue with Google for it.
Edit note: Rectified grammatical errors
Upvotes: 1