appscript.dev
Automation Beginner Gmail

Email yourself a daily inbox-zero scorecard

Count unread, awaiting-reply, and snoozed threads and email yourself a 7am scorecard.

Published Aug 26, 2025

“Inbox zero” is easy to aim for and hard to measure. Most mornings you open Gmail, see a wall of threads, and have no idea whether yesterday was a good day or a bad one. The number you actually care about — how many threads are still waiting on you — is buried in among newsletters, receipts, and read-and-done mail.

At Northwind, Awadesh wanted one honest number waiting for him before the day starts. This script runs at 7am, counts the threads that genuinely need attention, and emails him a short scorecard: unread, awaiting reply, snoozed, and a single “open” total. It is a beginner automation — three searches and a send — but it turns a vague feeling into a metric you can watch trend.

What you’ll need

  • A Gmail account — the script reads and counts your own inbox, nothing else.
  • Two minutes to add a time-driven trigger so it runs every morning.
  • That’s it. No spreadsheet, no API key, no extra services.

The script

// Gmail search queries for each bucket of "needs attention" mail.
// Tweak these to match how you actually triage — see "Watch out for".
const QUERY_UNREAD = 'in:inbox is:unread';
const QUERY_AWAITING = 'in:inbox is:read -from:me newer_than:7d';
const QUERY_SNOOZED = 'label:snoozed';

/**
 * Counts the inbox buckets that need attention and emails you a short
 * scorecard. Designed to run once a day on a time-driven trigger.
 */
function inboxScorecard() {
  // 1. Count each bucket. GmailApp.search returns matching threads,
  //    so .length is the count we want.
  const unread = GmailApp.search(QUERY_UNREAD).length;
  const awaiting = GmailApp.search(QUERY_AWAITING).length;
  const snoozed = GmailApp.search(QUERY_SNOOZED).length;

  // 2. The headline number: anything still demanding a response.
  //    Snoozed threads are deliberately parked, so they sit outside it.
  const total = unread + awaiting;

  // 3. Build a plain-text scorecard, padded so the numbers line up.
  const me = Session.getActiveUser().getEmail();
  const body = [
    `Unread:    ${unread}`,
    `Awaiting:  ${awaiting}`,
    `Snoozed:   ${snoozed}`,
    '',
    total === 0 ? '🎉 inbox zero' : 'Get to it.',
  ].join('\n');

  // 4. Send it to yourself with the total in the subject, so the
  //    score shows up in the notification without opening the mail.
  GmailApp.sendEmail(me, `Inbox: ${total} open`, body);
}

How it works

  1. inboxScorecard runs three Gmail searches, one per bucket. Each search returns an array of matching threads, and .length gives the count.
  2. The QUERY_UNREAD search counts threads in the inbox you haven’t opened yet.
  3. QUERY_AWAITING counts threads you have read, that didn’t come from you, and that arrived in the last seven days — a rough proxy for “someone is waiting on a reply”. The seven-day window stops ancient threads inflating it.
  4. QUERY_SNOOZED counts threads you’ve deliberately parked for later. They are reported but kept out of the headline total, because snoozed mail is not mail you’re behind on.
  5. total adds unread and awaiting into the one number that matters, and the script builds a padded text block so the columns line up in any mail client.
  6. It emails the scorecard to yourself. The total goes in the subject line, so you see the score in the notification before you even open the message.

Example run

On a typical Monday morning the three searches might return:

BucketQueryCount
Unreadin:inbox is:unread6
Awaitingin:inbox is:read -from:me newer_than:7d4
Snoozedlabel:snoozed3

The email that lands in your inbox looks like this:

Subject: Inbox: 10 open

Unread:    6
Awaiting:  4
Snoozed:   3

Get to it.

Clear an inbox completely and the subject becomes Inbox: 0 open with a 🎉 inbox zero line instead — a small but satisfying signal that the morning started well.

Trigger it

This is a scheduled job, so set it to run before your working day:

  1. In the Apps Script editor, open Triggers (the clock icon in the left sidebar).
  2. Click Add Trigger.
  3. Choose inboxScorecard, event source Time-driven, type Day timer, and the 6am–7am slot.
  4. Save, and approve the authorisation prompt the first time.

From then on the scorecard arrives every morning without you touching it.

Watch out for

  • The “awaiting” count is a heuristic, not the truth. is:read -from:me newer_than:7d catches read threads from other people, but it also catches newsletters and receipts you’ve opened. Add -category:promotions -category:updates to the query to cut most of that noise.
  • Gmail’s search is thread-based, not message-based. A long thread counts once, even if it has ten unanswered messages in it — fine for a scorecard, not for precise accounting.
  • The snoozed label only exists once you’ve snoozed at least one thread. If you never use snooze, that search returns zero, which is correct.
  • To scope the scorecard to a shared queue, add a label filter — for example label:support on each query counts just the support inbox.
  • Tighten the awaiting window by changing newer_than:7d to 48h if anything older than two days is effectively a lost cause anyway.

Related