Google Classroom APIをGoogle Apps Scriptで使ってみる。

# はじめに
[Google Classroom](https://classroom.google.com/)は、Googleが提供するLMS(Learning Management System：学習管理システム）で、筆者の大学にもようやく導入されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/58503/6c4a8163-6361-3b60-624b-e59b28e62360.png)

しかし、残念ながら提供されているアプリから出来ることが限定されており、成績データの細かい分析などをするときには不便です。

しかし、Googleが提供している[Classroom API](https://developers.google.com/classroom/)を用いると、Google Classroom上の幅広いデータにアクセスができるようになります。そこで、早速試してみました。

Classroom APIは.net, python, PHPなど様々な言語で利用可能ですが、ここでは最も簡単に開発環境を準備できるGoogle Apps Scriptでの使い方を見ていきます。

# 初期設定

[こちらの公式の説明](https://developers.google.com/classroom/quickstart/apps-script)をご覧ください。

# 基本的な機能

## クラスの一覧を出力する

```js:ListAllClasses
'use strict'

function ListAllCourses(){
  var response = Classroom.Courses
  var coursesArray = response.courses;
  coursesArray.forEach(function(e){
      Logger.log('%s (%s)', e.name, e.id);
  });
}
```
ClassroomサービスのCoursesコレクションのlistメソッドでレスポンスが得られるので、responseに保存します（[参照](https://developers.google.com/classroom/reference/rest/#rest-resource-v1courses)）。responseからcourses配列をcourseArrayに保存してログに出力します。得られるログはこういう感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/58503/21fbe6b6-190d-4381-e488-d2c9131b8bf4.png)

コースの名前と数字のIDが出力されます。コースのデータの取り出しなどはIDを使います。

## 課題（CourseWork）の一覧を出す
```js:ListAllCourseWork
function ListAllCourseWork(courseId){
  var response = Classroom.Courses.CourseWork.list(courseId);
  response.courseWork.forEach(function(e){
      Logger.log('%s (%s)', e.title, e.id);
  });  
}
```
与えられたコースIDの授業で出したコースワークの一覧（タイトルとID）を出力します。

## 受講生の一覧を出す

```js:ListAllStudents
function ListAllStudents(courseId){

  var listStudents = function (pageToken){
    if (pageToken){
      var newResponse = Classroom.Courses.Students.list(courseId,{pageToken: pageToken});      
      if(newResponse.nextPageToken){
        return newResponse.students.concat(listStudents(newResponse.nextPageToken));
      }  else{
        return newResponse.students;
      }
    }
  }
  
  var initialResponse = Classroom.Courses.Students.list(courseId);  

  if (initialResponse.nextPageToken){
    return initialResponse.students.concat(listStudents(initialResponse.nextPageToken));  
  } else {
    return initialResponse.students;
  }    
  
}
```
Classroom.Courses.Students.listでcourseIdで指定するコースの受講生一覧をリクエストするのですが、一度に取れるのは30名までです。それより生徒数が多い場合は、nextPageTokenを使って再度リクエストする必要があります。そのため、listStudentsという再帰関数を使って、nextPageTokenが空でない間は、自分自身を再び呼び出すようにしています。profileには、各受講生の名前、メールアドレスなどの情報があります（[参照](https://developers.google.com/classroom/reference/rest/v1/userProfiles#UserProfile)]）。関数型言語ではよくあるパターンですね。

私の場合、学生さんは大学のメールアドレスでログインし、メールアドレスの前半に学生番号に関する情報が含まれているので、メールアドレスが一番重要な情報であり、それを出力するようにしています。他にも、ID、名前などを取得可能です。

## 提出されたコースワーク（課題）の一覧を出す
```js:ListAllStudentWork
function ListAllStudentWork(courseId,courseWorkId){
  var listStudentWork = function (pageToken){
    if (pageToken){
      var newResponse = Classroom.Courses.CourseWork.StudentSubmissions.list(courseId,courseWorkId,{pageToken: pageToken});      
      if(newResponse.nextPageToken){
        return newResponse.studentSubmissions.concat(listStudentWork(newResponse.nextPageToken));
      }  else{
        return newResponse.studentSubmissions;
      }
    }
  }
  
  var initialResponse = Classroom.Courses.CourseWork.StudentSubmissions.list(courseId,courseWorkId);

  if (initialResponse.nextPageToken){
    return initialResponse.studentSubmissions.concat(listStudentWork(initialResponse.nextPageToken));  
  } else {
    return initialResponse.studentSubmissions;
  }
  
}
```
「受講生の一覧を出す」とやっていることはほとんど同じです。courseIDと、courseWorkIdを使って提出された課題のリストを取得します。studentSubmissions配列の要素に含まれるデータ[こちら](https://developers.google.com/classroom/reference/rest/v1/courses.courseWork.studentSubmissions)の通りです。shortAnswerSubmission, userIDなどが含まれています。

#おわりに
一見すると機能が限定されているGoogle Classroomですが、APIを使うとそれなりにデータを取得できるので、色々な分析に応用したいですね。