Turn starred emails into a task list
Sync every starred thread into the Northwind Tasks sheet automatically.
Published May 26, 2026
A star is the fastest way to say “I need to deal with this” — one click and you move on. But the inbox is a poor task list. Stars pile up, scroll out of view, and mix with everything else, so the thing you starred to remember is the thing you forget.
At Northwind, Awadesh stars threads that turn into work and wants them to land in
a proper Tasks sheet without any extra effort. This script does the sync: every
few minutes it finds newly starred threads, copies each into the Tasks sheet with
a clickable link back to the email, and marks the thread as captured so it is
never added twice. Starring stays the one-click habit; the tracking happens on
its own.
What you’ll need
- A Google Sheet with a
Taskstab. The script writes four columns in this order:title,source,link,status. Add those headers in row 1. - The spreadsheet’s ID, taken from its URL, set in the config below.
- Nothing else — the script creates the
tasks/capturedlabel itself.
The script
// The spreadsheet that holds the task list.
const TASKS_SHEET_ID = '1abcTasksSheetId';
// The label applied to a thread once it has been synced, so the same
// starred thread is never captured twice.
const CAPTURED_LABEL = 'tasks/captured';
/**
* Finds starred threads that haven't been captured yet and appends one
* row per thread to the Tasks sheet, with a link back to the email.
* Designed to run on a short time-driven trigger.
*/
function syncStarredToTasks() {
const sheet = SpreadsheetApp.openById(TASKS_SHEET_ID).getSheets()[0];
// 1. Read column C (the link column) to know what's already captured.
const known = new Set(
sheet.getRange('C2:C').getValues().flat().filter(Boolean)
);
// 2. Find starred threads not yet carrying the captured label.
const starred = GmailApp.search(`is:starred -label:${CAPTURED_LABEL}`);
if (starred.length === 0) {
Logger.log('No new starred threads to sync.');
return;
}
// 3. Find the captured label, creating it on first run.
const captured = GmailApp.getUserLabelByName(CAPTURED_LABEL)
|| GmailApp.createLabel(CAPTURED_LABEL);
// 4. Build a row for each new starred thread.
const rows = [];
for (const thread of starred) {
const link = `https://mail.google.com/mail/u/0/#inbox/${thread.getId()}`;
// Skip if the link is already in the sheet — a second guard against
// duplicates alongside the captured label.
if (known.has(link)) continue;
rows.push([thread.getFirstMessageSubject(), 'gmail', link, 'open']);
thread.addLabel(captured);
}
// 5. Append all the new rows in one write.
if (rows.length) {
sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, 4).setValues(rows);
}
Logger.log(`Synced ${rows.length} starred thread(s) to Tasks.`);
}
How it works
- The script opens the Tasks sheet and reads column C — the link column — into a
Set. That set is the record of which emails have already become tasks. - It searches Gmail for starred threads that do not carry the
tasks/capturedlabel. If there are none, it logs a message and stops before doing any more work. - It looks up the
tasks/capturedlabel and creates it on the first run, so there is no manual label setup. - For each new starred thread it builds a direct link to the email and a task
row: the subject of the first message as the title,
gmailas the source, the link, and a status ofopen. It also applies the captured label to the thread. - The link is checked against the
knownset before the row is built — a second guard so that even if a label is removed by hand, an already-synced email is not duplicated. - All the new rows are appended to the sheet in a single write, which is faster and tidier than appending one row at a time.
Example run
Awadesh stars two threads during the morning: “Contract review — Belmont” and “Logo files for handover”. On the next run the script finds both, since neither carries the captured label yet, and appends:
| title | source | link | status |
|---|---|---|---|
| Contract review — Belmont | gmail | https://mail.google.com/mail/u/0/#inbox/18f… | open |
| Logo files for handover | gmail | https://mail.google.com/mail/u/0/#inbox/18g… | open |
Both threads are now labelled tasks/captured. On the next run they are skipped,
so re-starring or re-opening them does not create duplicate rows.
Trigger it
This should feel close to instant, so run it on a short interval:
- In the Apps Script editor, open Triggers (the clock icon).
- Click Add Trigger.
- Choose
syncStarredToTasks, event source Time-driven, type Minutes timer, and pick Every 5 minutes. - Save, and approve the authorisation prompt the first time it runs.
Watch out for
- A thread is captured once. After the
tasks/capturedlabel is applied, un-starring and re-starring the same thread does nothing — the row already exists. That is intentional, but it means you cannot “re-add” a task by starring it again. - The link uses
thread.getId()against the#inbox/path. If the thread has been archived or moved out of the inbox, the link still resolves in Gmail, but the path is cosmetic rather than exact. - The duplicate check matches the link string exactly. If you edit a link in the sheet, the guard will no longer recognise it and the thread could be re-added if its label is also removed.
- The script only ever appends rows — it never updates or removes them. If you
complete a task, change its
statusin the sheet by hand; the script will not touch existing rows. - The title is the subject of the first message in the thread. A long thread that drifted off its original topic will still be titled after where it started.
Related
Convert long email threads into a summary note
Collapse a thread's history into a Doc for handover — perfect for client transitions or vacation cover.
Updated Jun 6, 2026
Pull event RSVPs from emails into a Sheet
Parse yes/no replies to event invites and tally attendance automatically.
Updated Jun 2, 2026
Turn forwarded emails into project tasks
Forward to [email protected] and a row lands in the Projects sheet under the right client.
Updated May 30, 2026
Alert when a label hits a backlog threshold
Warn the Northwind team in Slack when a Gmail label has more than N unread threads.
Updated Mar 31, 2026
Rank email templates by reply rate
Log every templated send and compute which subject lines and bodies actually earn replies.
Updated Mar 24, 2026