appscript.dev
Automation Intermediate Gmail Docs

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.

Published Jun 6, 2026

When a client relationship changes hands — someone goes on leave, an account is reassigned — the history lives in one sprawling email thread. Forwarding that thread to the next person is technically a handover, but it is a cruel one: dozens of messages, quoted replies stacked four deep, no way to skim.

At Northwind, María hits this every time she covers a colleague’s accounts. This script turns a single Gmail thread into a clean Google Doc — every message in order, each with a clear sender-and-date heading, and the quoted reply clutter stripped out. The result is a readable note she can hand over, annotate, or drop into a shared drive. It is not an AI summary; it is a faithful, tidy transcript that an actual person can read top to bottom.

What you’ll need

  • The thread you want to capture — either its Gmail URL (the kind you get from the address bar with a thread open) or its raw thread ID.
  • Permission to create Google Docs in your account. The script makes a new Doc in your My Drive each time it runs.
  • Nothing else — no sheet, no config, no API key.

The script

/**
 * Captures a single Gmail thread as a clean Google Doc: every message in
 * order, each under a sender/date heading, with quoted-reply lines removed.
 * Accepts either a Gmail thread URL or a raw thread ID.
 * Returns the URL of the new Doc.
 */
function summarizeThreadToDoc(threadUrlOrId) {
  // 1. Accept either a full Gmail URL or a bare ID. If the input matches the
  //    "#inbox/<id>" URL shape, pull the ID out; otherwise treat it as an ID.
  const id = (threadUrlOrId.match(/#inbox\/(.+)$/) || [, threadUrlOrId])[1];

  // 2. Look up the thread and bail out clearly if it cannot be found.
  const thread = GmailApp.getThreadById(id);
  if (!thread) {
    throw new Error('Thread not found for: ' + threadUrlOrId);
  }

  // 3. Create a Doc named after the thread's subject and add a title.
  const subject = thread.getFirstMessageSubject();
  const doc = DocumentApp.create('Thread — ' + subject);
  const body = doc.getBody();
  body.appendParagraph(subject)
    .setHeading(DocumentApp.ParagraphHeading.TITLE);

  // 4. Walk every message in order, writing a heading and a cleaned body.
  for (const msg of thread.getMessages()) {
    body.appendParagraph(msg.getFrom() + ' — ' + msg.getDate().toISOString())
      .setHeading(DocumentApp.ParagraphHeading.HEADING3);
    body.appendParagraph(cleanBody(msg.getPlainBody()));
  }

  // 5. Save the Doc and hand back its URL.
  doc.saveAndClose();
  return doc.getUrl();
}

/**
 * Strips quoted-reply lines (those starting with one or more ">" markers)
 * from a plain-text message body and trims surrounding whitespace.
 */
function cleanBody(plainText) {
  return plainText.replace(/\n>+ ?[^\n]*/g, '').trim();
}

How it works

  1. summarizeThreadToDoc accepts either a Gmail URL or a bare thread ID. The regular expression matches the #inbox/<id> portion of a URL; if it does not match, the input is assumed to already be an ID.
  2. It looks the thread up with getThreadById and throws a clear error if nothing comes back — far easier to debug than a later null reference.
  3. It creates a new Google Doc named after the thread’s subject and writes that subject as the document title.
  4. It loops through every message in the thread in chronological order. Each message gets a Heading 3 line — sender plus an ISO timestamp — followed by its body.
  5. cleanBody removes the quoted-reply clutter: any line beginning with one or more > characters, which is how plain-text email marks quoted history. What remains is just what each person actually wrote in that message.
  6. The Doc is saved and its URL returned, so the caller can open or share it.

Example run

Pass a thread URL to the function from the script editor:

function summariseAcme() {
  console.log(summarizeThreadToDoc(
    'https://mail.google.com/mail/u/0/#inbox/19abc...',
  ));
}

For a five-message thread titled “Acme rollout schedule”, the new Doc reads:

Acme rollout schedule                          (Title)

Priya Shah <[email protected]> — 2026-05-12T09:14:00.000Z   (Heading 3)
Can we lock the rollout for the first week of June?

María Lopez <[email protected]> — 2026-05-12T11:02:00.000Z
First week works. I'll confirm the training dates tomorrow.

Priya Shah <[email protected]> — 2026-05-13T08:40:00.000Z
Great — looping in Tom so he has visibility.
...

The console logs the Doc’s URL. Quoted “On Tue, Priya wrote:” blocks that would have appeared four times over are gone, leaving a transcript that reads cleanly top to bottom.

Run it

This is an on-demand tool — you run it for one specific thread when a handover comes up:

  1. Open the thread in Gmail and copy its URL from the address bar.
  2. In the Apps Script editor, paste the URL into a wrapper like summariseAcme above.
  3. Select that function and click Run, then approve the authorisation prompt the first time.
  4. Open the URL from the execution log to read the finished Doc.

Watch out for

  • The Doc is a faithful transcript, not a summary — it is as long as the thread. For a genuinely huge thread, run it and then feed the Doc through Summarize long email threads into three bullets for an AI digest on top of the clean source.
  • getPlainBody returns text only. Inline images, formatting and attachments are not carried into the Doc — only the words.
  • The quoted-line filter targets the standard > marker. Some clients quote history without it (for example, with an indented HTML block), and that history will survive into the Doc.
  • A Gmail thread URL must come from a thread that is actually in your inbox view for the #inbox/<id> pattern to match. If you copy a URL from a different label, pass the bare thread ID instead.
  • Every run creates a new Doc in My Drive. Run it repeatedly on the same thread and you will accumulate duplicates — tidy up, or move each Doc into the client’s folder once it is done.

Related