Oluebubechukwu Onaga
Oluebubechukwu Onaga

Reputation: 13

"The caller does not have permission - google-apps-script"

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

Answers (1)

Sourabh Choraria
Sourabh Choraria

Reputation: 2331

This solution involves doing 2 things -

  1. Updating the manifest file (appsscript.json)
  2. Updating the Code.gs file

Task 1

Updating the manifest file (appsscript.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"
}

Task 2

Updating the Code.gs file

Once 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

Related Questions