質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

メール

メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

3回答

1617閲覧

GASを使用してGoogleカレンダーでイベントを作成、更新、削除をしたら、スプレッドシートを通してその内容を任意のメールアドレスに送信

kks

総合スコア3

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

メール

メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

2クリップ

投稿2024/04/10 09:02

編集2024/04/30 10:00

実現したいこと

表題の件ですがGASを使用してGoogleカレンダーでイベントを作成、更新、削除した場合、
任意のメールアドレスに送信されるという仕組みです。

発生している問題・分からないこと

今回の場合、
以下の点で困っています。

・なぜかメール通知がなされない
・削除の場合の送信ができない

該当のソースコード

GAS

1function monitorMyCalendar(e) { // 関数名も変えました 2 if (e) { 3 try { 4 // 表示用の文字列 5 const isNotExist = 'が設定されていません'; 6 7 // 過去にイベントオブジェクトが複数発生(スクリプトが複数起動)したことへの対応 8 const lock = LockService.getScriptLock(); 9 lock.waitLock(0); 10 11 // プロパティサービスから前回実行日時を取得 12 const properties = PropertiesService.getScriptProperties(); 13 const lastUpdated = new Date(properties.getProperty('lastUpdated')); 14 const noticedDate = formatDate_(lastUpdated); 15 16 // スクリプトの実行日時を取得 17 const currentTime = new Date(); 18 const currentDate = formatDate_(currentTime); 19 20 // 実行日と2週間後及び6ヶ月後の日付を生成 21 const today = new Date(); 22 today.setHours(0, 0, 0, 0); // 時刻をクリア 23 const twoWeeksLater = new Date(today); 24 twoWeeksLater.setDate(twoWeeksLater.getDate() + 14); // 2週間後の日付 25 const sixMonthsLater = new Date(today); 26 sixMonthsLater.setMonth(today.getMonth() + 6); // 6ヶ月後の日付 27 28 // 更新されたカレンダーを6ヶ月後まで取得 29 const calendar = CalendarApp.getCalendarById(e.calendarId); 30 const events = calendar.getEvents(today, sixMonthsLater); // 6ヶ月後までの予定を取得 31 32 let noticeCount = 0; // 通知されるイベントの数をカウントする変数 33 const mailBodies = []; // 通知内容を蓄積する配列 34 const twoWeeksMap = new Map(); 35 36 // 追加・更新された予定を検出 37 for (const event of events) { 38 const eventUpdated = event.getLastUpdated(); 39 const isNewEvent = eventUpdated > lastUpdated || event.getStartTime() > lastUpdated; // 新しいイベントまたは更新されたイベントかどうかを判定 40 if (eventUpdated > twoWeeksLater) { 41 break; 42 } else if (isNewEvent) { 43 twoWeeksMap.set(event.getId(), eventUpdated); 44 // メール通知項目を生成 45 const eventDetails = { 46 title: event.getTitle() || 'タイトル' + isNotExist, 47 startTime: event.getStartTime() ? formatDate_(event.getStartTime()) : '開始日時' + isNotExist, 48 endTime: event.getEndTime() ? formatDate_(event.getEndTime()) : '終了日時' + isNotExist, 49 updateTime: formatDate_(eventUpdated), 50 description: event.getDescription() || '詳細' + isNotExist, 51 location: event.getLocation() || '場所' + isNotExist, 52 url: 'https://www.google.com/calendar/event?eid=' + Utilities.base64Encode(event.getId().split('@')[0] + ' ' + e.calendarId), // URL を直接指定 53 calendarId: e.calendarId, 54 calendarName: calendar.getName(), 55 }; 56 // メール本文を蓄積する 57 mailBodies.push(eventDetails); 58 noticeCount++; // 通知されるイベントの数を増やす 59 } 60 } 61 62 // 削除確認用の予定の控えをスプレッドシートから復元し、2週間分のみ抽出(シート名はカレンダーIDの最初の16文字) 63 const ss = SpreadsheetApp.openById("シートID"); 64 const sheet = ss.getSheetByName(e.calendarId.slice(0, 16)) ?? ss.insertSheet(e.calendarId.slice(0, 16)); 65 const savedEvents = sheet.getDataRange().getValues(); 66 const twoWeeksSavedEvents = savedEvents.filter(data => data[5] >= today && data[5] <= twoWeeksLater); 67 68 // 削除されたイベントIDのリストを格納するための配列 69 const deletedEventIds = []; 70 71 // 2週間分の保存されたイベントを反復処理 72 for (const data of twoWeeksSavedEvents) { 73 if (!twoWeeksMap.has(data[0])) { 74 // 削除されたイベントIDを検出し、deletedEventIds に追加 75 deletedEventIds.push(data[0]); 76 } 77 } 78 79 // deletedEventIds を元に削除されたイベントの詳細を取得し、メール通知の準備を行う 80 for (const eventId of deletedEventIds) { 81 // 削除されたイベントの詳細を取得 82 const deletedEventData = savedEvents.find(data => data[0] === eventId); 83 84 // 削除されたイベントの詳細が見つかった場合、メール通知項目を生成して mailBodies に追加 85 if (deletedEventData) { 86 const eventDetails = { 87 title: deletedEventData[3] || 'タイトル' + isNotExist, 88 startTime: deletedEventData[5] ? formatDate_(deletedEventData[5]) : '開始日時' + isNotExist, 89 endTime: deletedEventData[6] ? formatDate_(deletedEventData[6]) : '終了日時' + isNotExist, 90 updateTime: formatDate_(calendar.getEventById(eventId).getLastUpdated()), 91 description: deletedEventData[8] || '詳細' + isNotExist, 92 location: deletedEventData[7] || '場所' + isNotExist, 93 url: '', 94 calendarId: e.calendarId, 95 calendarName: calendar.getName(), 96 }; 97 // メール本文を蓄積する 98 mailBodies.push(eventDetails); 99 noticeCount++; // 通知されるイベントの数を増やす 100 } 101 } 102 103 if (mailBodies.length > 0) { 104 // 開始日時順に並び替え 105 mailBodies.sort((a, b) => new Date(a.startTime) - new Date(b.startTime)); 106 // メールを送信 107 sendEmailNotification_(mailBodies, { noticedDate, currentDate }, properties, lastUpdated); 108 // 最後の通知時刻を保存 109 properties.setProperty('lastUpdated', currentTime.toISOString()); 110 } 111 Logger.log('通知されるイベントの数: ' + noticeCount); 112 113 // 6ヶ月分の予定の控えを更新(保存) 114 if (events.length > 0) { 115 const values = events.map(event => [ 116 event.getId(), // イベントID[0] 117 calendar.getName(), // カレンダー名[1] 118 e.calendarId, // カレンダーID[2] 119 event.getTitle(), // タイトル[3] 120 event.getLastUpdated(), // 最終更新日時[4] 121 event.getStartTime(), // 開始日時[5] 122 event.getEndTime(), // 終了日時[6] 123 event.getLocation(), // 場所[7] 124 event.getDescription(), // 詳細[8] 125 ]); 126 sheet.clearContents(); 127 sheet.getRange(1, 1, values.length, values[0].length).setValues(values); 128 } 129 130 // スクリプトのロックを解放 131 Utilities.sleep(300); 132 lock.releaseLock(); 133 134 } catch (error) { 135 if (error.toString().includes('Lock timeout')) { 136 Logger.log('実行中のスクリプトが重複しているので処理を中断しました'); 137 } else { 138 Logger.log('予定の確認中に次のエラーが発生しました: ' + error); 139 } 140 } 141 } else { 142 console.log('エディタからは実行できません'); 143 } 144} 145 146// 日付を指定された形式に整形(日付が文字列の場合に対応) 147function formatDate_(date) { 148 return Utilities.formatDate(new Date(date), 'JST', 'yyyy/MM/dd HH:mm'); // 日本時間で表示 149} 150 151// 通知を送信 152function sendEmailNotification_(mailBodies, date, properties, lastUpdated, isNewEvent, isDeletedEvent) { 153 try { 154 const lastNotificationDate = new Date(properties.getProperty('lastNotificationDate')); 155 const currentTime = new Date(); 156 157 // 前回の通知日時と現在の日時を比較し、新しいイベントまたは削除されたイベントがある場合にメール通知を送信する 158 if (lastNotificationDate < lastUpdated && currentTime >= lastUpdated && (isNewEvent || isDeletedEvent)) { 159 const recipientEmail = 'test@gmail.com'; // 送信先のメールアドレスを設定してください 160 161 // 新しいイベントの情報を含む通知メール 162 if (isNewEvent) { 163 const subject = "Googleカレンダーに新しいイベントが追加されました"; 164 let body = '前回の通知(' + date.noticedDate + ')以降、Googleカレンダーに新しいイベントが追加されました。\n' + 165 '今回の通知(' + date.currentDate + ')対象のカレンダー名: ' + mailBodies[0].calendarName + '\n\n'; 166 167 for (const item of mailBodies) { 168 body += 169 '作成日時: ' + item.updateTime + '\n' + 170 'タイトル: ' + item.title + '\n' + 171 '開始日時: ' + item.startTime + '\n' + 172 '終了日時: ' + item.endTime + '\n' + 173 '場所: ' + item.location + '\n' + 174 '詳細: ' + item.description + '\n' + 175 'URL: ' + item.url + '\n\n'; 176 } 177 MailApp.sendEmail(recipientEmail, subject, body); 178 Logger.log('新しいイベントの通知メールが送信されました: ' + body); 179 } 180 181 // 削除されたイベントの情報を含む通知メール 182 if (isDeletedEvent) { 183 const subject = "Googleカレンダーのイベントが削除されました"; 184 let body = '前回の通知(' + date.noticedDate + ')以降、Googleカレンダーからイベントが削除されました。\n' + 185 '今回の通知(' + date.currentDate + ')対象のカレンダー名: ' + mailBodies[0].calendarName + '\n\n'; 186 187 for (const item of mailBodies) { 188 body += 189 '削除日時: ' + item.updateTime + '\n' + 190 'タイトル: ' + item.title + '\n' + 191 '開始日時: ' + item.startTime + '\n' + 192 '終了日時: ' + item.endTime + '\n' + 193 '場所: ' + item.location + '\n' + 194 '詳細: ' + item.description + '\n\n'; 195 } 196 MailApp.sendEmail(recipientEmail, subject, body); 197 Logger.log('削除されたイベントの通知メールが送信されました: ' + body); 198 } 199 200 // 最後の通知時刻を保存 201 properties.setProperty('lastNotificationDate', currentTime.toISOString()); 202 } else { 203 Logger.log('新しいイベントまたは削除されたイベントがないか、前回の通知以降に新しいイベントまたは削除されたイベントがありません。メールを送信しませんでした。'); 204 } 205 } catch (error) { 206 // メール送信中にエラーが発生した場合、エラーメッセージをログに出力する 207 Logger.log('通知メールの送信中にエラーが発生しました: ' + error); 208 } 209} 210 211

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

まずはトリガーの設定は以下に設定しています。

今回はいくつか同じ内容が来てしまうのでその場合は
removeDuplicatesFromSheet関数で削除を行っていますが
一度のメールがこのコードですと「0通」になってしまいます。

if (!lastEmailSent || (currentTime - lastEmailSent) >= emailInterval) {

上記の条件分岐が当てはまっていない気がします。
すみませんが皆様からのご教示のほどよろしくお願いいたします。

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YellowGreen

2024/04/10 23:30

追試してみましたが、正常に(?)2通のメールが届きました。 通知されるイベントがログに表示されていて、通知されるイベントの数が0なので、 eventIdのチェックで除外されているのでは?(通知済みの予定を変更したとか) なお、当方にはログが2つ残り、ログにはそれぞれ1通のメール送信のログがありましたが、 そちらのログで通知される予定の表示が2通分あって9秒の間隔が空いているのが不思議です。 カレンダーを共有していて、それぞれのカレンダーに同じ予定が表示されるようになっていますか。
kks

2024/04/11 00:47

YellowGreen様 先日はありがとうございました、 またコメントもありがとうございます。 すみませんが2つほど不明点がございます。 >eventIdのチェックで除外されているのでは?(通知済みの予定を変更したとか) →こちらもう少し教えていただけますでしょうか? 例えば既にあるイベントの更新(タイトル変更、時間変更等)のみの通知なのですが。 >カレンダーを共有していて、それぞれのカレンダーに同じ予定が表示されるようになっていますか。 →カレンダーは共有されていますが、他にグーグルカレンダー側で何かしらの条件があるのでしょうか? よろしくお願いいたします。
YellowGreen

2024/04/11 01:44

前回と異なり、今回のコードは次のチェックが追加されていますので、 作成時に通知済みのイベントは対象外になりますよ。 // イベントのIDが通知済みリストに含まれていないかを確認 if (!notifiedEvents.includes(eventId)) { // 通知されていない場合のみ通知を送信
kks

2024/04/11 01:59 編集

コメントありがとうございます。 通知済みにも許可得るようにしましたが、それでもメールに送信されませんね。。 以下がその時のログです。「TEST77777」が変更されたイベント名です。 ======= 2024/04/11 10:52:46 情報 通知されるイベント: TEST77777 (2024/04/13 20:45 - 2024/04/13 22:15) 2024/04/11 10:52:46 情報 通知されるイベントが既に通知済みです: TEST77777 2024/04/11 10:52:48 情報 通知されるイベント: TEST77777 (2024/04/13 20:45 - 2024/04/13 22:15) 2024/04/11 10:52:48 情報 通知されるイベントが既に通知済みです: TEST77777 2024/04/11 10:52:57 情報 通知されるイベント: TEST77777 (2024/04/13 20:45 - 2024/04/13 22:15) 2024/04/11 10:52:57 情報 通知されるイベントが既に通知済みです: TEST77777 2024/04/11 10:52:57 情報 通知されるイベントの数: 0 =======
codemaker

2024/04/11 22:20

発生している状況についての説明が少ないでので、何をしようとして何が問題なのかが良くわかりませんが。 「なぜかメール通知がなされない」 確かに、なぜなんでしょうね。 質問にあるスクリプトでスプレッドシートのIDなどを書き換えてみました。 なぜか正常にメールが送信されましたので何が問題なのかわからないままです。 IDやシート名やメールアドレスを再確認しましたか?
kks

2024/04/12 00:52

atlanticSalmon様 コメントありがとうございます。 該当のソースコードで 例えば「TEST1」というカレンダーイベント更新しました。 その時monitorAllCalendars関数内のログは ====== 2024/04/12 9:44:48 情報 イベントがスプレッドシートに追加されました: TEST1 2024/04/12 9:44:51 情報 イベントがスプレッドシートに追加されました: TEST1 2024/04/12 9:45:01 情報 イベントがスプレッドシートに追加されました: TEST1 2024/04/12 9:45:01 情報 スプレッドシートに追加されたイベントの数: 3 ====== と必ず出力されます。 ただし次にメール送信がされる MailApp.sendEmail の処理まで届いていないため、メールが届いていないと思われます。 >IDやシート名やメールアドレスを再確認しましたか? すみませんが以下の件ですよね? ===== var spreadsheetId = 'スプレッドシートのID'; var recipientEmail = '任意のメールアドレス'; // 送信先のメールアドレス ===== はい、こちらは間違いなくカレンダーに書き込みがありますし、IDは間違っていないかと思います。 スプレッドシートやメールアドレス制限がかかることがあったりしますでしょうか?
codemaker

2024/04/12 01:02

なぜかシート名に触れられていませんが、 2箇所あるシート名は確認しましたか? それと、時間主導型トリガーで実行されるremoveDuplicatesFromSheetは、 なぜ // 更新されたイベントのみを抽出 var updatedEvents = newData.filter(function(row) { return row[5] !== ''; // URLが空でない場合、更新されたイベントとみなす }); で更新されたイベントのみが抽出されるとお考えでしたか? URLは送信後もそのままなので、 ここで必ず更新されたイベントと判断されます。 時間主導型のトリガーを5分ごとに設定すると 実行されるたびに同じメールが何度も届きます。
codemaker

2024/04/12 01:11

追加です。 131行目のvar dataRange = sheet.getRange(range);は、データがないシートの全ての行を確認する必要なないので、var dataRange = sheet.getRange(range + sheet.getLastRow());とすべきでは。
kks

2024/04/12 01:11

失礼しました。 var sheetName = 'カレンダー変更通知の管理'; こちらも同じで問題ありませんでした。 「更新されたイベントのみを抽出」部分は それそれイベントの内容を抽出(タイトル名、内容等)してそれをメール内容に含めて送信しようと考えていました。 条件文を外すとメールはきますがおっしゃる通りで時間主導型トリガーの設定のため 定期的に送られてきて困っています。
codemaker

2024/04/12 01:14

「条件文を外すとメールはきます」 68、69行目でURLも含めてシートに記入していますが、 メール送信前のシートにURLは記入されていないのですか?
kks

2024/04/12 01:37

ご指摘ありがとうございます。 >131行目のvar dataRange = sheet.getRange(range);は、データがないシートの全ての行を確認する必要なないので、var dataRange = sheet.getRange(range + sheet.getLastRow());とすべきでは。 →上記のソースコードに反映して修正しました。 >68、69行目でURLも含めてシートに記入していますが、 >メール送信前のシートにURLは記入されていないのですか? →ごめんなさい、こちらの部分がわかりかねるのですが、具体的に教えていただけますか?
YellowGreen

2024/04/12 02:01

68,69行目でURLも含めてシートに記入しているので、 164-167行目のrow[5] !== ''はtrueになるので、(F列にURLが記入されているので) 重複削除後の全ての行が毎回updatedEventsに格納されるのではないですか。 そのため、時間主導型のトリガーでシートに記入されている全ての予定が毎回通知されています。
codemaker

2024/04/12 02:05

シートに記入されているイベントを確認してみてください。 全ての予定にURLは記入されていると思います。 URLが空白かどうかで行を選択すると毎回全ての行が選択されます。 メールは全ての行を対象に送信されることになります。
codemaker

2024/04/12 02:07

私より丁寧な解説がありましたね。
YellowGreen

2024/04/12 02:14

スプレッドシートで重複を回避しようとしているところで恐縮ですが、 一度これまで試行してきたプロジェクトの全てのトリガーを解除した上で、 新規にファイルを作成して、 そのスクリプトエディタに私が回答欄で提案したスクリプトをコピペして、 メールアドレスを通知先に設定してから、 カレンダーから発動するトリガーを新たに設定してみて試していただけますか。 これまで作成してきた関数名の重複やトリガーの競合などを無くして 試行するためです。
kks

2024/04/12 02:34 編集

atlanticSalmon様 YellowGreen様 色々とご指摘ありがとうございます。 すみません、ひとつわかったことがありますので共有します。 自分のメールアドレスが「testA@gmail.com」をrecipientEmailにセットして、 自分でカレンダーイベント更新するとメールが来ません。 他人のメールアドレス「testB@gmail.com」をrecipientEmailにセットして、 自分でカレンダーイベント更新すると「testB@gmail.com」宛てにメールが1通届きました。 他人のメールアドレス「testB@gmail.com」をrecipientEmailにセットして、 他人でカレンダーイベント更新するとメールが来ません。 恐らくGoogle カレンダーの設定のほうで問題があるという事でしょうか?
codemaker

2024/04/12 02:35

自身のアドレスにもメールは届きます。ブラウザのGmailでは届いているのを確認することができます。 メールソフトなどメールを確認する方法(スレッド表示で送信済みの方に分類されるなど)の違いでしょうか。
codemaker

2024/04/12 02:44

メールソフトが原因かどうかは、ご自身でご自身にメールを送信してみて確認できると思います。
kks

2024/04/12 02:51

atlanticSalmon様 現在使用しているのがGmailのメールアドレスです、他人の方も同様です。 自分自身で送信したら、メールが届きます。 スレッドで何か分けているという事もありません(迷惑メール等)。 >自身のアドレスにもメールは届きます。ブラウザのGmailでは届いているのを確認することができます。 こちらの事象の再現できないので、何とも言えないですね。。
YellowGreen

2024/04/12 02:56 編集

当方でもrecipientEmailを自分のアドレスに変更しても届きます。 念のためですが、テスト用のアカウントで使い慣れていないなどで アドレスの記入誤りはないでしょうか。 それから、送信済みに送信履歴があるかどうかは確認できますか。
kks

2024/04/12 02:55

YellowGreen様 ご確認ありがとうございます。 recipientEmailでセットしてほかの方でもイベント更新通知が来るということは セットしたメールアドレスに何かしらの設定等に不具合があるということでしょうか?
codemaker

2024/04/12 03:03

「メールアドレスに何かしらの設定等に不具合」 ためしに誤ったメールアドレスを設定してみたのですが、 スクリプトによる送信後にバウンスメールは返ってきません。 送信済みには誤ったアドレスへの送信記録が残っています。
kks

2024/04/12 03:04

たびたびすみません ====== 自分のメールアドレスが「testA@gmail.com」をrecipientEmailにセットして、 自分でカレンダーイベント更新するとメールが来ません。 他人のメールアドレス「testB@gmail.com」をrecipientEmailにセットして、 自分でカレンダーイベント更新すると「testB@gmail.com」宛てにメールが1通届きました。 他人のメールアドレス「testB@gmail.com」をrecipientEmailにセットして、 他人でカレンダーイベント更新するとメールが来ません。 ====== →こちらですが他人のメールアドレスが1通着たのは「招待メール」であって 今回のGASを通したメールではありませんでした。。 つまり ====== 他人のメールアドレス「testB@gmail.com」をrecipientEmailにセットして、 自分でカレンダーイベント更新すると「testB@gmail.com」宛てにもきませんでした ====== という事になります。
codemaker

2024/04/12 03:06

そのアカウントのブラウザのGmailで送信済みを確認しましたか?
codemaker

2024/04/12 03:09

もう一つは、 更新のタイミングは60秒以上経過後になっていますか?
codemaker

2024/04/12 03:12

「60秒以上経過後」 とは、上のスクリプトの場合です。
YellowGreen

2024/04/12 03:39 編集

> 他人のメールアドレス「testB@gmail.com」をrecipientEmailにセットして、 > 自分でカレンダーイベント更新すると「testB@gmail.com」宛てにもきませんでした > ====== > > という事になります。 結局どうやってもメールは送信されていないということでしょうか。 当方の回答欄へのコメントはご覧になっていますか。
kks

2024/04/12 03:57

atlanticSalmon様 >そのアカウントのブラウザのGmailで送信済みを確認しましたか? こちらは以前から届いています。 >もう一つは、 >更新のタイミングは60秒以上経過後になっていますか? およそ1分後のタイミングになっています。 >「60秒以上経過後」 >とは、上のスクリプトの場合です。 こちら認識合っています。
kks

2024/04/12 04:00

YellowGreen様 >念のためですが、テスト用のアカウントで使い慣れていないなどで >アドレスの記入誤りはないでしょうか。 こちらは何度も見返しましたが、誤りはありませんでした。 >それから、送信済みに送信履歴があるかどうかは確認できますか。 Gamil送信済みで確認ができます、複数メールは一度に一斉メールが来ている履歴が残っています。 >結局どうやってもメールは送信されていないということでしょうか。 こちらスプレッドシートにかませる方法と、別回答のメールアドレスに送信の2パターンですが どちらとも「recipientEmail」にセットしたメールアドレスに届きませんでした。
codemaker

2024/04/12 09:09

送信済み記録があるのに届かないのは、 やはり、メールの受信環境などのスクリプト以外の要因ではないでしょうか。
kks

2024/04/15 07:37

atlanticSalmon様 コメントありがとうございます。 >やはり、メールの受信環境などのスクリプト以外の要因ではないでしょうか。 Google側の設定を確認してみましたが、デフォルトのままで特に何か設定を触ったという事もありませんでした。
YellowGreen

2024/04/19 18:49

カレンダーの更新トリガーでイベントオブジェクトが複数発生する現象が解消されたようですね。
codemaker

2024/04/21 00:11

実行日から6ヶ月後までの予定の配列をカレンダーから取得 2週間分の予定の配列は、6ヶ月分の予定の配列に対し .filter(開始日時が2週間後の日以前)メソッドで抽出できますので、 6ヶ月間の予定②を取得した後で2週間分にできますよ。 シートから取得した①の配列の方も同じように.filterメソッドで 実行日以降で2週間後以内の要素を抽出すれば、 2つの配列の差分をとることで削除された予定が取り出せると思います。
codemaker

2024/04/24 16:43 編集

回答された方からのスクリプトの提示がなくなったら無反応になりましたが、 結局この質問は?
kks

2024/04/30 09:33

atlanticSalmon様 ご連絡が遅くなり申し訳ございません。 本文のほうを更新しましたが未だ、以下のメールタイトルでメール2通来てしまうのと Googleカレンダーのイベント通知 Googleカレンダーのイベントが更新されました 「削除」の通知メールだけが飛んできていない状況です。
codemaker

2024/04/30 10:17

久しぶりに通知が来たので反応しました。 憶測になりますが、これまでの経緯を見ていると質問者様はコードをご理解されていなくてコピペすれば動くものを要求するために、回答がある度に質問を変更して回答者の回答が的ハズレの回答であるように装っているのだと思いますが。。。 コピペで動くコードが欲しいのであれば、Yahoo!知恵袋に質問されてはどうでしょうか。ここと違ってスクリプトの作成依頼に厳しくないですよ。マルチポストにならないようにこちらには同じ質問を投稿されないように。 あくまでもこれまでの経緯からの憶測(妄想)ですので違いましたらごめんなさい。
YellowGreen

2024/05/01 22:41

既に解決済みとなっていますが、試してみました。 > 以下のメールタイトルでメール2通来てしまうのと > > Googleカレンダーのイベント通知 > Googleカレンダーのイベントが更新されました > > 「削除」の通知メールだけが飛んできていない状況です。 について、 回答のコードでメールアドレスの部分だけを書き換えて利用すると、 通知は一つだけで削除された予定も通知されます。 おかしいのは、 > Googleカレンダーのイベント通知 というタイトルのメールは、 回答のsendEmailNotification_のコードにも 質問者様が独自に変更している方のsendEmailNotification_のコードにもないので 質問者様が別なスクリプトを実行してそちらの通知が届いているということだと考えられます。 削除された時の通知が来ないのは、 回答のsendEmailNotification_を使わずに 独自に必要のないコードを追加・変更してしいることが 原因と考えられます。 これは、動作不良となるのが当前です。
guest

回答3

0

自己解決

こちらの方法(GAS)ではなく、別のZoomアプリを介して対応する方向で実現にいたることができました。
ですので、こちらひとまず解決いたしました。

投稿2024/05/01 00:44

kks

総合スコア3

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

質問者様から何の反応もなくなりましたが、
参考までにコードをアップしておきます。

JavaScript

1// 質問者様から提示いただいたコードに修正を加えたバージョン 2// (質問内容の変更・追加が繰り返されたので、かなり変わってしまっています) 3function monitorMyCalendar(e) { // 関数名も変えました 4 if (e) { 5 try { 6 // 表示用の文字列 7 const isNotExist = 'が設定されていません'; 8 9 // 過去にイベントオブジェクトが複数発生(スクリプトが複数起動)したことへの対応 10 const lock = LockService.getScriptLock(); 11 lock.waitLock(0); 12 13 // プロパティサービスから前回実行日時を取得 14 const properties = PropertiesService.getScriptProperties(); 15 const lastUpdated = new Date(properties.getProperty('lastUpdated')); 16 const noticedDate = formatDate_(lastUpdated); 17 18 // スクリプトの実行日時を取得 19 const currentTime = new Date(); 20 const currentDate = formatDate_(currentTime); 21 22 // 実行日と2週間後及び6ヶ月後の日付を生成 23 const today = new Date(); 24 today.setHours(0, 0, 0, 0); // 時刻をクリア 25 const twoWeeksLater = new Date(today); 26 twoWeeksLater.setDate(twoWeeksLater.getDate() + 14); // 2週間後の日付 27 const sixMonthsLater = new Date(today); 28 sixMonthsLater.setMonth(today.getMonth() + 6); // 6ヶ月後の日付 29 30 // 更新されたカレンダーを6ヶ月後まで取得 31 const calendar = CalendarApp.getCalendarById(e.calendarId); 32 const events = calendar.getEvents(today, sixMonthsLater); // 6ヶ月後までの予定を取得 33 34 let noticeCount = 0; // 通知されるイベントの数をカウントする変数 35 const mailBodies = []; // 通知内容を蓄積する配列 36 const twoWeeksMap = new Map(); 37 38 // 追加・更新された予定を検出 39 for (const event of events) { 40 const eventUpdated = event.getLastUpdated(); 41 if (eventUpdated > twoWeeksLater) { 42 break; 43 } else if (eventUpdated > lastUpdated) { 44 twoWeeksMap.set(event.getId(), eventUpdated); 45 // メール通知項目を生成 46 const eventDetails = { 47 title: event.getTitle() || 'タイトル' + isNotExist, 48 startTime: event.getStartTime() ? formatDate_(event.getStartTime()) : '開始日時' + isNotExist, 49 endTime: event.getEndTime() ? formatDate_(event.getEndTime()) : '終了日時' + isNotExist, 50 updateTime: formatDate_(eventUpdated), 51 description: event.getDescription() || '詳細' + isNotExist, 52 location: event.getLocation() || '場所' + isNotExist, 53 url: 'https://www.google.com/calendar/event?eid=' + Utilities.base64Encode(event.getId().split('@')[0] + ' ' + e.calendarId), // URL を直接指定 54 calendarId: e.calendarId, 55 calendarName: calendar.getName(), 56 }; 57 // メール本文を蓄積する 58 mailBodies.push(eventDetails); 59 noticeCount++; // 通知されるイベントの数を増やす 60 } 61 } 62 63 // 削除確認用の予定の控えをスプレッドシートから復元し、2週間分のみ抽出(シート名はカレンダーIDの最初の16文字) 64 const ss = sheet = SpreadsheetApp.openById(SPREADSHEET_ID); 65 const sheet = ss.getSheetByName(e.calendarId.slice(0, 16)) ?? ss.insertSheet(e.calendarId.slice(0, 16)); 66 const savedEvents = sheet.getDataRange().getValues(); 67 const twoWeeksSavedEvents = savedEvents.filter(data => data[5] >= today && data[5] <= twoWeeksLater); 68 for (const data of twoWeeksSavedEvents) { 69 if (!twoWeeksMap.has(data[0])) { 70 // 削除された予定を検出 71 for (const data of deletedEvents) { 72 // メール通知項目を生成 73 const eventDetails = { 74 title: data[3] || 'タイトル' + isNotExist, 75 startTime: data[5] ? formatDate_(data[5]) : '開始日時' + isNotExist, 76 endTime: data[6] ? formatDate_(data[6]) : '終了日時' + isNotExist, 77 updateTime: formatDate_(calendar.getEventById(data[0]).getLastUpdated()), 78 description: data[8] || '詳細' + isNotExist, 79 location: data[7] || '場所' + isNotExist, 80 url: '', 81 calendarId: e.calendarId, 82 calendarName: calendar.getName(), 83 }; 84 // メール本文を蓄積する 85 mailBodies.push(eventDetails) 86 noticeCount++; // 通知されるイベントの数を増やす 87 } 88 } 89 } 90 91 if (mailBodies.length > 0) { 92 // 開始日時順に並び替え 93 mailBodies.sort((a, b) => new Date(a.startTime) - new Date(b.startTime)); 94 // メールを送信 95 sendEmailNotification_(mailBodies, { noticedDate, currentDate }); 96 // 最後の通知時刻を保存 97 properties.setProperty('lastUpdated', currentTime.toISOString()); 98 } 99 Logger.log('通知されるイベントの数: ' + noticeCount); 100 101 // 6ヶ月分の予定の控えを更新(保存) 102 if (events.length > 0) { 103 const values = events.map(event => [ 104 event.getId(), // イベントID[0] 105 calendar.getName(), // カレンダー名[1] 106 e.calendarId, // カレンダーID[2] 107 event.getTitle(), // タイトル[3] 108 event.getLastUpdated(), // 最終更新日時[4] 109 event.getStartTime(), // 開始日時[5] 110 event.getEndTime(), // 終了日時[6] 111 event.getLocation(), // 場所[7] 112 event.getDescription(), // 詳細[8] 113 ]); 114 sheet.clearContents(); 115 sheet.getRange(1, 1, values.length, values[0].length).setValues(values); 116 } 117 118 // スクリプトのロックを解放 119 Utilities.sleep(300); 120 lock.releaseLock(); 121 122 } catch (error) { 123 if (error.toString().includes('Lock timeout')) { 124 Logger.log('実行中のスクリプトが重複しているので処理を中断しました'); 125 } else { 126 Logger.log('予定の確認中に次のエラーが発生しました: ' + error); 127 } 128 } 129 } else { 130 console.log('エディタからは実行できません'); 131 } 132} 133 134// APIで同期するバージョン(Calendarサービスの登録が必要です) 135// カレンダーの更新のトリガーで起動すると増分同期して更新された予定を通知 136// 初回の同期の際は、更新されていない既存の予定も通知される 137// 手動で実行すると「既定の」カレンダーに対して初回の同期を行う 138function syncCalendar(e) { 139 try { 140 // 表示用の文字列 141 const isNotExist = 'が設定されていません'; 142 143 // 過去にイベントオブジェクトが複数発生(スクリプトが複数起動)したことへの対応 144 const lock = LockService.getScriptLock(); 145 lock.waitLock(0); 146 147 // プロパティーサービスから値を取得 148 const properties = PropertiesService.getScriptProperties(); 149 const syncToken = e ? properties.getProperty('nextSyncToken#' + e.calendarId) : ''; 150 const lastUpdated = new Date(properties.getProperty('lastUpdated#' + e.calendarId)); 151 const noticedDate = formatDate_(lastUpdated); 152 153 // 日付の処理 154 const currentTime = new Date(); // スクリプトの実行日時 155 const currentDate = formatDate_(currentTime); 156 157 // APIのオプションを設定 158 const options = syncToken ? 159 { syncToken: syncToken } : // 増分同期の場合(削除された予定を含む) 160 { timeMin: currentTime.toISOString() }; // 初回同期の場合 161 162 // メインループ 163 let noticeCount = 0; // 通知されるイベントの数をカウントする変数 164 const mailBodies = []; // 通知内容を蓄積する配列 165 const calendarId = e ? e.calendarId : CalendarApp.getDefaultCalendar().getId(); 166 const calendar = CalendarApp.getCalendarById(calendarId); 167 const events = Calendar.Events.list(calendarId, options); // カレンダーの同期 168 for (let item of events.items) { 169 if (item.status === 'cancelled') { 170 item = Calendar.Events.get(calendarId, item.id); // 削除された予定は個別に取得 171 item.summary = '【削除された予定】' + item.summary; 172 } 173 if (item.start.date) { 174 item.start.dateTime = item.start.date + ' 00:00'; 175 item.end.dateTime = item.end.date + ' 00:00'; 176 item.summary = '【終日の予定】' + item.summary; 177 } 178 if (item.recurrence) { 179 item.summary = '【定期的な予定】' + item.summary; 180 } 181 mailBodies.push({ 182 title: item.summary, 183 startTime: item.start.dateTime ? formatDate_(item.start.dateTime) : '開始日時' + isNotExist, 184 endTime: item.end.dateTime ? formatDate_(item.end.dateTime) : '終了日時' + isNotExist, 185 updateTime: item.updated ? formatDate_(item.updated) : '作成・更新日時' + isNotExist, 186 location: item.location || '場所' + isNotExist, 187 description: item.description || '詳細' + isNotExist, 188 url: item.status === 'cancelled' ? '' : item.htmlLink, 189 calendarId: calendarId, 190 calendarName: calendar.getName(), 191 }); 192 noticeCount++; 193 } 194 Logger.log('通知されるイベントの数: ' + noticeCount); 195 196 // メールを送信 197 if (mailBodies.length > 0) { 198 mailBodies.sort((a, b) => new Date(a.startTime) - new Date(b.startTime)); 199 sendEmailNotification_(mailBodies, { noticedDate, currentDate }); 200 properties.setProperty('lastUpdated#' + calendarId, currentTime.toISOString()); 201 } 202 203 // 事後処理 204 properties.setProperty('nextSyncToken#' + calendarId, events.nextSyncToken); 205 lock.releaseLock(); 206 } catch (error) { 207 if (error.toString().includes('Lock timeout')) { 208 Logger.log('既に実行中のスクリプトがあるため処理を中断しました'); 209 } else { 210 Logger.log('カレンダーの同期中に次のエラーが発生しました: ' + error); 211 } 212 } 213} 214 215// 日付を指定された形式に整形(日付が文字列の場合に対応) 216function formatDate_(date) { 217 return Utilities.formatDate(new Date(date), 'JST', 'yyyy/MM/dd HH:mm'); // 日本時間で表示 218} 219 220// 通知を送信 221function sendEmailNotification_(mailBodies, date) { 222 try { 223 const recipientEmail = '任意のメールアドレス'; // 送信先のメールアドレスを設定してください 224 const subject = "Googleカレンダーのイベントが更新されました"; 225 let body = '前回の通知(' + date.noticedDate + ')以降、Googleカレンダーのイベントが更新されました。\n' + 226 '今回の通知(' + date.currentDate + ')対象のカレンダー名: ' + mailBodies[0].calendarName + '\n\n'; 227 for (const item of mailBodies) { 228 body += 229 '作成・更新日時: ' + item.updateTime + '\n' + 230 'タイトル: ' + item.title + '\n' + 231 '開始日時: ' + item.startTime + '\n' + 232 '終了日時: ' + item.endTime + '\n' + 233 '場所: ' + item.location + '\n' + 234 '詳細: ' + item.description + '\n' + 235 'URL: ' + item.url + '\n\n'; 236 } 237 MailApp.sendEmail(recipientEmail, subject, body); 238 Logger.log('メールが送信されました: ' + body); 239 } catch (error) { 240 // メール送信中にエラーが発生した場合、エラーメッセージをログに出力する 241 Logger.log('メールの送信中にエラーが発生しました: ' + error); 242 } 243}

投稿2024/04/16 07:53

編集2024/04/26 19:15
YellowGreen

総合スコア791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kks

2024/04/17 04:50

回答2件目ありがとうございます。 「削除」に関する方法をなんとなく理解はできているのですが コード上で6か月先に保存するというところで躓いています。 うまく取得する方法はないでしょうか。 回答部分のコードを更新しています。
YellowGreen

2024/04/30 19:17 編集

> うまく取得する方法はないでしょうか。 通常の方法で 2週間の予定の取得ができているのですから、 同じように6ヶ月の予定を取得するだけです。 既存のスクリプトと組み合わせて複雑になるなら 既存のスクリプトとは別に **削除された予定を通知する機能**単体でスクリプトを作成しましょう。 既存のスクリプトとの組み合わせは、 単体のスクリプトが期待どおりに動作することを確認してからにしてはどうですか。 (コメントの一部を削除しました。)
YellowGreen

2024/04/30 19:14 編集

(コメントの一部を削除しました。) 念のための追記です。 Calendar APIでの増分同期の処理は、 list、item、getなどAPIの詳細を理解していることが前提になり、 とてもわかりにくいコードになってしまいます。 今回の質問は、新たなコードの作成依頼ではなく、 ご自身のコードの不具合修正に関する質問だったのでAPIは提案していません。
kks

2024/04/30 01:36 編集

YellowGreen様 お世話になっております。 別案件でこちらを離れており連絡が取れず申し訳ありませんでした。 まだ何もあれから検証しておりませんので随時、確認をします。
kks

2024/04/30 09:31

参考のソースコードありがとうございます。 こちらベースにやりくりしていましたが、 任意のメールアドレスに Googleカレンダーのイベント通知 Googleカレンダーのイベントが更新されました と連続してメールが飛んでしまうのと、 「削除」の時は未だメール通知が届きません。 まだやり方が異なるのでしょうか?
guest

0

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

投稿2024/04/11 02:22

編集2024/04/30 18:52
YellowGreen

総合スコア791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YellowGreen

2024/04/11 02:25

カレンダー共有のテスト環境をつくっていないので、 1つのカレンダーで試していますが、 当方での動作確認では、 カレンダーが1つだと2通のうち1通分は実行キャンセルになり、 通知は1通だけになり、予定の変更時にも通知が1通だけ届きますます。
YellowGreen

2024/04/11 02:34

テストの際は、関数名の重複がないようにトリガーを更新してみてください。
YellowGreen

2024/04/11 02:44

仮に新たなプロジェクトで実行したときは、 初回の実行時だけは、 今日以降2週間後までの予定全てが通知されてしまうと思います。
YellowGreen

2024/04/11 03:00

最後の通知日時と予定の更新日時との比較で予定が更新されたかどうかを判断しているので、 通知済みのイベントのリストを取得したり保存したりする必要はありませんでした。 回答を編集してその部分のコードを削除しました。
kks

2024/04/11 07:24

ありがとうございます。 上記のコードでも任意のメールアドレスに対して送信することがありませんでした。 また内容をカレンダーイベントをの更新した情報をスプレッドシートをかませた上で、任意のメールアドレスに送信というものに変更させていただきました。 シートにかまぜる理由は一度複数通知が来るのでそこから1通だけをチョイスしてそれをメールに送信しようと試みていますが、それでも送信されずに悩んでおります。
YellowGreen

2024/04/11 09:28 編集

お試しいただいたコードでの実行ログは、どうなっていましたか 相変わらず通知されるイベントが2つ表示されて、 通知されるイベントの数: 0 となっていたのでしょうか? お試しいただいたコードでもメールが届かないのであれば、 スクリプトの内容によるものではなく、 当方の実行環境(送信可能)と質問者様の実行環境(送信不可)との違いに起因する可能性が高いので 私には追試環境を構築できないので、 これ以上できることはないかもしれません。
kks

2024/04/11 09:44

コメントありがとうございます。 >相変わらず通知されるイベントが2つ表示されて、 >通知されるイベントの数: 0 同じログになりました、その時メールも飛ぶことがありませんでした。 ただ2通をどうしてもやめたいため、 スプレッドシートを通じての任意のメールアドレスに切り替えたという方向にシフトしました。 未だに該当のソースコードではメール飛ぶことはできませんね。。
YellowGreen

2024/04/11 11:50 編集

そうであれば、 トリガーで実行しているスクリプトが従前のものだったのではありませんか? お試しいただいたのは、 通知されるイベントが表示されてカウントが0はありえないコードです。 あるいは、独自に変更を加えたりしてませんでしょうか。 いずれにしても、 私にできることは、試しいただいたコードの提案なので、 これ以上は他の方からの回答にお任せします。
kks

2024/04/12 01:20 編集

大変失礼していました、見ているGASのソースコードではなかったです。 上記のコードを再確認してメールアドレスも任意にして実行しました。 とすると任意の設定したメールアドレスに大量のイベントメールが送られてきてしまいました。 ログの実行は最初、イベント内容が大漁旗来てしまいます。 次のログは 「実行中のスクリプトが重複しているので処理を中断しました。」 と出ていますのでその処理で問題ありませんでした。 例えば「TEST1」というカレンダーイベントが存在していたとして、 その内容を何かしたら更新したら、その「TEST1」だけを1通メールする仕様です。 今回はイベント更新のあるイベントだけでなく、99件も超えてしまいました。。
YellowGreen

2024/04/12 03:36 編集

先に書いたように、 > 初回の実行時だけは、 > 今日以降2週間後までの予定全てが通知されてしまうと思います。 2回目以降は、更新日時が保存されているので、 それ以降に作成・変更したものだけが通知されます。 少なくともこちrのスクリプトはメールが届いているようなのですが、 2回目以降をお試しいただいていますでしょうか。
kks

2024/04/12 03:53

>2回目以降をお試しいただいていますでしょうか。 こちら通知メールは着ていますが、 2回目以降も大量のメールがきてしまい、実現には難しそうです。。
YellowGreen

2024/04/12 05:22

メールが届くのがこちらのスクリプトなので、 こちらのスクリプトを通知が複数あってもメールは1通になるように修正しました。 なので、大量のメールは届かないと思います。 [スクリプトの差し替え方法] 修正前のコードを全てを削除(エディタでctrl-Aで全て選択→delete)してから、 修正後のコードを全てコピペ(コード右上の[+]のところをクリック→エディタにペースト)した上で、 "任意のメールアドレス"を書き換えて再度お試しいただけますか。 なお、メール本文に前回の通知日時が表示されるようにしてありますので、 カレンダーの変更を何度かお試しいただいて、 その日時がどのように表示されているのかをお教えくださるようお願いします。 当方では、前回の通知日時が表示されており、 2回目以降は更新した予定だけが通知されます。
kks

2024/04/12 08:55 編集

ありがとうございます。 上記設定してカレンダー内で「TEST1」というタイトル名のイベント更新をかけました。 トリガーも登録してありますので 下記のようなログが出力されました ▼1回目 2024/04/12 17:47:10 情報 通知されるイベント: 打ち合わせ (2024/04/12 12:30 - 2024/04/12…13:00) 2024/04/12 17:47:10 情報 通知されるイベント: MTG (2024/04/12 13:00 - 2024/04/12 15:00) 2024/04/12 17:47:10 情報 通知されるイベント: MTG (2024/04/12 15:00 - 2024/04/12 16:00) …以下省略 ▼2回目 2024/04/12 17:47:10 情報 実行中のスクリプトが重複しているので処理を中断しました。 と出てきました。 そしてメールアドレスを見ると 1通だけメールが来ていました。 ただし「TEST1」だけの状態だけでなく複数加筆された状態できました。 「TEST1」だけの情報が欲しいのに、その他のイベントまで書かれています。 その後、再度「TEST1」を更新してログを見ました。 ▼1回目 2024/04/12 17:50:48 情報 通知されるイベント: TEST1 (2024/04/13 22:15 - 2024/04/13 23:15) 2024/04/12 17:50:49 情報 メールが送信されました: 前回の通知(2024/04/12 17:47)以降、Googleカレンダーのイベントが更新されました。 カレンダー名: test@gmail.com タイトル: TEST1 開始日時: 2024/04/13 22:15 終了日時: 2024/04/13 23:15 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: https://calendar.google.com/calendar/render?action=VIEW&eid=3nqnjbbae9vtbblsb2f01ir8pc@google.com 2024/04/12 17:50:49 情報 通知されるイベントの数: 1 ▼2回目 2024/04/12 17:47:10 情報 実行中のスクリプトが重複しているので処理を中断しました。 と出てきました。 そしてメールアドレスを見ると1通だけきていて「TEST1」だけの内容となりました。
YellowGreen

2024/04/12 16:57 編集

ログの内容ではなく、次のようにお願いしております: > なお、メール本文に前回の通知日時が表示されるようにしてありますので、 > カレンダーの変更を何度かお試しいただいて、 > その日時がどのように表示されているのかをお教えくださるようお願いします。 メール本文の冒頭にある [前回の通知(yyyy/MM/dd HH:mm)以降、Googleカレンダーのイベントが更新されました。] の部分です。 お手数ですが、お願いします。 加えて、 今後は変更した予定だけが1通だけで通知されるようになっているのかをお教えください。 ご希望の動作がスプレッドシート経由での通知であって 直接の通知では意味がなくなってしまっているのであれば、 その旨も併せてお知らせください。(余計な提案になってしまったらごめんなさい。)
kks

2024/04/15 00:55

コメントありがとうございます。 例えば2024/04/12 18:02:16でイベント更新のトリガーが発動された時、 >前回の通知(2024/04/12 18:02)以降、Googleカレンダーのイベントが更新されました。 複数のイベントの内容が表示されます… という表示になります。 >今後は変更した予定だけが1通だけで通知されるようになっているのかをお教えください。 >ご希望の動作がスプレッドシート経由での通知であって >直接の通知では意味がなくなってしまっているのであれば、 >その旨も併せてお知らせください。(余計な提案になってしまったらごめんなさい。) →今回はできればGmailで対応はしていこうと思っています。 予定変更は1通着ますが直近のイベント複数?が盛り込まれています。
YellowGreen

2024/04/15 01:29

> >前回の通知(2024/04/12 18:02)以降、Googleカレンダーのイベントが更新されました。 > 複数のイベントの内容が表示されます… > > という表示になります。 そして、複数のイベントには、2024/04/12 18:02以降に作成・変更をしていない予定が含まれてしまっているのですね。 それらは、ご自身のアカウントがオーナーとなっているカレンダーの予定なのか共有先のカレンダーの予定なのかは決まっていますか。 それともカレンダーのオーナーに関係なく複数の未変更の予定が含まれてしまっていますか。 コードを修正して、通知対象の予定にはトリガー実行時に取得したそれぞれの予定が作成または最後に更新された日時を表示するようにしましたのでご確認ください。
kks

2024/04/15 02:52

ご確認ありがとうございます。 >それらは、ご自身のアカウントがオーナーとなっているカレンダーの予定なのか共有先のカレンダーの予定なのかは決まっていますか。 >それともカレンダーのオーナーに関係なく複数の未変更の予定が含まれてしまっていますか。 →カレンダーのオーナー関係なく、本日(2024/4/15)のイベントが最初にまとめて通知されます。 また、同じイベントを再更新したらその更新されたイベントしか書かれていないメール内容になります。 そして上記コードを参考に対応してみたら上記と同じ動作となりました。
YellowGreen

2024/04/15 03:22

あの、もしかしてカレンダーの更新以外に、スクリプトエディタからも実行していますか?
kks

2024/04/15 04:22

>もしかしてカレンダーの更新以外に、スクリプトエディタからも実行していますか? →こちら「スクリプトエディタ」とは上記のコードを入力するページの事を指しますでしょうか?
YellowGreen

2024/04/15 05:16

入力するページの上部の「実行」をクリックして起動していますか。
kks

2024/04/15 05:32

すみませんが見当たらないのでキャプチャいただけますでしょうか?
YellowGreen

2024/04/15 05:54

見当たらないということなら、手動ではスクリプトを実行していないのではないでしょうか。
YellowGreen

2024/04/15 05:57

カレンダーの予定を作成・更新した際に通知が1つしか届かない状態になっているのであれば。 当方からこれ以上回答を補正することもありませんので、 そのままお使いいただければよろしいかと思います。
kks

2024/04/15 07:36

ご確認ありがとうございます。 現状は自動でのスクリプト実行となっています。 カレンダー通知があれば通知という形です。 >カレンダーの予定を作成・更新した際に通知が1つしか届かない状態になっているのであれば。 →現状も複数メールが飛び交っている状況(まったく異なるイベントの情報も入ってきている)ですので、おそらく複数のカレンダーIDがある場合は難しいのかもしれませんね。
YellowGreen

2024/04/15 07:53 編集

いまだに複数の予定が通知されているのなら、 > コードを修正して、通知対象の予定にはトリガー実行時に取得したそれぞれの予定が作成または最後に > 更新された日時を表示するようにしましたのでご確認ください。 とお願いしておりましたが。 メールの冒頭に 「前回の通知(yyyy/MM/dd)以降、Googleカレンダーのイベントが更新されました」…① それぞれの予定ごとに 「カレンダー名: xxxxxxxx」 「作成・更新日時: yyyy/MM/dd」…② と記載があると思いますが。 この2つ(①と②)の日付の関係です。 作成・更新日時(②)の方が新しいのであれば、 前回通知以降更新されているので、 通知されるのは正常な動作です。 もし、②の日付が異常な値になっているのであれば、 教えてください。
kks

2024/04/15 08:15 編集

以下のメール文です。 恐らく登録されているカレンダー名が2つ指定されているから複数になるのでしょうか? ちなみに「TEST77777」というイベント1つを更新しています。 カレンダー名: test@gmail.com カレンダー名: 会議室B (4) となっています。 ======= 前回の通知(2024/04/15 17:01)以降、Googleカレンダーのイベントが更新されまし た。 カレンダー名: test@gmail.com 作成・更新日時: 2024/04/15 17:11 タイトル: TEST77777 開始日時: 2024/04/16 22:00 終了日時: 2024/04/16 23:00 詳細: 詳細が設定されていません 場所: 会議室B (4) URL: こちらURLは伏せます。 カレンダー名: 会議室B (4) 作成・更新日時: 2024/04/15 17:11 タイトル: TEST77777 開始日時: 2024/04/16 22:00 終了日時: 2024/04/16 23:00 詳細: 詳細が設定されていません 場所: 会議室B (4) URL: こちらURLは伏せます。 =======
YellowGreen

2024/04/15 08:23 編集

> ちなみに「TEST77777」というイベント1つを更新しています。 このとき、二つのカレンダーに登録するために、 具体的にどのような操作を行なっていますか。 例えば、サブメニューから会議室B(4)にコピーですか。
kks

2024/04/15 08:35 編集

コメントありがとうございます。 >このとき、二つのカレンダーに登録するために、 >具体的にどのような操作を行なっていますか。 >例えば、サブメニューから会議室B(4)にコピーですか。 →こちらの場合、 ・場所の変更(会議質Bから会議室Aに変更) で切り替えています。 GoogleカレンダーのUIで左下の「他のカレンダー」で登録されている会議室Aや会議室Bと紐づいています。 またそのほかの変更方法は ・タイトル名 ・開始時間、終了時間 ・添付データを付与 ・内容にコメント追加
YellowGreen

2024/04/15 08:42

1) 場所の変更で切り替えているというのは、お手数ですが、具体的な操作方法をお教えください。 2) 会議室Aや会議室Bと紐づいているとはどのようなことですか?
kks

2024/04/15 08:43

ごめんなさい、 「TEST77777」のイベントの通知が来るのは問題ないのですが、 この場合の複数通知とは、まったく関係のないイベントまでたまに拾ってきて、メール文に加筆されてしまうという事です。 つまり関係のないカレンダー名まで拾ってきてしまう事です。
kks

2024/04/15 08:50

1) 場所の変更で切り替えているというのは、お手数ですが、具体的な操作方法をお教えください。 →質問文の中に画像を追加しました。 2) 会議室Aや会議室Bと紐づいているとはどのようなことですか? →「他のカレンダー」に追加されているという事です。
YellowGreen

2024/04/15 08:50

あの、関係のないカレンダーとはどういう意味でしょうか。 もともと質問者様からご提示いただいたスクリプトは、 ご自身のアカウントに登録されている**全てのカレンダー**から 前回更新以降に更新された予定を通知するようになっていましたが… これを更新のあったカレンダーだけを参照するように変更しましょうか?
kks

2024/04/15 08:56 編集

>関係のないカレンダーとはどういう意味でしょうか。 →例えば、更新していないイベントまで通知されてしまうという事です。 その中で自分に関係のあるイベントであれば通知されるのはOKですが、自分には関係のないイベントもまで通知されるのは期待されている動作ではありません。 >もともと質問者様からご提示いただいたスクリプトは、 >ご自身のアカウントに登録されている**全てのカレンダー**から >前回更新以降に更新された予定を通知するようになっていましたが… →すみません、認識が異なるのかもしれませんが、自分に関係するイベント(新規作成、更新、削除)があったら1つ通知というのが希望です。
YellowGreen

2024/04/15 09:02 編集

> 例えば、更新していないイベントまで通知されてしまう ですから、更新されていないかどうか①と②の日時を比較して異常値があったら教えて欲しいと繰り返しお願いしているのですが…それを教えていただけないまま苦情を言われても。 > 自分に関係するイベント(新規作成、更新、削除)があったら 自分に関係するイベントかどうかはどのようにして判別できるのでしょうか? 上のお願いにも関連しますが。関係ないという予定が更新されたかどうか②の日時でご確認を。
kks

2024/04/15 09:17 編集

>ですから、更新されていないかどうか①と②の日時を比較して異常値があったら教えて欲しいと繰り返しお願いしているのですが… =========== 前回の通知(2024/04/15 09:51)以降、Googleカレンダーのイベントが更新されまし た。 カレンダー名: 会議室A (8) 作成・更新日時: 2024/04/15 10:17 タイトル: 【SF初期設定】 開始日時: 2024/04/15 13:00 終了日時: 2024/04/15 14:00 詳細: テキスト 場所: 会議室A (8) URL: URL伏せます カレンダー名: testA@gmail.com 作成・更新日時: 2024/04/15 10:17 タイトル: 【SF初期設定】 開始日時: 2024/04/15 13:00 終了日時: 2024/04/15 14:00 詳細: テキスト 場所: 会議室A (8) URL: URL伏せます カレンダー名: testB@gmail.com 作成・更新日時: 2024/04/15 11:23 タイトル: RENT 開始日時: 2024/04/16 13:30 終了日時: 2024/04/16 14:30 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URL伏せます カレンダー名: testC@gmail.com 作成・更新日時: 2024/04/15 11:23 タイトル: RENT 開始日時: 2024/04/18 13:30 終了日時: 2024/04/18 14:30 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URL伏せます カレンダー名: testD@gmail.com 作成・更新日時: 2024/04/15 11:23 タイトル: RENT 開始日時: 2024/04/23 13:30 終了日時: 2024/04/23 14:30 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URL伏せます カレンダー名: testD@gmail.com 作成・更新日時: 2024/04/15 11:23 タイトル: TOKYORENT 開始日時: 2024/04/25 13:30 終了日時: 2024/04/25 14:30 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URL伏せます カレンダー名: testE@gmail.com 作成・更新日時: 2024/04/15 10:14 タイトル: 入力 開始日時: 2024/04/18 10:00 終了日時: 2024/04/18 12:00 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URL伏せます カレンダー名: testF@gmail.com 作成・更新日時: 2024/04/15 10:17 タイトル: 【SF初期設定】 開始日時: 2024/04/15 13:00 終了日時: 2024/04/15 14:00 詳細: テキスト 場所: 会議室A (8) URL: URL伏せます カレンダー名: testG@gmail.com 作成・更新日時: 2024/04/15 10:50 タイトル: 定額減税 開始日時: 2024/04/16 12:00 終了日時: 2024/04/16 16:30 詳細: 女性就業支援センターホール 場所: 場所が設定されていません URL: URL伏せます カレンダー名: testG@gmail.com 作成・更新日時: 2024/04/15 10:54 タイトル: TEST 開始日時: 2024/04/25 00:00 終了日時: 2024/04/26 00:00 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URL伏せます カレンダー名: testA@gmail.com 作成・更新日時: 2024/04/15 11:47 タイトル: TEST1 開始日時: 2024/04/20 21:45 終了日時: 2024/04/20 22:45 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URL伏せます =========== こちらになります。 本日「TEST1」は一度更新したら他のイベントまで複数拾ってきてしまうという事象です。 メール文一番下に「タイトル: TEST1」は加筆されています。 上記の他に情報は必要になりますでしょうか? ※上のメール文は必ずあるわけではありません、たまにこのような形でメール文内容で送られてきます。
kks

2024/04/15 09:22

>自分に関係するイベントかどうかはどのようにして判別できるのでしょうか? >上のお願いにも関連しますが。関係ないという予定が更新されたかどうか②の日時でご確認を。 →イベントの判別はGASでできないのでしょうか?質問で質問してしまい、申し訳ありません。
YellowGreen

2024/04/15 09:32

繰り返しますが、**自分に関係する**予定かどうかは何をもって判断するのですか? 上にあげていただいた予定は全て前回通知日時(2024/04/15 09:51)以降に 更新されたことになっている予定です。 共有カレンダーということですが、 質問者様以外で予定を更新される方はいらっしゃらないのですか。
kks

2024/04/15 09:34

すみませんが、もうひとパターンです。 以下は 「TEST1」を更新した時、「13:00まで」というメールも届きました。 この場合は「TEST1」だけで大丈夫なのですが。。 「18:29にメール通知」は分けて2通届きました。 ======= ▼18:29にメール通知 前回の通知(2024/04/15 17:31)以降、Googleカレンダーのイベントが更新されまし た。 カレンダー名: testB@gmail.com 作成・更新日時: 2024/04/15 17:37 タイトル: 13:00まで 開始日時: 2024/04/17 10:00 終了日時: 2024/04/17 13:00 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URLは伏せます。 ▼18:29にメール通知 前回の通知(2024/04/15 18:29)以降、Googleカレンダーのイベントが更新されまし た。 カレンダー名: testA@gmail.com 作成・更新日時: 2024/04/15 18:29 タイトル: TEST1 開始日時: 2024/04/20 22:30 終了日時: 2024/04/20 23:30 詳細: 詳細が設定されていません 場所: 場所が設定されていません URL: URLは伏せます。 =======
YellowGreen

2024/04/15 09:37

実行日時が異なりますから…メールが一度に複数発送されたわけではありません。 たまたま、メールが届くのが一緒になっただけですので スクリプトでメールが遅れずに届くようにはできないです。
kks

2024/04/15 09:44

承知しました。 となりますと、任意のメールアドレスに送る時、 自分のアカウントに関するイベントの更新、作成があった場合は取得できますが、1通(自分が参加しているイベント)だけというのはやはり難しいという認識でよろしいでしょうか…?
YellowGreen

2024/04/30 19:04 編集

今まで、カレンダーの更新があったら全てのカレンダーをチェックするのがご希望と受け止めていました。 特定のカレンダーだけをチェックするようにした後も複数のカレンダーで更新メールが必要なら その分トリガーも複数(カレンダーIDごとに)設定してください。
kks

2024/04/15 09:57

ご確認ありがとうございます。 こちら修正したソースコードで試してみます。 その上でこちらでご報告させていただきます。
kks

2024/04/16 01:01

こちらありがとうございます。 本日こちらで確認をしたいと思います。 何かしらありましたら、こちらで連絡いたします。
kks

2024/04/16 02:02

ありがとうございます。 上記でスクリプト試験してみました(トリガーは再登録済み)。 基本的に問題ありません、ありがとうございます。 気になる点としましては、たまに作成・更新をかけると例ですが 以下のように2通届いてしまうことがあります(頻繁ではありません)。 こちらは更新時のタイミング的なものでしょうがないですよね。。 別件で以下のコードですがクリックすると「この予定は見つかりませんでした。」というポップアップが出てしまうことに気づきました。 すみませんが、こちらのポップアップを出さない方法はありますでしょうか? url: 'https://calendar.google.com/calendar/render?action=VIEW&eid=' + eventId, // URL を直接指定 =========== ▼2通目 前回の通知(2024/04/16 10:16)以降、Googleカレンダーのイベントが更新されまし た。 今回の通知(2024/04/16 10:16)対象のカレンダー名: test@gmail.com 作成・更新日時: 2024/04/16 10:16 タイトル: TEST4188 開始日時: 2024/04/20 21:00 終了日時: 2024/04/20 22:00 詳細: 詳細が設定されていません 場所: 会議室B URL: URL伏せます ▼1通目 前回の通知(2024/04/16 10:14)以降、Googleカレンダーのイベントが更新されまし た。 今回の通知(2024/04/16 10:16)対象のカレンダー名: test@gmail.com 作成・更新日時: 2024/04/16 10:16 タイトル: TEST4188 開始日時: 2024/04/20 21:00 終了日時: 2024/04/20 22:00 詳細: 詳細が設定されていません 場所: 会議室B URL: URL伏せます ===========
YellowGreen

2024/04/30 19:01 編集

> 以下のように2通届いてしまう 念のため、82行目を追加してみました。 > 「この予定は見つかりませんでした。」というポップアップが出てしまう 念のため、62行目のURLの取得方法を変更しておきました。
kks

2024/04/16 04:26

82行目とURLの件確認して理解ができました、ありがとうございます。 あともう1点なのですが 現在は「新規作成、更新」以外で「削除」もメールに飛ばすことは可能でしょうか?
YellowGreen

2024/04/30 18:59 編集

(コメントの一部を削除しました。) 新たなコードの提示が必要ならこの質問を改変するのではなく、 ご自身でお試しになったことを記載の上で改めて新規に質問を投稿してください。
kks

2024/04/16 07:25

そうでしたか、更新には「作成、削除」の含みもありました。申し訳ありません。 本題のタイトル変更します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問