Search code examples
google-apps-scriptgoogle-sheetsgoogle-drive-apigoogle-classroom

I want to post 'materials' from a Google Sheet to individual students in a Google Classroom


Using apps script in Google Sheet I can create a new assignment or 'materials' for all students in a Google Classroom. The materials are generated from a row of cells in Google Sheets. I want to post different materials for different students. In effect, each row of information will create a new materials post in Google Classroom based on the name of the student in each row. This name matches a student name in the Google Classroom.

I wrote code to retrieve the Student ID from Google Classroom

function getStudentId(studentName) {
  var students = Classroom.Courses.Students.list("Course ID").students;
  for (var i = 0; i < students.length; i++) {
    if (students[i].profile.name.fullName === studentName) {
      return students[i].userId;
    }
  }
  return null;
}

and assign the created materials to this student, as part of the code generating the materials in Google Classroom

      Classroom.Courses.CourseWorkMaterials.create(materials, courseId, {assigneeMode: "INDIVIDUAL_STUDENTS", individualStudentsOptions: {studentIds: [getStudentId(pupil)]}});

This throws an error - GoogleJsonResponseException: API call to classroom.courses.students.list failed with error: Requested entity was not found.

I don't know if the error is in my code or if it is a permissions thing. I have added Classroom and Drive APIs to the Apps Script.


Solution

  • Modification points:

    • It seems that the arguments of Classroom.Courses.CourseWorkMaterials.create is resource: Classroom_v1.Classroom.V1.Schema.CourseWorkMaterial and courseId: string. But, in your script, 3 arguments of materials, courseId, {assigneeMode: "INDIVIDUAL_STUDENTS", individualStudentsOptions: {studentIds: [getStudentId(pupil)]}} are used. Although I'm not sure about the value of your materials, I guessed that this might be the reason for your current issue.
    • And, in your request body of {assigneeMode: "INDIVIDUAL_STUDENTS", individualStudentsOptions: {studentIds: [getStudentId(pupil)]}}, it is required to include title property. Please be careful about this.

    When these points are reflected in your script, it becomes as follows.

    From:

    Classroom.Courses.CourseWorkMaterials.create(materials, courseId, {assigneeMode: "INDIVIDUAL_STUDENTS", individualStudentsOptions: {studentIds: [getStudentId(pupil)]}});
    

    To:

    Classroom.Courses.CourseWorkMaterials.create({ assigneeMode: "INDIVIDUAL_STUDENTS", individualStudentsOptions: { studentIds: [getStudentId(pupil)] }, title: "sample title" }, courseId);
    
    • When this script is run, I confirmed that the user of getStudentId(pupil) gets an email.

    Note:

    • In this modification, it supposes that your values of courseId and getStudentId(pupil) are valid values and you have permission for using this API. Please be careful about this.

    Reference: