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 |1 Answer
Reset to default 1I 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).
const
andlet
are better for variable declaration for most cases. – Wicket Commented Mar 26 at 13:44