最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Google Classroom Call to retrieve Topics, Coursework and Materials returns null - Stack Overflow

programmeradmin4浏览0评论

I am trying to retrieve Topics, courseWork and Materials from a classroom to eventually populate a new class (in another step), but I am failing at the first hurdle since the call to the source classroom fails to return courseWork or materials (but does return Topics). The source classroom has approx 10 topics, 20 courseworks and 10 materials I know the API is working since this call returns properly as does the topics call.

var destinationCourseData = Classroom.Courses.get(759489185424);
Logger.log("Destination course Data: " + JSON.stringify(destinationCourseData));

However, the call for courseWork and materials fail, without any apparent error but return null, implying that either the call silently failed or that it detected nothing. CourseWork and Materials in the source classroom are in draft but I have also tried with posted materials. Documentation suggests that entities would be returned from any state. Sample code is here

  var destinationCourseData = Classroom.Courses.get(759489185424); 
  Logger.log("Destination course Data: " + JSON.stringify(destinationCourseData));
  var sourceCourseId = 747142722748;
  var destinationCourseId = 689872265288;
  var topics = Classroom.Courses.Topics.list(sourceCourseId).topic;
  Logger.log("Topics: "+JSON.stringify(topics));
  var sourceCourseWorkResponse = Classroom.Courses.CourseWork.list(sourceCourseId);
  //     if (sourceCourseWorkResponse && sourceCourseWorkResponse.courseWork) {
  var courseWork = sourceCourseWorkResponse.courseWork;
  Logger.log("Coursework : "+JSON.stringify(sourceCourseWorkResponse));

var topic returns valid results but courseWork returns {}

Any thoughts or suggestions are appreciated. PS: I have also tried with a backoff routine - same result

I am trying to retrieve Topics, courseWork and Materials from a classroom to eventually populate a new class (in another step), but I am failing at the first hurdle since the call to the source classroom fails to return courseWork or materials (but does return Topics). The source classroom has approx 10 topics, 20 courseworks and 10 materials I know the API is working since this call returns properly as does the topics call.

var destinationCourseData = Classroom.Courses.get(759489185424);
Logger.log("Destination course Data: " + JSON.stringify(destinationCourseData));

However, the call for courseWork and materials fail, without any apparent error but return null, implying that either the call silently failed or that it detected nothing. CourseWork and Materials in the source classroom are in draft but I have also tried with posted materials. Documentation suggests that entities would be returned from any state. Sample code is here

  var destinationCourseData = Classroom.Courses.get(759489185424); 
  Logger.log("Destination course Data: " + JSON.stringify(destinationCourseData));
  var sourceCourseId = 747142722748;
  var destinationCourseId = 689872265288;
  var topics = Classroom.Courses.Topics.list(sourceCourseId).topic;
  Logger.log("Topics: "+JSON.stringify(topics));
  var sourceCourseWorkResponse = Classroom.Courses.CourseWork.list(sourceCourseId);
  //     if (sourceCourseWorkResponse && sourceCourseWorkResponse.courseWork) {
  var courseWork = sourceCourseWorkResponse.courseWork;
  Logger.log("Coursework : "+JSON.stringify(sourceCourseWorkResponse));

var topic returns valid results but courseWork returns {}

Any thoughts or suggestions are appreciated. PS: I have also tried with a backoff routine - same result

Share Improve this question edited Mar 26 at 9:34 Tedinoz 8,3103 gold badges28 silver badges41 bronze badges asked Mar 25 at 9:00 Class AdminClass Admin 134 bronze badges 5
  • Please add a minimal reproducible example. – Wicket Commented Mar 25 at 15:22
  • Hi Wicket and thanks for the attention, this is driving me mad. The code included is a minimal reproducible example - except it needs wrapping in a function and the sourceCourseId will need to reflect a classroom on the testers domain, since the one above is locked to ours. The above code returns Topics perfectly but returns {} for courseWork and similarly for materials (which is not shown here). Any thoughts or help is appreciated – Class Admin Commented Mar 26 at 8:12
  • I also intended to say that I am running this as an App script – Class Admin Commented Mar 26 at 8:38
  • The code include are snippets, not a minimal reproducible example. Please include a complete function declaration as well any detail required to reproduce the error. In this case , explain what kind of account is used, the roles / permissions of the account, a brief technical description or the class, etc. – Wicket Commented Mar 26 at 13:39
  • By the way, nowadays const and let are better for variable declaration for most cases. – Wicket Commented Mar 26 at 13:44
Add a comment  | 

1 Answer 1

Reset to default 1

I think there are a few points here:

1. First, to clarify, if all the materials are in the draft state, this is working as intended.

Documentation suggests that entities would be returned from any state.

This isn't accurate. The docs for coursework.list say "If unspecified, items with a work status of PUBLISHED is returned." in the state parameter.

That said, you mentioned trying with published resources as well.

2. The ID's should actually be strings, not numbers, but I don't think that's the issue here, as Apps Scripts seems to handle that in their abstraction. But I would make them strings to be safe.

3. After swapping in my own course ID (with published materials), and using string ID values, I'm not able to reproduce the behavior you're seeing. However, I did get a very unexpected error with my example; Topics.list() worked fine and CourseWork.list() gave me a permissions error.

// Topics.list() is successful, CourseWork.list() fails with permission issue??
function workingExample() {
  var sourceCourseId = '123'; // this is now a string
  var topics = Classroom.Courses.Topics.list(sourceCourseId).topic;
  Logger.log("Topics: "+JSON.stringify(topics));
  var sourceCourseWorkResponse = Classroom.Courses.CourseWork.list(sourceCourseId);
  var courseWork = sourceCourseWorkResponse.courseWork;
  Logger.log("Coursework : "+JSON.stringify(sourceCourseWorkResponse));
}

That doesn't make sense to me, and I use Apps Scripts pretty regularly so it might be a bug.

I tried using HTTP directly instead of the Classroom service to rule out that as an issue, but had the same problem:

// This also thinks I don't have permission??
function fetchCourseworkHttp() {
  const courseId = '123';
  const apiUrl = `https://classroom.googleapis/v1/courses/${courseId}/courseWork`;
  const options = {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`,
      'Accept': 'application/json',
    },
  };
  const response = UrlFetchApp.fetch(apiUrl, options);
  const data = JSON.parse(response.getContentText());
  Logger.log(data)
}

I was finally able to resolve the issue by explicitly setting scopes for the methods in `appscript.json`:

{
  "timeZone": "America/New_York",
  "dependencies": {
    "enabledAdvancedServices": [
      {
        "userSymbol": "Classroom",
        "version": "v1",
        "serviceId": "classroom"
      }
    ]
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis/auth/classroom.courses.readonly",
    "https://www.googleapis/auth/classroom.coursework.me",
    "https://www.googleapis/auth/classroom.coursework.students",
    "https://www.googleapis/auth/classroom.topics"
  ]
}

Please let me know if any of that resolves your issue (and which step did).

发布评论

评论列表(0)

  1. 暂无评论