回答編集履歴

23

 

2024/04/30 18:52

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -1,5 +1,6 @@
1
1
  回答後に質問内容が大きく変更されており、
2
2
  こちらの回答は閲覧者の参考にはならないと思います。
3
+ なので、無用な混乱を避けるために
3
- なので、このコメントだけにしました。
4
+ このコメントだけにしました。
4
5
 
5
6
 

22

 

2024/04/30 18:47

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -1,143 +1,5 @@
1
+ 回答後に質問内容が大きく変更されており、
1
- れまで経過を踏えた修正を加えてありまので、
2
+ ちら回答は閲覧者の参考にはならないと思います
2
- スクリプをお試ください
3
+ で、このコメンだけにました
3
4
 
4
- ・既存の**予定を変更しても通知が届く**ようにしました。
5
- ・同じ通知のメールが2通にならない回避策として、
6
- 1つのイベントオブジェクトで**複数のスクリプトが起動しても後発のものは中断する**ようにしました。
7
- ・メールに**前回と今回の通知日時とカレンダー名**、個別の予定ごとに**更新日時を表示**するようにしました。
8
- ・**複数の予定の更新があっても1通のメールにまとめる**ようにしました。
9
- ・**トリガーを設定したカレンダーだけを処理**するようにしました。
10
5
 
11
- なお、検証しやすいように
12
- 変数や関数名を変更・省略したり位置を変更している部分がありますのでご了承ください。
13
- GASはブラウザの互換性を気にする必要がないので、
14
- 変数はconst, letで宣言してあります。
15
-
16
- ```JavaScript
17
- function monitorAllCalendars(e) { // 関数名と動作内容が合わなくなりました…
18
- if (e) {
19
- try {
20
- // 表示用の文字列
21
- const isNotExist = 'が設定されていません';
22
-
23
- // 過去にイベントオブジェクトが複数発生(スクリプトが複数起動)したことへの対応
24
- const lock = LockService.getScriptLock();
25
- lock.waitLock(0); // このスクリプトがすでに起動していたらエラーとする
26
-
27
- // プロパティサービスから前回実行日時を取得
28
- const properties = PropertiesService.getScriptProperties();
29
- const lastUpdated = new Date(properties.getProperty('lastUpdated'));
30
- const noticedDate = formatDate_(lastUpdated);
31
-
32
- // スクリプトの実行日時を取得
33
- const currentTime = new Date();
34
- const currentDate = formatDate_(currentTime);
35
-
36
- // 実行日の日付と2週間後の日付を生成
37
- const today = new Date();
38
- today.setHours(0, 0, 0, 0); // 時刻をクリア
39
- const twoWeeksLater = new Date(today);
40
- twoWeeksLater.setDate(twoWeeksLater.getDate() + 14); // 2週間後の日付を取得
41
-
42
- // 更新されたカレンダーを処理
43
- const calendar = CalendarApp.getCalendarById(e.calendarId);
44
- let notifiedCount = 0; // 通知されるイベントの数をカウントする変数
45
- const mailBodies = []
46
- // 実行日から2週間後までの予定を対象に処理
47
- const events = calendar.getEvents(today, twoWeeksLater);
48
- if (events && events.length > 0) {
49
- for (const event of events) {
50
- const eventId = event.getId();
51
- // 通知すべきイベントが更新されたかどうかを確認
52
- if (event.getLastUpdated() > lastUpdated) {
53
- let title = event.getTitle();
54
- if (!title) {
55
- title = 'タイトル' + isNotExist;
56
- Logger.log('イベントのタイトルがありませんでした。');
57
- }
58
-
59
- // イベントの開始日時と終了日時を適切なフォーマットに変換
60
- const startTime = event.getStartTime() ? formatDate_(event.getStartTime()) : '開始日時' + isNotExist;
61
- const endTime = event.getEndTime() ? formatDate_(event.getEndTime()) : '終了日時' + isNotExist;
62
- const updateTime = event.getLastUpdated() ? formatDate_(event.getLastUpdated()) : '作成・更新日時' + isNotExist;
63
-
64
- // 通知されるべきイベントの詳細をログに出力
65
- Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + '<<' + updateTime + ')');
66
-
67
- const description = event.getDescription() || '詳細' + isNotExist;
68
- const location = event.getLocation() || '場所' + isNotExist;
69
-
70
- const eventDetails = {
71
- title: title,
72
- startTime: startTime,
73
- endTime: endTime,
74
- updateTime: updateTime,
75
- description: description,
76
- location: location,
77
- url: 'https://www.google.com/calendar/event?eid=' + Utilities.base64Encode(eventId.split('@')[0] + ' ' + e.calendarId), // URL を直接指定
78
- calendarId: e.calendarId,
79
- calendarName: calendar.getName(),
80
- };
81
-
82
- // メールを送信する
83
- mailBodies.push(eventDetails);
84
- notifiedCount++; // 通知されるイベントの数を増やす
85
- }
86
- }
87
- }
88
- if (mailBodies.length > 0) {
89
- sendEmailNotification_(mailBodies, { noticedDate, currentDate });
90
- // 最後の通知時刻を保存
91
- properties.setProperty('lastUpdated', currentTime.toISOString());
92
- }
93
- // 通知されるイベントの数をログに記録
94
- Logger.log('通知されるイベントの数: ' + notifiedCount);
95
-
96
- // スクリプトのロックを解放
97
- Utilities.sleep(300);
98
- lock.releaseLock();
99
-
100
- } catch (error) {
101
- if (error.toString().includes('Lock timeout')) {
102
- Logger.log('実行中のスクリプトが重複しているので処理を中断しました。');
103
- } else {
104
- Logger.log('monitorAllCalendarsのエラーが発生しました: ' + error);
105
- }
106
- }
107
- } else {
108
- console.log('エディタからは実行できません');
109
- }
110
- }
111
-
112
- // 日付(文字列の場合を考慮)を指定された形式に整形
113
- function formatDate_(date) {
114
- return Utilities.formatDate(new Date(date), 'JST', 'yyyy/MM/dd HH:mm');
115
- }
116
-
117
- // 通知を送信
118
- function sendEmailNotification_(mailBodies, date) {
119
- try {
120
- const recipientEmail = '任意のメールアドレス'; // 送信先のメールアドレスを設定してください
121
- const subject = "Googleカレンダーのイベントが更新されました";
122
- let body = '前回の通知(' + date.noticedDate + ')以降、Googleカレンダーのイベントが更新されました。\n' +
123
- '今回の通知(' + date.currentDate + ')対象のカレンダー名: ' + mailBodies[0].calendarName + '\n\n';
124
- for (const eventDetails of mailBodies) {
125
- body +=
126
- '作成・更新日時: ' + eventDetails.updateTime + '\n' +
127
- 'タイトル: ' + eventDetails.title + '\n' +
128
- '開始日時: ' + eventDetails.startTime + '\n' +
129
- '終了日時: ' + eventDetails.endTime + '\n' +
130
- '詳細: ' + eventDetails.description + '\n' +
131
- '場所: ' + eventDetails.location + '\n' +
132
- 'URL: ' + eventDetails.url + '\n\n';
133
- }
134
- MailApp.sendEmail(recipientEmail, subject, body);
135
- Logger.log('メールが送信されました: ' + body);
136
-
137
- } catch (error) {
138
- // メール送信中にエラーが発生した場合、エラーメッセージをログに出力する
139
- Logger.log('メールの送信中にエラーが発生しました: ' + error);
140
- }
141
- }
142
- ```
143
-

21

 

2024/04/19 18:38

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -14,15 +14,15 @@
14
14
  変数はconst, letで宣言してあります。
15
15
 
16
16
  ```JavaScript
17
- function monitorAllCalendars(e) {
17
+ function monitorAllCalendars(e) { // 関数名と動作内容が合わなくなりました…
18
18
  if (e) {
19
19
  try {
20
20
  // 表示用の文字列
21
21
  const isNotExist = 'が設定されていません';
22
22
 
23
- // 同じスクリプトが起動したときは後者をキャンセル
23
+ // 過去にイベントオブジェクトが複数発生(スクリプトが複数起動したへの対応
24
24
  const lock = LockService.getScriptLock();
25
- lock.waitLock(0); // 既にこのスクリプトが実行中ならエラーとするためロックを取得
25
+ lock.waitLock(0); // このスクリプトがすでに起動していたらエラーとする
26
26
 
27
27
  // プロパティサービスから前回実行日時を取得
28
28
  const properties = PropertiesService.getScriptProperties();
@@ -109,9 +109,9 @@
109
109
  }
110
110
  }
111
111
 
112
- // 日付を指定された形式に整形
112
+ // 日付(文字列の場合考慮)を指定された形式に整形
113
113
  function formatDate_(date) {
114
- return Utilities.formatDate(date, 'JST', 'yyyy/MM/dd HH:mm');
114
+ return Utilities.formatDate(new Date(date), 'JST', 'yyyy/MM/dd HH:mm');
115
115
  }
116
116
 
117
117
  // 通知を送信

20

不要なコードを削除しました。

2024/04/18 09:11

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  // 同じスクリプトが起動したときは後者をキャンセル
24
24
  const lock = LockService.getScriptLock();
25
- lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒だけ待機)
25
+ lock.waitLock(0); // 既にこのスクリプトが実行中ならエラーとするためロックを取得
26
26
 
27
27
  // プロパティサービスから前回実行日時を取得
28
28
  const properties = PropertiesService.getScriptProperties();
@@ -35,10 +35,9 @@
35
35
 
36
36
  // 実行日の日付と2週間後の日付を生成
37
37
  const today = new Date();
38
- today.setHours(0, 0, 0, 0);
38
+ today.setHours(0, 0, 0, 0); // 時刻をクリア
39
39
  const twoWeeksLater = new Date(today);
40
- twoWeeksLater.setDate(today.getDate() + 14); // 2週間後の日付を取得
40
+ twoWeeksLater.setDate(twoWeeksLater.getDate() + 14); // 2週間後の日付を取得
41
- twoWeeksLater.setHours(0, 0, 0, 0); // 時刻をリセットして日付のみにする
42
41
 
43
42
  // 更新されたカレンダーを処理
44
43
  const calendar = CalendarApp.getCalendarById(e.calendarId);

19

予定へののURLの取得方法を変更してみました。

2024/04/16 04:04

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -75,8 +75,8 @@
75
75
  updateTime: updateTime,
76
76
  description: description,
77
77
  location: location,
78
- url: 'https://calendar.google.com/calendar/render?action=VIEW&eid=' + eventId, // URL を直接指定
78
+ url: 'https://www.google.com/calendar/event?eid=' + Utilities.base64Encode(eventId.split('@')[0] + ' ' + e.calendarId), // URL を直接指定
79
- calendarId: calendar.getId(),
79
+ calendarId: e.calendarId,
80
80
  calendarName: calendar.getName(),
81
81
  };
82
82
 

18

ロックを解放する前にウェイトをかけてみた。

2024/04/16 03:29

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -95,6 +95,7 @@
95
95
  Logger.log('通知されるイベントの数: ' + notifiedCount);
96
96
 
97
97
  // スクリプトのロックを解放
98
+ Utilities.sleep(300);
98
99
  lock.releaseLock();
99
100
 
100
101
  } catch (error) {

17

メール通知の内容を整理しました。

2024/04/15 17:18

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -4,7 +4,7 @@
4
4
  ・既存の**予定を変更しても通知が届く**ようにしました。
5
5
  ・同じ通知のメールが2通にならない回避策として、
6
6
  1つのイベントオブジェクトで**複数のスクリプトが起動しても後発のものは中断する**ようにしました。
7
- ・メールに**前回の通知日時とカレンダー名**、個別の予定ごとに**更新日時を表示**するようにしました。
7
+ ・メールに**前回と今回の通知日時とカレンダー名**、個別の予定ごとに**更新日時を表示**するようにしました。
8
8
  ・**複数の予定の更新があっても1通のメールにまとめる**ようにしました。
9
9
  ・**トリガーを設定したカレンダーだけを処理**するようにしました。
10
10
 
@@ -31,6 +31,7 @@
31
31
 
32
32
  // スクリプトの実行日時を取得
33
33
  const currentTime = new Date();
34
+ const currentDate = formatDate_(currentTime);
34
35
 
35
36
  // 実行日の日付と2週間後の日付を生成
36
37
  const today = new Date();
@@ -86,7 +87,7 @@
86
87
  }
87
88
  }
88
89
  if (mailBodies.length > 0) {
89
- sendEmailNotification_(mailBodies, noticedDate);
90
+ sendEmailNotification_(mailBodies, { noticedDate, currentDate });
90
91
  // 最後の通知時刻を保存
91
92
  properties.setProperty('lastUpdated', currentTime.toISOString());
92
93
  }
@@ -114,12 +115,12 @@
114
115
  }
115
116
 
116
117
  // 通知を送信
117
- function sendEmailNotification_(mailBodies, noticedDate) {
118
+ function sendEmailNotification_(mailBodies, date) {
118
119
  try {
119
120
  const recipientEmail = '任意のメールアドレス'; // 送信先のメールアドレスを設定してください
120
121
  const subject = "Googleカレンダーのイベントが更新されました";
121
- let body = '前回の通知(' + noticedDate + ')以降、Googleカレンダーのイベントが更新されました。\n';
122
+ let body = '前回の通知(' + date.noticedDate + ')以降、Googleカレンダーのイベントが更新されました。\n' +
122
- body += 'カレンダー名: ' + mailBodies[0].calendarName + '\n\n';
123
+ '今回の通知(' + date.currentDate + ')対象のカレンダー名: ' + mailBodies[0].calendarName + '\n\n';
123
124
  for (const eventDetails of mailBodies) {
124
125
  body +=
125
126
  '作成・更新日時: ' + eventDetails.updateTime + '\n' +

16

メール通知の内容を整理しました。

2024/04/15 16:44

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -1,9 +1,12 @@
1
+ これまでの経過を踏まえた修正を加えてありますので、
1
- 前回の複数通知の件も含めて、次のスクリプトをお試しください。
2
+ 次のスクリプトをお試しください。
3
+
2
- 既存の予定を変更しても通知が届くようにしたのと、
4
+ 既存の**予定を変更しても通知が届く**ようにしまし
3
- 同じ予定の通知が2通にならない回避策を加え
5
+ 同じ通知のメールが2通にならない回避策として
6
+ 1つのイベントオブジェクトで**複数のスクリプトが起動しても後発のものは中断する**ようにしました。
4
- 通知カレンダー名と前回の通知日時を表示するようにしてあり、
7
+ ・メールに**前回の通知日時とカレンダー名**、個別の予定ごに**更新日時を表示**するようにしました。
5
- なおかつ**複数のカレンダーの更新があっても1通のメールにまとめる**ようにしました。
8
+ **複数の予定の更新があっても1通のメールにまとめる**ようにしました。
6
- トリガーを設定したカレンダーだけを処理しま
9
+ ・**トリガーを設定したカレンダーだけを処理**するようにしました
7
10
 
8
11
  なお、検証しやすいように
9
12
  変数や関数名を変更・省略したり位置を変更している部分がありますのでご了承ください。
@@ -36,7 +39,7 @@
36
39
  twoWeeksLater.setDate(today.getDate() + 14); // 2週間後の日付を取得
37
40
  twoWeeksLater.setHours(0, 0, 0, 0); // 時刻をリセットして日付のみにする
38
41
 
39
- // 更新されたカレンダー処理(★全てのカレンダー → 更新されたカレンダーのみに変更)
42
+ // 更新されたカレンダー処理
40
43
  const calendar = CalendarApp.getCalendarById(e.calendarId);
41
44
  let notifiedCount = 0; // 通知されるイベントの数をカウントする変数
42
45
  const mailBodies = []
@@ -59,7 +62,7 @@
59
62
  const updateTime = event.getLastUpdated() ? formatDate_(event.getLastUpdated()) : '作成・更新日時' + isNotExist;
60
63
 
61
64
  // 通知されるべきイベントの詳細をログに出力
62
- Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + ' << ' + updateTime + ')');
65
+ Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + '<<' + updateTime + ')');
63
66
 
64
67
  const description = event.getDescription() || '詳細' + isNotExist;
65
68
  const location = event.getLocation() || '場所' + isNotExist;
@@ -116,9 +119,9 @@
116
119
  const recipientEmail = '任意のメールアドレス'; // 送信先のメールアドレスを設定してください
117
120
  const subject = "Googleカレンダーのイベントが更新されました";
118
121
  let body = '前回の通知(' + noticedDate + ')以降、Googleカレンダーのイベントが更新されました。\n';
122
+ body += 'カレンダー名: ' + mailBodies[0].calendarName + '\n\n';
119
123
  for (const eventDetails of mailBodies) {
120
124
  body +=
121
- 'カレンダー名: ' + eventDetails.calendarName + '\n' +
122
125
  '作成・更新日時: ' + eventDetails.updateTime + '\n' +
123
126
  'タイトル: ' + eventDetails.title + '\n' +
124
127
  '開始日時: ' + eventDetails.startTime + '\n' +

15

 

2024/04/15 16:18

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -59,7 +59,7 @@
59
59
  const updateTime = event.getLastUpdated() ? formatDate_(event.getLastUpdated()) : '作成・更新日時' + isNotExist;
60
60
 
61
61
  // 通知されるべきイベントの詳細をログに出力
62
- Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + '<<' + updateTime + ')');
62
+ Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + ' << ' + updateTime + ')');
63
63
 
64
64
  const description = event.getDescription() || '詳細' + isNotExist;
65
65
  const location = event.getLocation() || '場所' + isNotExist;

14

トリガー設定したカレンダーだけを処理することとした。

2024/04/15 09:50

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -3,8 +3,7 @@
3
3
  同じ予定の通知が2通にならない回避策を加え、
4
4
  通知にカレンダー名と前回の通知日時を表示するようにしてあり、
5
5
  なおかつ**複数のカレンダーの更新があっても1通のメールにまとめる**ようにしました。
6
- 複数の通知が届くときはカレンダー確認てみてください
6
+ トリガーを設定したカレンダーだけ処理ます
7
- (カレンダー名の設定がない場合、IDと同じメールアドレスになります。)
8
7
 
9
8
  なお、検証しやすいように
10
9
  変数や関数名を変更・省略したり位置を変更している部分がありますのでご了承ください。
@@ -12,35 +11,35 @@
12
11
  変数はconst, letで宣言してあります。
13
12
 
14
13
  ```JavaScript
15
- function monitorAllCalendars() {
14
+ function monitorAllCalendars(e) {
15
+ if (e) {
16
- try {
16
+ try {
17
- // 表示用の文字列
17
+ // 表示用の文字列
18
- const isNotExist = 'が設定されていません';
18
+ const isNotExist = 'が設定されていません';
19
19
 
20
- // 同じスクリプトが起動したときは後者をキャンセル
20
+ // 同じスクリプトが起動したときは後者をキャンセル
21
- const lock = LockService.getScriptLock();
21
+ const lock = LockService.getScriptLock();
22
- lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒だけ待機)
22
+ lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒だけ待機)
23
23
 
24
- // プロパティサービスから前回実行日時を取得
24
+ // プロパティサービスから前回実行日時を取得
25
- const properties = PropertiesService.getScriptProperties();
25
+ const properties = PropertiesService.getScriptProperties();
26
- const lastUpdated = new Date(properties.getProperty('lastUpdated'));
26
+ const lastUpdated = new Date(properties.getProperty('lastUpdated'));
27
- const noticedDate = formatDate_(lastUpdated);
27
+ const noticedDate = formatDate_(lastUpdated);
28
28
 
29
- // スクリプトの実行日時を取得
29
+ // スクリプトの実行日時を取得
30
- const currentTime = new Date();
30
+ const currentTime = new Date();
31
31
 
32
- // 実行日の日付と2週間後の日付を生成
32
+ // 実行日の日付と2週間後の日付を生成
33
- const today = new Date();
33
+ const today = new Date();
34
- today.setHours(0, 0, 0, 0);
34
+ today.setHours(0, 0, 0, 0);
35
- const twoWeeksLater = new Date(today);
35
+ const twoWeeksLater = new Date(today);
36
- twoWeeksLater.setDate(today.getDate() + 14); // 2週間後の日付を取得
36
+ twoWeeksLater.setDate(today.getDate() + 14); // 2週間後の日付を取得
37
- twoWeeksLater.setHours(0, 0, 0, 0); // 時刻をリセットして日付のみにする
37
+ twoWeeksLater.setHours(0, 0, 0, 0); // 時刻をリセットして日付のみにする
38
38
 
39
- // 全てのカレンダーを対象処理
39
+ // 更新されたカレンダーの処理(★全てのカレンダー → 更新されたカレンダーのみ変更)
40
+ const calendar = CalendarApp.getCalendarById(e.calendarId);
40
- let notifiedCount = 0; // 通知されるイベントの数をカウントする変数
41
+ let notifiedCount = 0; // 通知されるイベントの数をカウントする変数
41
- const calendars = CalendarApp.getAllCalendars();
42
- const mailBodies = [];
42
+ const mailBodies = []
43
- for (const calendar of calendars) {
44
43
  // 実行日から2週間後までの予定を対象に処理
45
44
  const events = calendar.getEvents(today, twoWeeksLater);
46
45
  if (events && events.length > 0) {
@@ -60,7 +59,7 @@
60
59
  const updateTime = event.getLastUpdated() ? formatDate_(event.getLastUpdated()) : '作成・更新日時' + isNotExist;
61
60
 
62
61
  // 通知されるべきイベントの詳細をログに出力
63
- Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + updateTime + ')');
62
+ Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + '<<' + updateTime + ')');
64
63
 
65
64
  const description = event.getDescription() || '詳細' + isNotExist;
66
65
  const location = event.getLocation() || '場所' + isNotExist;
@@ -83,25 +82,26 @@
83
82
  }
84
83
  }
85
84
  }
85
+ if (mailBodies.length > 0) {
86
+ sendEmailNotification_(mailBodies, noticedDate);
87
+ // 最後の通知時刻を保存
88
+ properties.setProperty('lastUpdated', currentTime.toISOString());
89
+ }
90
+ // 通知されるイベントの数をログに記録
91
+ Logger.log('通知されるイベントの数: ' + notifiedCount);
92
+
93
+ // スクリプトのロックを解放
94
+ lock.releaseLock();
95
+
96
+ } catch (error) {
97
+ if (error.toString().includes('Lock timeout')) {
98
+ Logger.log('実行中のスクリプトが重複しているので処理を中断しました。');
99
+ } else {
100
+ Logger.log('monitorAllCalendarsのエラーが発生しました: ' + error);
101
+ }
86
102
  }
87
- if (mailBodies.length > 0) {
88
- sendEmailNotification_(mailBodies, noticedDate);
89
- // 最後の通知時刻を保存
90
- properties.setProperty('lastUpdated', currentTime.toISOString());
91
-
92
- }
93
- // 通知されるイベントの数をログに記録
94
- Logger.log('通知されるイベントの数: ' + notifiedCount);
95
-
96
- // スクリプトのロックを解放
97
- lock.releaseLock();
98
-
99
- } catch (error) {
100
- if (error.toString().includes('Lock timeout')) {
101
- Logger.log('実行中のスクリプトが重複しているので処理を中断しました。');
102
- } else {
103
+ } else {
103
- Logger.log('monitorAllCalendarsのラーが発生しした: ' + error);
104
+ console.log('エディタからは実行できせん');
104
- }
105
105
  }
106
106
  }
107
107
 
@@ -113,11 +113,11 @@
113
113
  // 通知を送信
114
114
  function sendEmailNotification_(mailBodies, noticedDate) {
115
115
  try {
116
- const recipientEmail = "任意のメールアドレス"; // 送信先のメールアドレスを設定してください
116
+ const recipientEmail = '任意のメールアドレス'; // 送信先のメールアドレスを設定してください
117
117
  const subject = "Googleカレンダーのイベントが更新されました";
118
118
  let body = '前回の通知(' + noticedDate + ')以降、Googleカレンダーのイベントが更新されました。\n';
119
119
  for (const eventDetails of mailBodies) {
120
- body +=
120
+ body +=
121
121
  'カレンダー名: ' + eventDetails.calendarName + '\n' +
122
122
  '作成・更新日時: ' + eventDetails.updateTime + '\n' +
123
123
  'タイトル: ' + eventDetails.title + '\n' +

13

 

2024/04/15 01:37

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -119,7 +119,7 @@
119
119
  for (const eventDetails of mailBodies) {
120
120
  body +=
121
121
  'カレンダー名: ' + eventDetails.calendarName + '\n' +
122
- '作成・更新日時' + eventDetails.updateTime + '\n' +
122
+ '作成・更新日時: ' + eventDetails.updateTime + '\n' +
123
123
  'タイトル: ' + eventDetails.title + '\n' +
124
124
  '開始日時: ' + eventDetails.startTime + '\n' +
125
125
  '終了日時: ' + eventDetails.endTime + '\n' +

12

デバッグ:ログとメールの通知に通知対象の予定の作成・更新日時を表示するようにしました。

2024/04/15 01:26

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -57,9 +57,10 @@
57
57
  // イベントの開始日時と終了日時を適切なフォーマットに変換
58
58
  const startTime = event.getStartTime() ? formatDate_(event.getStartTime()) : '開始日時' + isNotExist;
59
59
  const endTime = event.getEndTime() ? formatDate_(event.getEndTime()) : '終了日時' + isNotExist;
60
+ const updateTime = event.getLastUpdated() ? formatDate_(event.getLastUpdated()) : '作成・更新日時' + isNotExist;
60
61
 
61
62
  // 通知されるべきイベントの詳細をログに出力
62
- Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + ')');
63
+ Logger.log('通知されるイベント: ' + title + ' (' + startTime + ' - ' + endTime + updateTime + ')');
63
64
 
64
65
  const description = event.getDescription() || '詳細' + isNotExist;
65
66
  const location = event.getLocation() || '場所' + isNotExist;
@@ -68,6 +69,7 @@
68
69
  title: title,
69
70
  startTime: startTime,
70
71
  endTime: endTime,
72
+ updateTime: updateTime,
71
73
  description: description,
72
74
  location: location,
73
75
  url: 'https://calendar.google.com/calendar/render?action=VIEW&eid=' + eventId, // URL を直接指定
@@ -117,6 +119,7 @@
117
119
  for (const eventDetails of mailBodies) {
118
120
  body +=
119
121
  'カレンダー名: ' + eventDetails.calendarName + '\n' +
122
+ '作成・更新日時' + eventDetails.updateTime + '\n' +
120
123
  'タイトル: ' + eventDetails.title + '\n' +
121
124
  '開始日時: ' + eventDetails.startTime + '\n' +
122
125
  '終了日時: ' + eventDetails.endTime + '\n' +
@@ -133,3 +136,4 @@
133
136
  }
134
137
  }
135
138
  ```
139
+

11

複数の通知を1通のメールにまとめるようにしました。

2024/04/12 05:13

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -1,7 +1,8 @@
1
1
  前回の複数通知の件も含めて、次のスクリプトをお試しください。
2
2
  既存の予定を変更しても通知が届くようにしたのと、
3
3
  同じ予定の通知が2通にならない回避策を加え、
4
- 通知にカレンダー名を表示するようにしてありますので
4
+ 通知にカレンダー名と前回の通知日時を表示するようにしてあり、
5
+ なおかつ**複数のカレンダーの更新があっても1通のメールにまとめる**ようにしました。
5
6
  複数の通知が届くときはカレンダー名を確認してみてください。
6
7
  (カレンダー名の設定がない場合、IDと同じメールアドレスになります。)
7
8
 
@@ -18,11 +19,12 @@
18
19
 
19
20
  // 同じスクリプトが起動したときは後者をキャンセル
20
21
  const lock = LockService.getScriptLock();
21
- lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒待機)
22
+ lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒だけ待機)
22
23
 
23
24
  // プロパティサービスから前回実行日時を取得
24
25
  const properties = PropertiesService.getScriptProperties();
25
- const lastUpdated = properties.getProperty('lastUpdated');
26
+ const lastUpdated = new Date(properties.getProperty('lastUpdated'));
27
+ const noticedDate = formatDate_(lastUpdated);
26
28
 
27
29
  // スクリプトの実行日時を取得
28
30
  const currentTime = new Date();
@@ -37,6 +39,7 @@
37
39
  // 全てのカレンダーを対象に処理
38
40
  let notifiedCount = 0; // 通知されるイベントの数をカウントする変数
39
41
  const calendars = CalendarApp.getAllCalendars();
42
+ const mailBodies = [];
40
43
  for (const calendar of calendars) {
41
44
  // 実行日から2週間後までの予定を対象に処理
42
45
  const events = calendar.getEvents(today, twoWeeksLater);
@@ -44,7 +47,7 @@
44
47
  for (const event of events) {
45
48
  const eventId = event.getId();
46
49
  // 通知すべきイベントが更新されたかどうかを確認
47
- if (event.getLastUpdated() > new Date(lastUpdated)) {
50
+ if (event.getLastUpdated() > lastUpdated) {
48
51
  let title = event.getTitle();
49
52
  if (!title) {
50
53
  title = 'タイトル' + isNotExist;
@@ -73,18 +76,20 @@
73
76
  };
74
77
 
75
78
  // メールを送信する
76
- sendEmailNotification_(eventDetails);
79
+ mailBodies.push(eventDetails);
77
80
  notifiedCount++; // 通知されるイベントの数を増やす
78
81
  }
79
82
  }
80
83
  }
81
84
  }
85
+ if (mailBodies.length > 0) {
86
+ sendEmailNotification_(mailBodies, noticedDate);
87
+ // 最後の通知時刻を保存
88
+ properties.setProperty('lastUpdated', currentTime.toISOString());
82
89
 
90
+ }
83
91
  // 通知されるイベントの数をログに記録
84
92
  Logger.log('通知されるイベントの数: ' + notifiedCount);
85
-
86
- // 最後の実行時刻を保存
87
- properties.setProperty('lastUpdated', currentTime.toISOString());
88
93
 
89
94
  // スクリプトのロックを解放
90
95
  lock.releaseLock();
@@ -104,19 +109,21 @@
104
109
  }
105
110
 
106
111
  // 通知を送信
107
- function sendEmailNotification_(eventDetails) {
112
+ function sendEmailNotification_(mailBodies, noticedDate) {
108
113
  try {
109
114
  const recipientEmail = "任意のメールアドレス"; // 送信先のメールアドレスを設定してください
110
115
  const subject = "Googleカレンダーのイベントが更新されました";
111
- const body = 'Googleカレンダーのイベントが更新されました。\n' +
116
+ let body = '前回の通知(' + noticedDate + ')以降、Googleカレンダーのイベントが更新されました。\n';
117
+ for (const eventDetails of mailBodies) {
118
+ body +=
112
- 'カレンダー名: ' + eventDetails.calendarName + '\n' +
119
+ 'カレンダー名: ' + eventDetails.calendarName + '\n' +
113
- 'タイトル: ' + eventDetails.title + '\n' +
120
+ 'タイトル: ' + eventDetails.title + '\n' +
114
- '開始日時: ' + eventDetails.startTime + '\n' +
121
+ '開始日時: ' + eventDetails.startTime + '\n' +
115
- '終了日時: ' + eventDetails.endTime + '\n' +
122
+ '終了日時: ' + eventDetails.endTime + '\n' +
116
- '詳細: ' + eventDetails.description + '\n' +
123
+ '詳細: ' + eventDetails.description + '\n' +
117
- '場所: ' + eventDetails.location + '\n' +
124
+ '場所: ' + eventDetails.location + '\n' +
118
- 'URL: ' + eventDetails.url;
125
+ 'URL: ' + eventDetails.url + '\n\n';
119
-
126
+ }
120
127
  MailApp.sendEmail(recipientEmail, subject, body);
121
128
  Logger.log('メールが送信されました: ' + body);
122
129
 

10

 

2024/04/11 03:30

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -24,7 +24,7 @@
24
24
  const properties = PropertiesService.getScriptProperties();
25
25
  const lastUpdated = properties.getProperty('lastUpdated');
26
26
 
27
- // スクリプトの実行日時を保存
27
+ // スクリプトの実行日時を取得
28
28
  const currentTime = new Date();
29
29
 
30
30
  // 実行日の日付と2週間後の日付を生成

9

 

2024/04/11 03:20

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -83,7 +83,7 @@
83
83
  // 通知されるイベントの数をログに記録
84
84
  Logger.log('通知されるイベントの数: ' + notifiedCount);
85
85
 
86
- // 最後の通知を保存
86
+ // 最後の実行を保存
87
87
  properties.setProperty('lastUpdated', currentTime.toISOString());
88
88
 
89
89
  // スクリプトのロックを解放

8

 

2024/04/11 03:14

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -68,8 +68,6 @@
68
68
  description: description,
69
69
  location: location,
70
70
  url: 'https://calendar.google.com/calendar/render?action=VIEW&eid=' + eventId, // URL を直接指定
71
- triggerUid: "your_trigger_uid_here",
72
- authMode: "your_auth_mode_here",
73
71
  calendarId: calendar.getId(),
74
72
  calendarName: calendar.getName(),
75
73
  };

7

 

2024/04/11 03:12

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -27,7 +27,7 @@
27
27
  // スクリプトの実行日時を保存
28
28
  const currentTime = new Date();
29
29
 
30
- // 実行日の日付と2週間後の日付を取得
30
+ // 実行日の日付と2週間後の日付を生成
31
31
  const today = new Date();
32
32
  today.setHours(0, 0, 0, 0);
33
33
  const twoWeeksLater = new Date(today);

6

 

2024/04/11 03:10

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -11,7 +11,7 @@
11
11
  変数はconst, letで宣言してあります。
12
12
 
13
13
  ```JavaScript
14
- function monitorAllCalendars(e) {
14
+ function monitorAllCalendars() {
15
15
  try {
16
16
  // 表示用の文字列
17
17
  const isNotExist = 'が設定されていません';

5

 

2024/04/11 03:09

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  // 同じスクリプトが起動したときは後者をキャンセル
20
20
  const lock = LockService.getScriptLock();
21
- lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒だけ待機)
21
+ lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒待機)
22
22
 
23
23
  // プロパティサービスから前回実行日時を取得
24
24
  const properties = PropertiesService.getScriptProperties();

4

 

2024/04/11 03:07

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -20,7 +20,7 @@
20
20
  const lock = LockService.getScriptLock();
21
21
  lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒だけ待機)
22
22
 
23
- // プロパティサービスから最終更新日時を取得
23
+ // プロパティサービスから前回実行日時を取得
24
24
  const properties = PropertiesService.getScriptProperties();
25
25
  const lastUpdated = properties.getProperty('lastUpdated');
26
26
 

3

 

2024/04/11 03:04

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -5,7 +5,7 @@
5
5
  複数の通知が届くときはカレンダー名を確認してみてください。
6
6
  (カレンダー名の設定がない場合、IDと同じメールアドレスになります。)
7
7
 
8
- なお、検証しやすいように
8
+ なお、検証しやすいように
9
9
  変数や関数名を変更・省略したり位置を変更している部分がありますのでご了承ください。
10
10
  GASはブラウザの互換性を気にする必要がないので、
11
11
  変数はconst, letで宣言してあります。

2

 

2024/04/11 03:03

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -11,8 +11,6 @@
11
11
  変数はconst, letで宣言してあります。
12
12
 
13
13
  ```JavaScript
14
- const MAIL_ADDRESS = 'mutsuo.anzai@gmail.com';
15
-
16
14
  function monitorAllCalendars(e) {
17
15
  try {
18
16
  // 表示用の文字列

1

通知済みイベントのリストは使わないので、その部分のコードと取得する関数を削除しました。

2024/04/11 02:57

投稿

YellowGreen
YellowGreen

スコア731

test CHANGED
@@ -11,6 +11,8 @@
11
11
  変数はconst, letで宣言してあります。
12
12
 
13
13
  ```JavaScript
14
+ const MAIL_ADDRESS = 'mutsuo.anzai@gmail.com';
15
+
14
16
  function monitorAllCalendars(e) {
15
17
  try {
16
18
  // 表示用の文字列
@@ -20,10 +22,9 @@
20
22
  const lock = LockService.getScriptLock();
21
23
  lock.waitLock(100); // 既に実行中ならエラーとするロックを取得(0.1秒だけ待機)
22
24
 
23
- // プロパティサービスから最終更新日時と通知済みの予定を取得
25
+ // プロパティサービスから最終更新日時を取得
24
26
  const properties = PropertiesService.getScriptProperties();
25
27
  const lastUpdated = properties.getProperty('lastUpdated');
26
- const notifiedEvents = getNotifiedEvents_(properties);
27
28
 
28
29
  // スクリプトの実行日時を保存
29
30
  const currentTime = new Date();
@@ -78,9 +79,6 @@
78
79
  // メールを送信する
79
80
  sendEmailNotification_(eventDetails);
80
81
  notifiedCount++; // 通知されるイベントの数を増やす
81
-
82
- // 通知されたイベントを記録
83
- notifiedEvents.push(eventId);
84
82
  }
85
83
  }
86
84
  }
@@ -89,8 +87,7 @@
89
87
  // 通知されるイベントの数をログに記録
90
88
  Logger.log('通知されるイベントの数: ' + notifiedCount);
91
89
 
92
- // 通知されたイベントと最後の通知時間を保存
90
+ // 最後の通知時間を保存
93
- properties.setProperty('notifiedEvents', notifiedEvents.join(','));
94
91
  properties.setProperty('lastUpdated', currentTime.toISOString());
95
92
 
96
93
  // スクリプトのロックを解放
@@ -105,16 +102,12 @@
105
102
  }
106
103
  }
107
104
 
108
- // 日付を指定された形式に整形する関数
105
+ // 日付を指定された形式に整形
109
106
  function formatDate_(date) {
110
107
  return Utilities.formatDate(date, 'JST', 'yyyy/MM/dd HH:mm');
111
108
  }
112
109
 
113
- function getNotifiedEvents_(properties) {
114
- const notifiedEvents = properties.getProperty('notifiedEvents');
115
- return notifiedEvents ? notifiedEvents.split(',') : [];
110
+ // 通知を送信
116
- }
117
-
118
111
  function sendEmailNotification_(eventDetails) {
119
112
  try {
120
113
  const recipientEmail = "任意のメールアドレス"; // 送信先のメールアドレスを設定してください