😊
Googleカレンダーの予約スケジュールの予定をスプレッドシートに転記する
はじめに
これで作成された予定をspreadsheetに転記してほしいと依頼があったのでツールを作成する。
- 各自のGoogleアカウントでトリガーをセットする。
- 自動で23時に、自分のGoogleカレンダーから予約の説明欄に「予約者」があるものをシートに転記する。
- その際、すでにシートにあるものは転記しない。
- 自動で23時に、自分のGoogleカレンダーから予約の説明欄に「予約者」があるものをシートに転記する。
code
main.gs
function main() {
const sheetEventList = getEventListFromSheet();
const eventList = CalendarApp.getDefaultCalendar().getEventsForDay(new Date()).reduce((eventList, event) => {
const e = new Event();
e.setDataFromGoogleCalendar(event);
// ターゲットのイベントであり、またシートにないイベントをeventListに追加
if (e.isTarget() && !sheetEventList.some(sheetEvent => sheetEvent.isSame(e))) eventList.push(e);
return eventList;
}, []);
// シートに追記
Shomin.addSheetLastRow(
SHEET.calendar,
eventList.map(e => e.getOutList())
);
}
// 各自のGoogleアカウントで実行してもらうためトリガー作成をGASで処理する。このスクリプトと連動した画像がspreadsheetにある
function setTrigger(){
ScriptApp.newTrigger('main').timeBased().everyDays(1).atHour(23).create();
Browser.msgBox('トリガーを設定しました。');
}
Shominについては以下参照
class/Event.gs
class Event {
constructor(event) {
this.title;
this.startTime = dayjs.dayjs(null);
this.description;
}
setDataFromGoogleCalendar(event){
this.title = event.getTitle();
this.startTime = dayjs.dayjs(event.getStartTime());
this.description = event.getDescription();
}
setDataFromSheet(row){
this.title = row[SHEET.calendar.column.title - 1];
this.startTime = dayjs.dayjs(row[SHEET.calendar.column.startTime - 1]);
this.description = row[SHEET.calendar.column.description - 1];
}
isSame(event){
return this.getTitle() === event.getTitle() && this.getStartTimeText() === event.getStartTimeText();
}
getTitle(){
return this.title;
}
getStartTimeText(){
return this.startTime.format('YYYY/MM/DD HH:mm');
}
isTarget(){
return this.description.includes('予約者');
}
getOutList() {
const descriptionTextList = this.description.split('\n');
// 形式が変わったときにエラーにならないように念の為例外を握りつぶしている
const getDescriptionList = _ => {
try{
return [
descriptionTextList[1],
descriptionTextList[2]
];
}catch(e){
return [
e,
''
];
}
};
return [
this.title,
this.getStartTimeText(),
this.description
].concat(getDescriptionList());
}
}
sheet.gs
const SHEET = {
calendar: {
name: 'Calendar',
row: {
data: 2,
},
column: {
title: 1,
startTime: 2,
description: 3,
},
},
};
function getEventListFromSheet(){
return BaseLibrary.getSheetData(SHEET.calendar).map(row => {
const event = new Event();
event.setDataFromSheet(row);
return event;
});
}
使いたい方へ
あとは概要シートの小鳥の画像を押下したら23時に自動実行されるはずです。
結果
右端のステータス欄については依頼されていないが、あったほうがいいと思ったので追加した。データにはすべてステータスが内包されており、後続処理を考えたときにステータスの追加を主張したほうがいいことがある。
こうして書いたプログラムがみんなに運用されていくと、やりがいがありますね。
なお、過去分を一気に取り込んでもらったところ、name がとれない割合は6.14%だった。
今後直接顧客管理システムに投入する場合、この6%を少なくすることが課題になる。
Discussion