落とし物係の先生必見!落とし物情報クラスルーム通知アプリ/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ドライブから、
上記の開いたところに生成されていくので、落とし物という名前がついているフォルダからIDを取得してください。
Googleドライブの場合は、URLの末尾になります。
https://drive.google.com/drive/u/1/folders/フォルダID
このフォルダIDをGASの指定された場所に貼り付けてください。
これで準備完了です。
GASを動かします。
動かし方はこちら↓
そうすると、スプレッドシートに一覧が出ているので、下記の手順でクラスルームの指定をしてください。
これで本当に準備完了!!!
動かしてみましょ。
もちろん、このレポート様式は変更できます。
最後に改めて注意
※注意サンプルを試す場合は、サブアカウント等のクラスルームで十分に行ってから、運用クラスで行なってください。
やってみて
このnoteを書く方がよっぽど億劫だった笑
タンゴを初めて使ってみたんだけど、結構いいね🤔
これ、小学校とかならclassroomだけでなく、保護者宛に一斉メールとかしたら喜ばれません?笑
返却率も爆上がりだと思うけどな。
うちの学校使ってくれないかなー。使わないだろーなー笑
今回のソース
何かと0から1を作るのは大変だと思います。学校はどこも似たような問題課題に対応していると思います。それなのに、先生って自分だけで頑張ろうとするんですよね。ボクの資料やnoteが1になって、学校ごとの現状に合わせてカスタムしていただければと思います‼️