朝いちばんにスプレッドシートを開いて、「今日が期限のタスクはどれだっけ」と上から目で追う。これ、地味に時間を取られますよね。
私も副業のタスクをスプレッドシートで管理していたころ、毎朝この確認から1日を始めていました。しかも忙しい朝に限って開き忘れて、夜になってから「あ、今日が期限だった」と気づく……。そこで、シートの中身を要約して、毎朝メールで届けてもらうことにしました。
スプレッドシートのタスク一覧から「未完了・今日が期限・期限切れ」を数えて、毎朝決まった時間帯にGmailへ要約メールを送るGASを作ります。
宛先のメールアドレスはコードに書かず、スクリプトプロパティから読み込みます。コピペして動かすだけなら、目安は20分ほどです。
この記事の前提
- Googleアカウントがあり、Googleスプレッドシートを使える
- GASのエディタを開いて「実行」ボタンを押したことがある(なくても手順どおりで大丈夫です)
- トリガーそのものの基本は、GASを毎日自動で動かす|時間主導型トリガーの設定手順 でも解説しています。この記事は「何を自動で送るか」の中身づくりが中心です
用語メモ
| 用語 | ざっくりした意味 |
|---|---|
| GAS | Google Apps Scriptの略。Googleのサービスを動かせるJavaScriptベースの仕組み |
| 時間主導型トリガー | 決めた時間帯に、指定した関数を自動で実行してくれる設定 |
| スクリプトプロパティ | スクリプトごとに保存できる「名前と値」のメモ帳。宛先や設定値を入れておける |
| MailApp | GASからメールを送るためのサービス。送信専用 |
結論:やることは3つだけ
先に全体像です。
- シートを読み、未完了・今日が期限・期限切れの件数とタスク名を集める
- それをメール本文にまとめて、
MailApp.sendEmailで送る - 時間主導型トリガーで、毎朝7時台にこの関数を動かす
手順1:サンプルのシートを用意する
新しいスプレッドシートを作り、シート名を「タスク」にして、次のダミーデータを入れます。1行目は見出しです。A列は日付として入力してください。
| 期限 | タスク | 状態 |
|---|---|---|
| (今日の日付) | ブログ記事の下書きを見直す | 未着手 |
| (今日の日付) | 請求書のテンプレートを確認する | 作業中 |
| (昨日の日付) | 画像のサイズをそろえる | 未着手 |
| (来週の日付) | 次の企画を3つ書き出す | 未着手 |
| (昨日の日付) | 問い合わせフォームのテスト | 完了 |
日付の列に「2026/11/03」のように入力すると、スプレッドシートが日付として扱ってくれます。テストしやすいように、今日・昨日・来週の日付を混ぜておくのがコツです。
手順2:宛先をスクリプトプロパティに登録する
宛先のメールアドレスは、コードに直接書かずにスクリプトプロパティへ入れておきます。コードを人に見せたり、別のシートにコピーしたりしても、宛先が一緒に出回らないので安心です。
- スプレッドシートのメニュー「拡張機能」→「Apps Script」を開く
- 左側の「プロジェクト設定」(歯車のアイコン)を開く
- 下のほうの「スクリプト プロパティを追加」をクリックする
- 「プロパティ」に
MAIL_TO、「値」に自分の受け取りたいアドレス(例:[email protected])を入れる - 「スクリプト プロパティを保存」をクリックする
同じ「プロジェクト設定」にタイムゾーンの項目もあります。ここが「(GMT+09:00) 日本標準時」になっているか、ついでに確認しておきましょう。日付の比較やトリガーの時間帯は、このタイムゾーンが基準になります。あわせて、スプレッドシート側の「ファイル」→「設定」にあるタイムゾーンも日本になっているか見ておくと、日付が1日ずれるトラブルを防げます。
手順3:要約メールを送るコードを貼る
エディタに戻り、最初からある function myFunction() {} を消して、次のコードを貼り付けて保存します。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
// ===== 設定 =====
const SHEET_NAME = 'タスク'; // 読み込むシート名
const COL = { DUE: 0, TASK: 1, STATUS: 2 }; // 列の位置(A列=0, B列=1…)
const DONE_LABEL = '完了'; // この状態の行は「済み」として数えない
// ================
function sendDailySummary() {
// 宛先はスクリプトプロパティから読む(コードに直書きしない)
const to = PropertiesService.getScriptProperties().getProperty('MAIL_TO');
if (!to) throw new Error('スクリプトプロパティ MAIL_TO が設定されていません');
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(SHEET_NAME);
if (!sheet) throw new Error(`シート「${SHEET_NAME}」が見つかりません`);
// 見出し行を除き、タスク名が空の行は無視する
const rows = sheet.getDataRange().getValues().slice(1)
.filter(r => String(r[COL.TASK]).trim() !== '');
const tz = Session.getScriptTimeZone();
const fmt = d => Utilities.formatDate(d, tz, 'yyyy/MM/dd');
const today = fmt(new Date());
const notDone = rows.filter(r => r[COL.STATUS] !== DONE_LABEL);
const hasDate = r => r[COL.DUE] instanceof Date;
const dueToday = notDone.filter(r => hasDate(r) && fmt(r[COL.DUE]) === today);
const overdue = notDone.filter(r => hasDate(r) && fmt(r[COL.DUE]) < today);
const lines = [
`${today} のタスク要約です。`,
'',
`■ 未完了:${notDone.length}件`,
'',
`■ 今日が期限:${dueToday.length}件`,
...dueToday.map(r => `・${r[COL.TASK]}(${r[COL.STATUS]})`),
'',
`■ 期限切れ:${overdue.length}件`,
...overdue.map(r => `・${r[COL.TASK]}(期限 ${fmt(r[COL.DUE])})`),
'',
`シートを開く:${ss.getUrl()}`,
];
const subject = `【毎朝の要約】${today} 今日が期限 ${dueToday.length}件 / 期限切れ ${overdue.length}件`;
MailApp.sendEmail(to, subject, lines.join('\n'));
console.log(`送信しました。今日あと送れる宛先数の目安:${MailApp.getRemainingDailyQuota()}`);
}ポイントは3つです。
-
Session.getScriptTimeZone()で、プロジェクト設定のタイムゾーンに合わせて日付を文字にしています。日付をyyyy/MM/ddの形にそろえると、文字のまま大小を比べられるので「今日より前=期限切れ」が簡単に判定できます - 状態が「完了」の行は数えません。自分のシートで「済」などを使っているなら、
DONE_LABELを書き換えてください -
MailApp.getRemainingDailyQuota()は、その日にあと何人の宛先へ送れるかを返します。ログで確認できるようにしておくと、送りすぎに気づけます
保存したら、関数の選択欄で sendDailySummary を選び、「実行」を押します。初回は承認(=スクリプトがシートやメールを使ってよいかの確認)の画面が出るので、自分のアカウントを選んで許可してください。途中で「Googleがこのアプリを確認していない」という趣旨の警告が出た場合は、「詳細」を開き、自分のプロジェクト名へ進むリンクから許可します(自分で作ったスクリプトなので心配はいりません)。受信箱に要約メールが届けば成功です。
本文をもっと見やすくしたい、列の並びが違う、といったときは、AIに次のように頼むと早いです。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
次のGoogle Apps Scriptは、スプレッドシートの「タスク」シートから
未完了・今日が期限・期限切れのタスクを集めて、MailAppで要約メールを送るものです。
【やりたいこと】
- 私のシートは A列=タスク、B列=担当、C列=期限、D列=状態 です。列の位置を合わせてください
- 期限が「3日以内」のタスクも別の見出しで一覧に入れてください
- 宛先はスクリプトプロパティ MAIL_TO から読む書き方は変えないでください
【今のコード】
(ここに sendDailySummary のコードを貼る)手順4:毎朝7時台に動くトリガーを付ける
画面から設定する場合は、公式の手順どおり次の流れです。
- エディタ左側の「トリガー」(目覚まし時計のアイコン)を開く
- 右下の「トリガーを追加」をクリックする
- 実行する関数に
sendDailySummary、イベントのソースに「時間主導型」、タイプに「日付ベースのタイマー」、時刻に「午前7時~8時」を選ぶ - 「保存」をクリックする
画面の項目名はGoogleの更新で変わることがあります。見つからないときは「関数」「時間主導型」「毎日」「時間帯」の4つを探すつもりで見てみてください。
コードで作りたい場合は、次の関数を1回だけ実行します。同じトリガーが重複しないよう、すでにあるときは作らないようにしています。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
function createMorningTrigger() {
const exists = ScriptApp.getProjectTriggers()
.some(t => t.getHandlerFunction() === 'sendDailySummary');
if (exists) {
console.log('sendDailySummary のトリガーはすでにあります');
return;
}
// 毎日、午前7時台のどこかで実行(タイムゾーンはプロジェクト設定に従う)
ScriptApp.newTrigger('sendDailySummary')
.timeBased()
.atHour(7)
.everyDays(1)
.create();
}公式ドキュメントによると、時間主導型トリガーの実行時刻は多少ランダムになります。たとえば午前9時のトリガーなら、9時から10時のどこかの時刻が選ばれ、その時刻が毎日続きます(前回からおよそ24時間おきに動きます)。「7時に来ない、壊れた?」と焦らなくて大丈夫です。
つまずきやすい点
私が最初にやらかしたのは、テスト中に createMorningTrigger を何回も実行してしまい、同じメールが朝に3通届いたことです。トリガー画面で重複がないか、ときどき見ておくと安心ですよ。
| 症状 | 原因 | 対処 |
|---|---|---|
| 「MAIL_TO が設定されていません」と出る | スクリプトプロパティの名前が違う、または保存していない | 「プロジェクト設定」でプロパティ名が MAIL_TO になっているか確認する |
| 今日が期限なのに0件になる | A列が日付ではなく文字として入っている | 表示形式を「日付」にして入れ直す |
| 日付が1日ずれる | プロジェクト、またはスプレッドシートのタイムゾーンが日本になっていない | 「プロジェクト設定」と、スプレッドシートの「ファイル」→「設定」でタイムゾーンを確認する |
| 同じメールが何通も届く | トリガーが重複している | 「トリガー」画面で余分なものを削除する |
| メールが届かない日がある | 1日に送れる宛先数の上限に達した、またはエラーで止まった | 左側の「実行数」で失敗がないか確認する |
1日に送れるメールの宛先数には上限があり、公式の割り当て表では個人のGoogleアカウント(gmail.com など)で1日100件、Google Workspaceで1日1,500件です。この上限は、その日最初に送ってから24時間でリセットされます。自分宛てに1日1通なら心配いりませんが、宛先を増やすときは意識しておきましょう。
うまく動かないときは、エラー文ごとAIに渡すのが近道です。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Google Apps Scriptで、スプレッドシートの要約をMailAppで送る関数を
時間主導型トリガーで毎朝動かしています。
【困っていること】
手動で実行するとメールが届くのに、トリガーで動いたときだけ届きません。
【わかっていること】
- 「実行数」画面の状態:(失敗/完了 など)
- エラーメッセージ:(ここに貼る)
- プロジェクト設定のタイムゾーン:(例:日本標準時)
考えられる原因を可能性が高い順に挙げて、確認する場所を教えてください。まとめ
- 宛先はスクリプトプロパティ
MAIL_TOに入れて、コードには書かない - 日付は
Utilities.formatDateで文字にそろえると、「今日が期限」「期限切れ」を判定しやすい - トリガーは「7時台のどこか」で動く。重複させないように注意する
次の一歩は、自分が毎朝見ているシートを1つ選んで、COL の列番号だけ書き換えて実行してみることです。1通目が届いたら、朝の確認はもうメールを開くだけになりますよ。
関連する本・記事
こうした「毎朝同じものを確認する仕事」をGASでまとめて自動化したい方は、『Google Apps Script × 生成AI 全自動仕事術』も参考になります。生成AIに頼みながら、GASで手作業を減らしていきたい方向けの1冊です。
- トリガーの基本をもう少し詳しく:GASを毎日自動で動かす|時間主導型トリガーの設定手順
- Gmail側も自動で整理したいなら:GASでGmailを自動整理!ラベル付け&定期実行トリガーで受信箱をスッキリさせる方法
- シートの入力ミスも減らしたいなら:GASで入力ミスを自動で見つける|スプレッドシートの確認作業を減らす方法
- GASを順番に学びたい方へ:GAS学習の進め方|既存記事をつなぐ学習マップ
- メンバーのKindle本の一覧:biliotechまわりのKindle著書リスト