GAS – Google クラスルーム に神機能を追加!生徒のストリーム投稿を通知させる

コピペでGAS

という需要があると思いまして!!👍

Google Classroom でストリームに投稿するとき、教師から行うとその通知を送る設定にしておけば、勝手に Gmail に通知が届くんですよね!

ただ、生徒の投稿では通知がこないんです。

教師の投稿に対するコメントや限定公開コメントも通知は来ますが、生徒の投稿に対しては通知がこないんですよね。

そもそも、生徒による自発的な投稿は禁止をしているところが多いかもしれませんが…..。

教科係やクラス委員からの連絡でも使えるし、そういうのはLINEでやってほしくないですし。
入ってない子もいるから。

こういったオフィシャルなことは、オフィシャルな場でやろう!!

ということで、今回のシステムは、

Google Classroom  で生徒のストリーム投稿に対して通知(メール)を送ることができるようになります!!!

これから、生徒の投稿を見逃すことはないですね!!!

さてさて。作っていきましょー。

まずは、こちらから Google スプレッドシート を作成してください。

Google Sheets: Sign-in
Access Google Sheets with a personal Google account or Google Workspace account (for business use).

まずはクラスルーム一覧の取得です。

スプシの「拡張機能」から「Apps Script」をクリックして編集画面を開きましょう。

function classroomdata(){
  var now = new Date();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sht = ss.getSheetByName('クラスルーム一覧');
  var response = Classroom.Courses.list({});
  var courses = response.courses;
  //console.log(courses);
  var course = '';
  for (i = 0; i < courses.length; i++) {
    course = courses[i];
    var folders = course.teacherFolder;
    sht.getRange(i+2, 1).setValue(course.name);
    sht.getRange(i+2, 2).setValue(course.id);
    sht.getRange(i+2, 3).setValue(course.teacherGroupEmail);
    sht.getRange(i+2, 4).setValue(course.courseGroupEmail);
    sht.getRange(i+2, 5).setValue(course.alternateLink);
    sht.getRange(i+2, 6).setValue(course.ownerId);
    sht.getRange(i+2, 7).setValue(folders.alternateLink);
    sht.getRange(i+2, 8).setValue(folders.id);
    sht.getRange(i+2, 9).setValue(folders.title);
    sht.getRange(i+2, 10).setValue(course.enrollmentCode);
    sht.getRange(i+2, 11).setValue(course.creationTime);
    sht.getRange(i+2, 12).setValue(course.calendarId);
  }
}

このような状態にして、💾で保存をしましょう。

次に、「サービス」の+アイコンをクリックします。

Google Classroom API」があるので、

選択します。

「追加」をクリックしましょう。

サービスを追加したら、また保存をすることを忘れずに!

保存をしたら実行をしてみましょう。

実行方法がわからない方はこちらを参考にしてください!

#権限の承認

クラスルームが一覧になって取得できるはずです。

続いて、生徒一覧の取得です。

こちらのプログラムを追加します。

function getStudent() {//生徒IDの取得
  const ss  = SpreadsheetApp.getActiveSpreadsheet();
  const ui = SpreadsheetApp.getUi();
  const res = ui.prompt('生徒一覧を取得するクラスIDを入力してください');
  var courseId = res.getResponseText();
  var sht = ss.getSheetByName('生徒一覧');
  var profile = '';
  var name = '';
  var fullName = '';
  var givenName = '';
  var familyName = '';
  var emailAddress = '';
  var pageToken = null; 
  do {
    var optionalArgs = {
      pageToken: pageToken
    };
    var response = Classroom.Courses.Students.list(courseId,optionalArgs);
   // console.log(response);
    if (response) {
      try {
        var ob = response.students;
        for(var j in ob){
          var data = ob[j];
          profile = data['profile'];
          name = profile['name'];
          emailAddress = profile['emailAddress'];
          fullName = name['fullName'];
          givenName = name['givenName'];
          familyName = name['familyName'];
          sht.appendRow([String(data['userId']),fullName,familyName,givenName,emailAddress]);
        }
      } catch (err) {
        Logger.log('Course with id "%s" not found', courseId);
        }
    }
  pageToken = response.nextPageToken; 
  } while (pageToken != null);
  return;
}

コピペをしたら保存をします!

それでは、実行してみましょう。

まず、生徒一覧を取得したいクラスのIDをコピーしておいてください。
「クラスルーム一覧」のB列に出てきていた数字です。

それでは、実行するプログラムを↓のように変更します。

GAS は function の後ろに入れてある名前が関数名になり、どの関数を実行させるかをここで設定します。

実行すると、スプシにこのような表示が出てきます。

ここに、先ほどコピーしたクラスのIDを貼り付けて、OKをクリックしてください。

わざわざこんなことをしなくても、フラグという列を作ってあるので、別の方法もあるのですが。
この表示をするコードの紹介も含めたかったので使っているだけです。

できる方は適宜変更してください!

生徒一覧というシートに生徒の名前やIDなどが取得されています。

それでは、クラスルームのストリームに投稿されている内容を取得したいと思います。

下記のプログラムを追加してください。

function getCourseAnnouncement() {
  var now = new Date(); 
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sht = ss.getSheetByName('クラスルーム一覧');
  var sht2 = ss.getSheetByName('ストリーム一覧');
  var sht3 = ss.getSheetByName('生徒一覧');
  const lastRow = sht.getLastRow();//クラスルーム一覧の最終行取得
  const lastRow2 = sht2.getLastRow();//クラスルーム一覧の最終行取得
  const lastRow3 = sht3.getLastRow();//クラスルーム一覧の最終行取得
  let array =[];
  array = String(sht2.getRange(1, 2,lastRow2).getValues());//課題のIDを取得する
  try {
    for(row = 2; row <= lastRow; row++) {//クラスルームを一つずつ確認する
      if(sht.getRange(row, 13).getValue()){//投稿のセルに投稿内容が入力されているクラスだけ投稿する
        var courseId = String(sht.getRange(row,2).getValue());
        var response = Classroom.Courses.Announcements.list(courseId);
        //console.log(response.announcements);
        const ob = response.announcements;
        for(j = 0; j < ob.length; j++){
          var data = ob[j];
          if(array.indexOf(data['id'])===-1){
            sht2.insertRowBefore(2);
            sht2.getRange(2, 1).setValue(data['courseId']);
            sht2.getRange(2, 2).setValue(data['id']);
            sht2.getRange(2, 3).setValue(data['text']);
            sht2.getRange(2, 4).setValue(data['state']);
            sht2.getRange(2, 5).setValue(data['alternateLink']);
            sht2.getRange(2, 6).setValue(new Date(data['creationTime']));
            sht2.getRange(2, 7).setValue(new Date(data['updateTime']));
            sht2.getRange(2, 8).setValue(data['assigneeMode']);
            sht2.getRange(2, 9).setValue(data['creatorUserId']);
            for(let row3 = 2;row3<= lastRow3; row3++){
              let studentId = sht3.getRange(row3,1).getValue();
              if(studentId==data['creatorUserId']){
                let name = sht3.getRange(row3,2).getValue();
                let text = data['text'];
                let alternateLink = data['alternateLink'];
                let creationTime = new Date(data['creationTime']);
                //mail(name,text,alternateLink,creationTime);
              }
            }
          }
        }
      }
    }
    //console.log(data['id']);
  } catch (err) {
   Logger.log('Course with id "%s" not found', courseId);
  }
}

コピペしたら保存をしましょう!

次にスプシの準備です。

「クラスルーム一覧」のシートで、投稿を取得したいクラスのM列(flag)に半角で1を入れてください。

この1が入っているクラスの投稿を取得します。
こんな感じで、いらない行は消してくれても構いません!

これで準備完了です。

実行をしてみましょう!

実行するのは、getCourseAnnouncement です!

これまでの投稿を取得することができます。

まだ、生徒への通知は行っていません。
投稿を取得しただけですのでご安心ください。

この後の設定をすると、生徒に通知がいきますので注意してください。

ポイントは、先にここまでを終わらせることです。

どういうことかというと、
これまでにストリームに投稿されている内容を取得しておかないと、これまでの投稿が全て新規投稿という認識という感じなり、大量のメールを送ってしまいます。

よって、これまでの投稿を先に取得しておくのです!

生徒への通知をするには、プログラムを追加してください。

function mail(name,text,alternateLink,creationTime){
  let To ='';
  let Options = {
  //'cc':'' //ここでCCを設定、学年主任や養護教諭、複数設定したい場合は半角カンマで区切る
  //'bcc':'ここ' //ここでbccを設定、学年主任や養護教諭、複数設定したい場合は半角カンマで区切る
  };
  // 自動返信メール件名
  let Subject = 'コメントがありました';//こちらはメールの件名
  // 自動返信メール本文
  let Body =
  name + 'さんから投稿がありました。\n\n'+text+'\n\n詳しくはリンクから確認してください。\n'+alternateLink+'\n\n更新日時:'+creationTime;
  GmailApp.sendEmail(To, Subject, Body, Options);
}

次に、この通知のプログラムを使うために、getCourseAnnouncement の中にある

//mail(name,text,alternateLink,creationTime);

この部分の // を外してください。

↓のようにします。

mail(name,text,alternateLink,creationTime);

それでは、保存をしてください!

これで、新しい投稿があったらメール(通知)をするように設定できます。

ただ、この状態だと、全て手動で行わないといけないですよね。

そのため、自動化するためにトリガーの設定をします。

トリガーの設定方法に不安の方はこちら

#トリガー

⏰のアイコンからトリガーの設定をします。

右下のトリガーを追加をクリックします。

自動化したい関数は、getCourseAnnouncement なので、変更します。

次に、イベントソースを選択から時間手動型にします。

おすすめの「時間ベースのトリガーのタイプ」は、「分ベースのタイマー」「15分おき」です。

これで、15分おきに新しい投稿がないかをチェックしてくれて、新しい投稿があれば取得、メールで通知をしてくれます。

瞬時にできるわけではないってことになるのですが….。

もちろん、時間の間隔を短くすればその分早く取得のチェックをしてくれます。

さて、最後の設定です。

通知を送るメールアドレスです。

このアドレスの設定は、次の画像で説明すると119行目で決めているのです。

‘ ‘ で囲われているアドレスに送るのですが、今は空欄になっていますので、誰にも送られません。

ここでおすすめしたいのが Google グループ です。

いわゆるメーリングリストになるんですけど、下記からグループを作成することができます。

Sign in - Google Accounts

通知を送りたい生徒のアドレスを登録して、グループを作り、そのグループのアドレスを入れます。

  let To ='  ここに入れる  ';

これで完成です。必ず保存をしてください!

後は、新しい投稿があって、15分後にメールが来るはず!

動画でも解説していますので、ご覧ください!

また、うまくいかない!や Google グループ の使い方がわからない!などなどありましたら、コメントやお問合せください!

#クラスルーム

コメント

  1. のん より:

    参考にさせていただき、生徒からの投稿が通知されるようになり助かりました。ありがとうございます。

    もう一つ解消したい課題がありますので、質問させていただきます。
    生徒の投稿に対してコメントがあった場合に、そのコメントがあったことを通知する機能も欲しいのですが、その場合はどうしたらいいでしょうか。

  2. くま より:

    初心者でGASのコードが全くわからず、大変失礼な質問になってしまうかもしれず、申し訳ありません。
    複数のクラスで行いたい場合、最後の設定のところで複数グループ分を設定するのかと思うのですが、その考え方で大丈夫でしょうか?
    各クラスのストリームだけがそのクラスの生徒に流れるのであって、取得した学生全てにメールが届くようなことはおこりませんか?

    • keisuke より:

      > くま さん
      コメントありがとうございます!!
      返信が遅くなり申し訳ありません…。

      複数のクラスで行っても、そのクラスのストリームだけが、そのクラスの生徒に流れます!
      よって、全ての生徒にメールが届くことはありません!
      その認識で大丈夫です。

      ただし、このプログラムは、かなり負荷がかかります。
      クラスへの投稿数が多くなれば多くなるほどです…。

      そのため、ひとクラスで、1スプレッドシートのようにして分割した方が良いと思います!!
      複数のクラスをまとめてしまうと、結構エラーが出てしまうかなと思います。

      私が運用していた時も、ひとクラスずつ分けて行っていました。

      またご質問等あればお気軽にコメントください😋

  3. マイク より:

    生徒からの投稿が通知されるようになり、大変助かっています。

    GASのコードなど全くわからずにお聞きします。
    現在、教師と生徒2人だけの個別のクラスルームを複数人分(大量になる可能性も)作る必要があります。作るタイミングがバラバラなので、クラスルームの取得、生徒一覧の取得もトリガーでオートメーション化はできたらいいなと思っています。もちろん、生徒の投稿の通知は継続して使用したいです。

    このオートメーション化は可能でしょうか?可能だとすれば、どのようにしたらいいでしょうか?

    • keisuke より:

      > マイク さん
      コメントありがとうございます!
      連絡が遅くなり申し訳ありません…。

      現在、教師と生徒2人だけの個別のクラスルームを複数人分(大量になる可能性も)作る必要があります。作るタイミングがバラバラなので、クラスルームの取得、生徒一覧の取得もトリガーでオートメーション化はできたらいいなと思っています。もちろん、生徒の投稿の通知は継続して使用したいです。
      このオートメーション化は可能でしょうか?可能だとすれば、どのようにしたらいいでしょうか?
      >> Google Classroom の「クラス」を GAS で一括で作成することは可能です!
      ただ、初めてだとなかなか難しいかなと思います…。実は、そのようなサービスも出始めていたりしますね。
      作成した後に、この通知機能をつけていく感じになりますね!
      ただ、2人だけのクラスであれば、質問か何かを投稿しておいて、そこから連絡してね。というパターンや、
      2人だけということは、密室ということになるので、それなら Google チャット のスペースを作って、そこでやり取りでも良いのかもしれません。管理者も確認できますしね。
      ご質問の内容を全て組み込むプログラムだと、なかなかハードになる気がします😅
      可能ではあります!!!
      もしよろしければ、個別でもご相談いただければと思います!!

タイトルとURLをコピーしました