Edited at

GAS で共有カレンダーを作る

Google Calendar でチームの共有カレンダーを作っているんですが、一括で入れたいと思うとなかなか面倒なんですよね。 GAS で作ろうとして権限まわりが少し難しかったのでメモです。


全体

Date.prototype.addMinutes = function(m) {

return new Date(this.getTime() + (m * 60 * 1000));
};

/**
* @param {string} name
* @return {Calendar} カレンダー
*/

function findOrCreateCalendar(name) {
var calendar = CalendarApp.getCalendarsByName(name);
if (calendar.length > 0) {
return calendar[0];
}
return CalendarApp.createCalendar(name);
}

function addUsers(calendarId, emails) {
emails.forEach(function(email) {
Calendar.Acl.insert({
"role": "owner",
"scope": {
"type": "user",
"value": email,
},
}, calendarId);
});
}

function newJSTDate(date, time) {
return new Date(date + "T" + time + ":00+09:00");
}

function main() {
const calendar = findOrCreateCalendar("カレンダーの名前");
calendar.setSelected(true);

Calendar.Acl.insert({
"role": "reader",
"scope": {
"type": "domain",
"value": "GSuite のドメイン",
}
}, calendar.getId());
addUsers(calendar.getId(), [
// 作成者はすでに入っている
"招待する人のメールアドレス1",
"招待する人のメールアドレス2",
]);

// 以下は例
// これぐらい単純だったら CSV をインポートする方が楽かも

var startAt = newJSTDate("2019-06-24", "13:30");
calendar.createEvent("タイトル1", startAt, startAt.addMinutes(90));
startAt = newJSTDate("2019-06-24", "15:15");
calendar.createEvent("タイトル2", startAt, startAt.addMinutes(90));
startAt = newJSTDate("2019-06-24", "17:00");
calendar.createEvent("タイトル3", startAt, startAt.addMinutes(90));
}

リソースは Calendar API だけ付与しています。メニューの「リソース」→「Google の拡張サービス」から追加しましょう。


ポイント


ドキュメント


getCalendarsByName

CalendarApp.getCalendarsByName

名前では一意にならないので注意。 array が返ってきます。


Calendar.Acl

Calendar.Acl のドキュメントは App Script には無いので API Reference の方を見てください。

自分は作成時点で含まれていて変更できません。上記の addUsers に含めるとエラーになります。

GSuite のドメインで絞りたい場合は domain を利用します。メールアドレスのドメイン部分を value に指定してください。


Date

startAt や endAt に利用する Date は JavaScript と同様です。 MDN を参照すると良いです。


createEvent

何度も実行できるように冪等にして宣言的に書きたかったんですがあきらめました。タイトルで一意なら簡単なんですが。 Properties で ID を覚えたりするとできそうです。