カレンダー通知の設定漏れを追加前に発見|GASでリマインダー計画をdry-run監査
ツールおじ|GoogleアカウントをAIエージェント化
リマインダーを付けたつもりなのに通知されない。反対に、同じ予定へ似た通知を重ねてしまう。カレンダーを直接更新してから気づくと、どの設定を戻せばよいか分かりにくくなります。
この記事では、Googleカレンダーへ一切書き込まず、スプレッドシート上のリマインダー計画だけをGASでdry-run監査します。空欄、日時、通知方法、何分前、重複を行番号で確認できるため、実際の予定へ反映する前のチェックに使えます。
この無料例で行うこと
- 「リマインダー計画」シートだけを読み取る
- 必須項目と入力形式を検査する
- 同じ予定キー・通知方法・何分前の重複を検出する
- 予定名や予定キーをログへ出さず、件数と行番号だけを記録する
- カレンダーの予定・通知・トリガーは作成、変更、削除しない
この例は設定前の確認専用です。既存のカレンダー通知を取得する機能や、監査後に自動反映する機能は含みません。
準備するシート
スプレッドシートに「リマインダー計画」というシートを作り、1行目へ次の5列を左から並べます。
- 予定キー
- 開始日時
- 通知方法
- 何分前
- 有効
2行目以降へ、例として「evt-001」「2026/09/16 10:00」「popup」「30」「TRUE」を入力します。通知方法は popup または email、有効は TRUE または FALSE にします。予定キーは監査用の任意識別子で、実際のカレンダーIDや個人情報を入力する必要はありません。
コピーして使えるdry-runコード
function auditCalendarReminderPlan() {
const SHEET_NAME = 'リマインダー計画';
const MAX_ROWS = 100;
const ALLOWED_METHODS = new Set(['popup', 'email']);
const MAX_MINUTES = 40320; // 4週間。実運用前に最新仕様も確認する
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(SHEET_NAME);
if (!sheet) {
throw new Error('「' + SHEET_NAME + '」シートが見つかりません。');
}
const values = sheet.getDataRange().getValues();
if (values.length < 2) {
throw new Error('見出しとデータ行を用意してください。');
}
const expected = ['予定キー', '開始日時', '通知方法', '何分前', '有効'];
const headers = values[0].map(value => String(value).trim());
const headerOk = expected.every((name, index) => headers[index] === name);
if (!headerOk) {
throw new Error('1行目の見出しまたは並び順が違います。');
}
const rows = values.slice(1, MAX_ROWS + 1);
const issues = [];
const seen = new Map();
let enabledCount = 0;
rows.forEach((row, index) => {
const rowNumber = index + 2;
const key = String(row[0]).trim();
const startAt = row[1];
const method = String(row[2]).trim().toLowerCase();
const minutes = Number(row[3]);
const enabled = row[4] === true ||
String(row[4]).trim().toUpperCase() === 'TRUE';
const isBlank = row.every(value => value === '' || value === null);
if (isBlank) return;
if (!key) issues.push({ row: rowNumber, code: 'MISSING_KEY' });
if (!(startAt instanceof Date) || Number.isNaN(startAt.getTime())) {
issues.push({ row: rowNumber, code: 'INVALID_START_AT' });
}
if (!ALLOWED_METHODS.has(method)) {
issues.push({ row: rowNumber, code: 'INVALID_METHOD' });
}
if (!Number.isInteger(minutes) || minutes < 1 || minutes > MAX_MINUTES) {
issues.push({ row: rowNumber, code: 'INVALID_MINUTES' });
}
if (enabled) {
enabledCount++;
if (key && ALLOWED_METHODS.has(method) && Number.isInteger(minutes)) {
const duplicateKey = [key, method, minutes].join('|');
if (seen.has(duplicateKey)) {
issues.push({
row: rowNumber,
code: 'DUPLICATE_SETTING',
firstRow: seen.get(duplicateKey)
});
} else {
seen.set(duplicateKey, rowNumber);
}
}
}
});
const summary = {
dryRun: true,
checkedRows: rows.filter(row =>
row.some(value => value !== '' && value !== null)
).length,
enabledRows: enabledCount,
issueCount: issues.length,
issues: issues
};
console.log(JSON.stringify(summary));
return summary;
}実行手順
- 検証用スプレッドシートをコピーするか、新規シートで上記5列を作る。
- 拡張機能からApps Scriptを開き、コードを貼り付けて保存する。
- Apps Scriptのプロジェクト設定とスプレッドシートのタイムゾーンを同じ地域にそろえる。
- auditCalendarReminderPlan を選んで実行する。
- 実行ログの dryRun が true であること、issueCount と issues の行番号・コードを確認する。
- 問題行を手動で直し、issueCount が0になるまで再実行する。
初回実行ではスプレッドシートを読むための承認画面が表示されることがあります。権限内容を確認し、検証用データで試してください。
検出する問題
- MISSING_KEY: 予定キーが空欄
- INVALID_START_AT: 開始日時を日付として読めない
- INVALID_METHOD: popup または email 以外
- INVALID_MINUTES: 1〜40320の整数ではない
- DUPLICATE_SETTING: 同じ予定キー・通知方法・何分前が有効行で重複
ログへ予定名、予定キー、メールアドレス、カレンダーIDは出しません。問題がある行番号だけを見て、シート側で内容を確認します。
安全に使うための制限
- このコードはスプレッドシートだけを読み取り、Googleカレンダーへ接続しない
- 既存予定のリマインダーと計画表の差分は検査しない
- 101行目以降のデータは対象外
- 通知方法や上限はGoogle側の仕様変更やアカウント条件で変わる可能性がある
- 実際に通知を追加する処理は、対象予定・権限・重複・停止方法を別途確認してから作る
- 自動実行トリガーはこの段階では設定しない
公開前チェックリスト
- 検証用シートで試した
- dryRun が true
- issueCount が0
- タイムゾーンをそろえた
- 個人情報やカレンダーIDをログへ出していない
- カレンダーの作成・変更・削除コードを追加していない
まとめ
通知の設定ミスは、カレンダーへ書き込む前の計画表で見つけると戻しやすくなります。まずはスプレッドシートだけを読むdry-runで、入力形式と重複を確認してください。
朝の予定とタスクをまとめて確認したい方は、関連する有料Tipsも確認できます。
関連する有料Tips商品を見る

GasおじのTips商品一覧を見る

※本記事は学習・検証用の例です。実データへ適用する前にコピー環境で確認してください。
※Google公式・Google公認の商品ではありません。Apps ScriptやGoogleカレンダーの仕様、利用上限、権限表示は変更される場合があります。
