見出し画像

落とし物係の先生必見!落とし物情報クラスルーム通知アプリ/AppSheet/GAS

落とし物発見

落とし物係の先生が(iPad等)でAppleSheetで写真や各種情報を登録

自動で落とし物情報のレポートを作成

作成されたレポートを指定したclassroom(基本全クラス)に配信

返却されたらその旨のレポートをclassroomで全クラスに配信

※注意サンプルを試す場合は、サブアカウント等のクラスルームで十分に行ってから、運用クラスで行なってください。

という物を作りました笑

今週、落とし物係の先生に

落とし物が出てくるたびに、朝の打ち合わせで連絡するのが無駄に感じる

という感じの相談されました。

・連絡すること自体はいいと思うんだけど、全クラスで連絡が行き届いているかわからない
・落とし物の特徴を言っても、物を見ないとわからない(黒い手袋とか笑)
・落とし物ボックスを毎回見に行くなんてこと、生徒はしない笑

という感じの課題感がありました。

こういうのってICTとかでなんとかできないですかね?的な相談を受けて、隙間時間で完成させました👍✨
(学校で使ってくれるかは不明笑)

ここからアプリのダウンロードをお願いします。

使い方

上記のAppSheetをコピーしたら、スプレッドシートが生成されます。

スプレッドシートまでの到達の仕方はこちらから↓

コピペするコードはこちら↓

function classroomdata(){
 var now = new Date();
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sht = ss.getSheetByName('クラスルーム一覧');
 var response = Classroom.Courses.list({});
 var courses = response.courses;
 var course = '';
 for (i = 0; i < courses.length; i++) {
   course = courses[i];
   sht.getRange(i+2, 1).setValue(course.name);
   sht.getRange(i+2, 2).setValue(course.id);
 }
}

//対象とするGoogleDriveフォルダのID
var TARGET_FOLDER_ID = 'ここにIDを入れてください';
//更新日時を記録するのスプレッドシートのID
var UPDATE_SHEET_ID = 'ここにIDを入れてください';
//スプレッドシートのシート名
var UPDATE_SHEET_NAME = '落とし物情報';

function updateCheck() {
 var targetFolder = DriveApp.getFolderById(TARGET_FOLDER_ID);
 var folders = targetFolder.getFolders();
 var files = targetFolder.getFiles();

 //フォルダ内を再帰的に探索してすべてのファイルIDを配列にして返す
 function getAllFilesId(targetFolder){
   var filesIdList = [];
   
   var files = targetFolder.getFiles();
   while(files.hasNext()){
     filesIdList.push(files.next().getId());
   }
   
   var child_folders = targetFolder.getFolders();
   while(child_folders.hasNext()){
     var child_folder = child_folders.next();
     //Logger.log( 'child_folder :' + child_folder );

     //Logger.log('getAllFilesId(child_folder):'+ getAllFilesId(child_folder));
     filesIdList = filesIdList.concat( getAllFilesId(child_folder) );
   }
   return filesIdList;
 }
 //Logger.log('getAllFilesId(targetFolder):' + getAllFilesId(targetFolder));
 var allFilesId = getAllFilesId(targetFolder);
 var lastUpdateMap = {};
 //Logger.log(folders)
 allFilesId.forEach(
   function( value, i ){
     var file =DriveApp.getFileById( value );
     lastUpdateMap[file.getName()] = {lastUpdate : file.getLastUpdated(), fileId: file.getId()};
   }
 );          

 // スプレッドシートに記載されているフォルダ名と更新日時を取得。
 var spreadsheet = SpreadsheetApp.openById(UPDATE_SHEET_ID);
 var sheet = spreadsheet.getSheetByName(UPDATE_SHEET_NAME);
 //Logger.log(sheet)
 var data = sheet.getDataRange().getValues();
 //Logger.log('data: ' + data)
 // 取得したデータをMapに変換。
 var sheetData = {};
 for (var i = 0; i < data.length; i++) {
   sheetData[data[i][0]] = {name : data[i][0], lastUpdate : data[i][1], rowNo : i + 1};
 }

 // 実際のフォルダとスプレッドシート情報を比較。
 var updateFolderMap = [];
 for (key in lastUpdateMap) {
   if( UPDATE_SHEET_ID == lastUpdateMap[key].fileId ){
     continue;
   }
   if(key in sheetData) {
     // フォルダ名がシートに存在する場合。
     if(lastUpdateMap[key].lastUpdate > sheetData[key].lastUpdate) {
       // フォルダが更新されている場合。
       sheet.getRange(sheetData[key].rowNo, 2).setValue(lastUpdateMap[key].lastUpdate);
       sheet.getRange(sheetData[key].rowNo, 3).setValue(lastUpdateMap[key].fileId);
       updateFolderMap.push({filename:key, lastUpdate:lastUpdateMap[key].lastUpdate, fileId:lastUpdateMap[key].fileId});
     }
   } else {
     // フォルダ名がシートに存在しない場合。
     var newRow = sheet.getLastRow() + 1;
     sheet.getRange(newRow, 1).setValue(key);
     sheet.getRange(newRow, 2).setValue(lastUpdateMap[key].lastUpdate);
     sheet.getRange(newRow, 3).setValue(lastUpdateMap[key].fileId);
     updateFolderMap.push({filename:key, lastUpdate:lastUpdateMap[key].lastUpdate, fileId:lastUpdateMap[key].fileId});
   }
 }
 //Logger.log('updateFolderMap:' + updateFolderMap)
 // 新規及び更新された情報をメール送信。
 var updateText = '';
 for( key in updateFolderMap ){
   item = updateFolderMap[key];
   updateText += 
    item.filename + ' 更新日時:' + Utilities.formatDate(item.lastUpdate, 'JST', 'yyyy-MM-dd HH:mm:ss') + '\n' 
   + DriveApp.getFileById(item.fileId).getUrl() + '\n\n'
   if (updateFolderMap.length != 0) {
     var sht = spreadsheet.getSheetByName('クラスルーム一覧');
     const lastRow = sht.getLastRow();
     var array = '';
     for(let row = 2; row <= lastRow; row++) {//クラスルームを一つずつ確認する
       array = String(sht.getRange(row, 2).getValue());//クラスルームのIDを取得する
       if(sht.getRange(row, 3).getValue() === 1){//投稿のセルが1のクラスにだけ配信する
         var data = {  //投稿する内容の設定
           "courseId" : array,//ここにクラスルームのIDが入っている
            "materials": [
           {
             "link": {
             "url": DriveApp.getFileById(item.fileId).getUrl(),//落とし物レポートのリンクを自動で挿入
             "title": "",
             "thumbnailUrl": ""
             }
           }
         ],
           "text":  "更新連絡通知\n【" + targetFolder.getName() + "】が更新されました。\n\n"+updateText,
           "assigneeMode": "ALL_STUDENTS",
           "state": "PUBLISHED"
         };
         Classroom.Courses.Announcements.create(data, array);
       }
     }
     }
 }   
}

2点修正をします。

スプレッドシートのIDを入れます。
これは、スプレッドシート開いた時のURLを見て、

https://docs.google.com/spreadsheets/d/スプレッドシートID/edit#gid=シートID

のスプレッドシートIDの部分を使ってください。

生成された落とし物レポートが保存されるドライブのIDは、Googleドライブから、

スクリーンショット 2022-01-15 12.57.47

上記の開いたところに生成されていくので、落とし物という名前がついているフォルダからIDを取得してください。
Googleドライブの場合は、URLの末尾になります。

https://drive.google.com/drive/u/1/folders/フォルダID

このフォルダIDをGASの指定された場所に貼り付けてください。

これで準備完了です。

GASを動かします。
動かし方はこちら↓

そうすると、スプレッドシートに一覧が出ているので、下記の手順でクラスルームの指定をしてください。

これで本当に準備完了!!!

動かしてみましょ。

スクリーンショット 2022-01-15 13.29.04

もちろん、このレポート様式は変更できます。

最後に改めて注意

※注意サンプルを試す場合は、サブアカウント等のクラスルームで十分に行ってから、運用クラスで行なってください。

やってみて

このnoteを書く方がよっぽど億劫だった笑

タンゴを初めて使ってみたんだけど、結構いいね🤔

これ、小学校とかならclassroomだけでなく、保護者宛に一斉メールとかしたら喜ばれません?笑

返却率も爆上がりだと思うけどな。

うちの学校使ってくれないかなー。使わないだろーなー笑

今回のソース


何かと0から1を作るのは大変だと思います。学校はどこも似たような問題課題に対応していると思います。それなのに、先生って自分だけで頑張ろうとするんですよね。ボクの資料やnoteが1になって、学校ごとの現状に合わせてカスタムしていただければと思います‼️