Creating threaded draft replies in Gmail using Google Apps Script

I built a Google Apps Script that automates email replies but I’m having trouble keeping the replies in the same conversation thread. When I send the replies, they show up as separate emails instead of being grouped together with the original message.

The script should copy recipients from the original email, add custom text, and save everything as a draft. Here’s what I have so far:

function buildReplyInterface() {
  var divider = CardService.newDivider();
  var messageInput = CardService.newTextInput()
    .setFieldName("replyText")
    .setMultiline(true);

  var submitAction = CardService.newAction()
    .setFunctionName('generateDraftReply');
  var submitBtn = CardService.newTextButton()
    .setText('Create Draft')
    .setComposeAction(submitAction, CardService.ComposedEmailType.REPLY_AS_DRAFT);

  var section = CardService.newCardSection()
    .addWidget(messageInput)
    .addWidget(divider)
    .addWidget(submitBtn);

  return CardService.newCardBuilder()
    .addSection(section)
    .build();
}

function generateDraftReply(e) {
  var msgId = e.gmail.messageId;
  var originalMsg = GmailApp.getMessageById(msgId);
  
  var recipients = originalMsg.getTo();
  var sender = originalMsg.getFrom();
  var ccList = originalMsg.getCc();
  var emailSubject = originalMsg.getSubject();
  var originalContent = originalMsg.getBody();
  var files = originalMsg.getAttachments();
  
  var requiredEmail = "[email protected]";
  var needsEmail = ccList.indexOf(requiredEmail) < 0;
  
  if (needsEmail) {
    ccList += ", " + requiredEmail;
  }
  
  var userText = e.formInputs.replyText;
  var newContent = "<br>" + userText + "<br><br>" + originalContent;
  
  var draftReply = originalMsg.createDraftReply('', {
    cc: ccList,
    htmlBody: newContent,
    attachments: files,
    replyTo: sender,
    subject: emailSubject
  });
  
  return CardService.newComposeActionResponseBuilder()
    .setGmailDraft(draftReply)
    .build();
}

What am I missing to make sure the draft stays in the same conversation thread when sent?

you’re using createDraftReply() right - it handles threading automatically. but your subject line changes might be breaking it. gmail threads by subject + references headers. drop the manual subject parameter from your draft options since createDraftReply() already takes care of that.

Your CC field handling is probably the culprit. When you run ccList.indexOf(requiredEmail) on an empty string or null, then concatenate with ccList += ", " + requiredEmail, you’ll get malformed addresses like ", [email protected]" that break threading. Check if ccList exists first and treat it as an array. Also, don’t include the original message body in your HTML - it messes with Gmail’s threading markers. Just send your userText and ditch the originalContent from newContent entirely. Gmail already shows conversation history below replies automatically. The threading will work fine with just the user’s new text - let createDraftReply handle the formatting.

It’s probably how you’re handling the recipient addresses and content structure. When you modify the CC list by concatenating strings, you might create malformed email addresses that Gmail can’t recognize for threading. Use an array instead and join it properly. Your HTML body structure could also be the problem. Gmail expects specific formatting for replies to keep threads intact. Don’t manually build HTML with the original content - let Gmail handle the reply formatting by keeping your custom text separate and using the reply mechanism normally. I’ve hit similar issues before. Overriding too many default reply parameters breaks threading. Remove the subject parameter like mentioned, and consider dropping the replyTo parameter since you’re already replying to the original sender.