TriggerShelf

Recipe

Log new Gmail messages to a Google Sheet

Trigger: Time-drivenServices: GmailApp, SpreadsheetAppMock-tested: Nov 2026

Finds mail matching a search, appends date, sender, subject and message ID to a tab, and skips messages already logged.

Set it up

  1. Make a tab named Inbox log with headers Date, From, Subject, Message ID.
  2. Paste the script, edit the query in GL, and save.
  3. Run logMessages and approve the prompts. Add a time-driven trigger to keep it running.

The script

/**
 * Log new Gmail messages that match a search into a sheet, once each.
 * Sheet columns: Date, From, Subject, Message ID. Add a time-driven trigger for logMessages.
 */
var GL = { sheetName: 'Inbox log', query: 'label:inbox newer_than:2d', maxThreads: 30 };

function logMessages() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(GL.sheetName);
  var last = sheet.getLastRow();
  var known = {};
  if (last > 1) {
    sheet.getRange(2, 4, last - 1, 1).getValues().forEach(function (r) { known[r[0]] = true; });
  }
  var rows = [];
  GmailApp.search(GL.query, 0, GL.maxThreads).forEach(function (thread) {
    thread.getMessages().forEach(function (m) {
      var id = m.getId();
      if (known[id]) return;
      known[id] = true;
      rows.push([m.getDate(), m.getFrom(), m.getSubject(), id]);
    });
  });
  if (rows.length) sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, 4).setValues(rows);
  return rows.length;
}
Test status. 3 of 3 automated checks pass, run Nov 2026 against simulated Google services. This recipe has not yet been run inside a live Google account. Test it on a copy of your sheet first.

What you should see

DateFromSubject
Nov 14 08:41billing@example.comInvoice 1043
Nov 14 09:02ana@example.comRe: schedule

Each message is logged once. Sample values, not output from a real account.

Common errors and fixes

The same message is logged again
Column D must keep the message ID. Do not delete it.
Nothing is logged
Test the search text in Gmail first. newer_than limits the window.
Exceeded maximum execution time
Lower maxThreads and run more often.

Permissions. Running this script asks you to grant Google permissions for the services listed above, to your own script. TriggerShelf never receives your Google data. See the permissions table. Google will show "Google hasn't verified this app"; that is expected for a script you paste yourself.