9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【GAS】Google Classroomで、生徒に個別に連絡をする。

Last updated at Posted at 2021-05-06

公立高校の教員(理科・物理)です。初のQiita投稿です!

作ったもの

スプレッドシートで、アプリケーションを作成しました。Excelのように、ボタンをクリックするとコードが実行されます。
classroom個別投稿.PNG
こちらのリンクからコピーを保存できます。この記事を読んで興味を持ってくださった方は、ご自身のドライブから実行してみてください。

なにができるのか

  • Google Classroomのストリームには、生徒を指定した限定公開の機能があります。このソフトでは、限定公開の機能を使って、スプレッドシートに事前に記録した内容を、生徒一人ひとりに限定公開で配信をします。
  • 今までExcel等で作成し、印刷していた生徒個票を、Classroom上で配信することで代替できます。
    • 使用例:出欠日数のおしらせ、提出物提出回数の確認、各種アカウントの配布
  • 操作ミスを防ぐために、スプレッドシートのメッセージボックスやインプットボックスを使って、多くの学校現場で使われているであろう、ExcelVBAで作られたソフトウェアと見た目を似せてみました。
  • 機能面や運用面のことはさておき、Qiitaでは、GASの技術面についてコメントを残します。

作成した関数の紹介

  • その前に...公式リファレンス等では、classroomを識別する値をcourseIdとしていますが、私が作成したプログラムでは、変数名をclassIdとしてしまっています。その2つは、同様のものをさしていると思って読み進めてください。

getClassListSS 関数

  • 自分が担当している授業名とコースIDをスプレッドシートに出力します。
  • コースIDとは、classroomに生徒を招待するときに使う「クラスコード」とは別物で、GASなどで各クラスを扱うときに使う識別番号です。
function getClassListSS() {
  var response = Classroom.Courses.list();
  var courses = response.courses;
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName('担当クラスリスト');
  sheet.clear();
  sheet.appendRow(["授業名", "クラスコード"]);
  for (i = 0; i < courses.length; i++) {
    Logger.log('%s (%s)', courses[i].name, courses[i].id);
    sheet.appendRow([courses[i].name, courses[i].id]);
  }
  sheet.activate();
  Browser.msgBox("【担当クラスリスト】のシートに、授業のリストを作りました。クラスコードをコピーしてください。");
}
  • sheet.appendRow(配列)が、便利でした。

createStudentListMaxSS 関数

  • getClassListSS関数で取得した担当授業一覧のコースIDを使います。
  • コースIDで指定したクラスの、参加生徒一覧を取得してスプレッドシートに書き出します。
  • コースIDは、文字列型で渡す必要があるので、String(コースId)として、型変換をしています。(これに気づかずに、少し時間を食いました。)
function createStudentListMaxSS() {
  var classId = Browser.inputBox("生徒リストを作成します。classroomのIDを入力してください。\n わからない場合は、キャンセルを押してください。", Browser.Buttons.OK_CANCEL); //ClassroomのIDを入力
  if (classId != "cancel") {
    classId = String(classId);
    className = getClassName(classId);
    Logger.log(className);
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = spreadsheet.getSheetByName('生徒リスト');
    sheet.clear();
    sheet.appendRow(["クラスコード", "アドレス", "生徒名", "連絡事項(はじめは空欄)", "送信状況(送信済みは、空欄)"]);

    // 取得したクラスIDから、そのクラスに所属している生徒リストを取得
    var students = getStudentListMax(classId);

    // 生徒一覧をログとして出力
    for (i = 0; i < students.length; i++) {
      Logger.log(students[i][0]);//生徒のアドレス出力
      Logger.log(students[i][1]);//生徒の名前を出力
      sheet.appendRow([classId, students[i][0], students[i][1], "ここに記入", "これから送信する"]);
    }
    sheet.getRange('A1').activate();

    //作成したスプレッドシートのURLをログに表示
    Browser.msgBox("生徒リストを作成しました。生徒リストのD列に、配信する文章を記録してください。");
  } else {
    Browser.msgBox("キャンセルが押されました。");
  }
}
  • getStudentListMaxは、コースIDを引数に取る、自作関数です。
    • 標準搭載の関数 Classroom.Courses.Students.list(コースID) だと、生徒数30人までしか取得できません。公式リファレンスを読むと、引数のpageSizeをいじればいいと書いてありますが、何度やっても30人以上取得できませんでした(まあ、そんなもんなんでしょう。)。
    • こちらの記事を参考に、getStudentListMax関数を作成しました。
function getStudentListMax(classId) {
  let pageToken = "";
  var cnt = 0;
  let allStudentList = [];// 空の配列を用意
  do {
    let studentList = Classroom.Courses.Students.list(classId, { "pageToken": pageToken });
    for (i = 0; i < studentList['students'].length; i++) {
      let student = studentList['students'][i];
      allStudentList.push([student['profile']['emailAddress'], student['profile']['name']['fullName']]);//生徒のアドレスを配列に追加
    }
    pageToken = studentList.nextPageToken;//しおりを挟む。最後のページでなければまた「do」する
    cnt = cnt + 1;
  } while (pageToken);//最後のページまで行ったら処理を辞める
  return allStudentList;
}
  • 引数にコースIDを取り、メールアドレスとフルネームを戻り値とします。allStudentListに格納する値を変えれば、ほかの値もできます。
    • JSONを戻り値にすればよかったのかもしれませんが、自分の知識不足でうまく扱えませんでした...。

listToClassroom 関数

  • 最後に、投稿する関数です。
  • 誤投稿を防ぐために、msgBoxで処理を分けています。
function listToClassroom() {
  var ck = Browser.msgBox("Okを押すと、生徒に個別配信されます。", "続けますか", Browser.Buttons.OK_CANCEL);
  if (ck == 'ok') {
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = spreadsheet.getSheetByName('生徒リスト');
    const lastRow = sheet.getLastRow();
    for (let i = 2; i <= lastRow; i++) {
      if (sheet.getRange(i, 5).getValue()) { //空欄の場合は、送信しない。
        const values = sheet.getRange(i, 1, 1, 4).getValues();
        console.log(values);
        postAnounceIndividual(values[0][0], values[0][1], values[0][2], values[0][3]);
        sheet.getRange(i, 5).clearContent();
      }
    }
    Browser.msgBox("ストリームに、個別の連絡を送信しました。");
  }
  if (ck == 'cancel') {
    Browser.msgBox("キャンセルを押しました");
  }
}
  • postAnounceIndividual関数は、[コースID、生徒のアドレス、生徒のフルネーム、投稿する文章]の4つの引数をとって、Classroom APIを使って実際に投稿をする関数です。
function postAnounceIndividual(target, mailAdressStr, nameStr, textStr) {

  studentList = [mailAdressStr];
  var data = {
    "courseId": String(target),
    "text": nameStr + "さんへ(個別連絡です。) \n \n " + textStr,
    "assigneeMode": "INDIVIDUAL_STUDENTS",
    "individualStudentsOptions": {
      "studentIds": studentList//スプレッドシートから取得した生徒のIDリストを渡す
    },
    "state": "PUBLISHED"
  };
  Classroom.Courses.Announcements.create(data, String(target));
  Logger.log(studentList + "_" + textStr + "______anounce!!");
}
  • Classroom.Courses.Announcements.create()の引数にJSON形式で投稿するテキストや送信相手のメールアドレスを指定することで、Classroomに投稿ができます。公式リファレンスはこちら
  • "assigneeMode"と、"studentIds"が、個別投稿のキモです。(でも正直よくわかっていませんw)

getClassName 関数

  • 最後におまけで、コースIDを引数に、授業名を戻す関数です。この手の処理は、探して見ると意外と見つからないものです。
function getClassName(targetClassId) {
  //ClassIdから、授業名を返します。
  var myCourses = Classroom.Courses.list().courses;

  ////取得したいクラスの名前を、IDから取得
  for (i = 0; i < myCourses.length; i++) {
    if (myCourses[i]['id'] === targetClassId) {//targetClassNameに一致するときのみ以下の処理を実施
      var inviteClassName = myCourses[i]['name'];
    } else {
      continue;
    }
  }
  return inviteClassName;
}

最後に

  • トリガーと連携させれば、「formが提出されたらclassroomでお知らせする」などもできると思います。
  • 「メールでやればいいじゃん!」と思った方へ、確かに、臨時休業中は、私もメールで連絡や提出チェック等を行っていました。
    • しかし、高校生の生徒にとって、メールは身近ではありません。学校で使うから...という理由で、メールアプリをインストールさせて、学校アドレスを登録して...なんていうのは、生徒・教員ともども負担が大きいです。
    • 一方、クラスルームは朝の連絡や健康観察等で毎朝アクセスさせているので、比較的高い割合で確認してくれます。
  • GIGAスクールなんちゃらで、多くの自治体がGoogle Classroom等を利用していると思います。GASを使うことで、様々な校務の効率化ができると思います。今後も、GASに関する投稿ができればいいなと思います。

2021/06/16追記

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?