Apply Gmail Label Rules

applyGmailLabelRules(rules) takes rule objects {query, label, archive}, creates any label that does not exist, applies it to matching threads in batches of 100, and returns a count per rule. Set archive: true to move those threads out of the Inbox as well.

When to use

  • A rules tab that labels billing mail, newsletters, or client threads
  • A time-driven trigger that keeps the Inbox tidy
  • Any repeatable Gmail cleanup you do not want to click through by hand

How to use this snippet

/** * Apply Gmail label rules. Creates missing labels. * Each rule: {query, label, archive}. Threads are fetched and labeled * in batches of 100 (the GmailApp.addToThreads / moveThreadsToArchive limit). * A -label: term is added so already-labeled threads are not processed again. * * @param {{query: string, label: string, archive?: boolean}[]} rules * @return {{query: string, label: string, archive: boolean, applied: number, skipped?: boolean}[]} */ function applyGmailLabelRules(rules) { var counts = []; (rules || []).forEach(function (rule) { var query = String((rule && rule.query) || '').trim(); var name = String((rule && rule.label) || '').trim(); var archive = !!(rule && rule.archive); if (!query || !name) { counts.push({ query: query, label: name, archive: archive, applied: 0, skipped: true }); return; } var label = GmailApp.getUserLabelByName(name) || GmailApp.createLabel(name); var term = /[\s"]/.test(name) ? '-label:"' + name.replace(/"/g, '') + '"' : '-label:' + name; var q = query + ' ' + term; var applied = 0; for (;;) { var threads = GmailApp.search(q, 0, 100); if (!threads.length) break; label.addToThreads(threads); if (archive) GmailApp.moveThreadsToArchive(threads); applied += threads.length; if (threads.length < 100) break; } counts.push({ query: query, label: name, archive: archive, applied: applied }); }); return counts; }

Example

function runInboxRules() { var rules = [ { query: 'from:billing@example.com newer_than:7d', label: 'Invoices', archive: true }, { query: 'from:news@example.com', label: 'Newsletters', archive: true } ]; Logger.log(applyGmailLabelRules(rules)); }

Notes

  • GmailLabel.addToThreads and GmailApp.moveThreadsToArchive accept at most 100 threads per call. The helper pages in chunks of 100 until the query is exhausted or the six-minute runtime is hit.
  • Already-labeled threads are skipped by appending -label:YourLabel to the query. Leave that term out of the sheet; the helper adds it.
  • Gmail has daily read/write quotas. A 15-minute trigger is a safe interval (everyMinutes allows 1, 5, 10, 15, or 30). A huge first-run backlog may take several trigger firings to finish.
  • Empty query or label rows are skipped (skipped: true).

Happy Coding!

NitroGAS Chrome Extension

Want this snippet handy inside the Apps Script editor? NitroGAS gives you free snippets — plus optional Co-Pilot when you want a boost (Day Pass — $3, or 1-week, 1-month, or yearly passes — no subscription). Happy Coding!

Get the Extension