Search code examples
google-apps-scriptgmail

How to send a reply to the recipient of the original message within the same Gmail thread using Apps Script?


I am working on an Apps Script project where I need to send a reply to the recipient of the original message within the same Gmail thread. I have tried using the available methods in the GmailApp service, but I couldn't find a direct way to achieve this.

Here's the scenario:

I send an initial email to a recipient.

I want to send a reply to the that email (original message of the thread) and send it to the recipient of the original message within the same thread, as a reminder or follow-up.

I have explored methods like message.reply() thread.reply() and forward() in the GmailApp service, but they don't provide the functionality I need. The reply() method only sends the reply to the sender of the original message, while the forward() method forwards the entire thread to a new recipient.

this is the main snippet of my code:

var emailBody = " Hello, This is a reminder to the previous email" ;

        var thread = GmailApp.getThreadById(existingThreadId); 

        var messages = thread.getMessages();

      var originalMessage = messages[0];
      var recipientEmail = originalMessage.getTo();// Get the recipient's email address from the original message
           
        // Reply to the thread and send the reply to the recipient of the original email
      
        originalMessage.reply("", { to: recipientEmail, htmlBody: emailBody });

Is there a way to send a reply within the same Gmail thread, specifically addressing the recipient of the original message?

I have also considered using the createDraft() method, but it creates a new email separate from the original thread.

Any guidance or workaround to achieve this functionality using Apps Script would be greatly appreciated.

Note: I have already reviewed the documentation for the GmailThread class in the Apps Script documentation, but couldn't find a suitable method for my requirement.

Thank you in advance for your assistance!


Solution

  • Much thanks to the basic post, where I could find a way to complete the task. The result is here:

    function sendReminder() {
      const THREAD_ID = '...';  // the thread of the original message
      const THREAD = GmailApp.getThreadById(THREAD_ID);
      const ORIGINAL_MSG = THREAD.getMessages()[0];
      // https://developers.google.com/gmail/api/reference/rest/v1/users.messages/get
      var raw = Gmail.Users.Messages.get("me", ORIGINAL_MSG.getId(), {format: "raw"}).raw;
      const ORIGINAL_TO = raw.reduce(bytesToString_, "").split("\n").filter((line) => /^To: /.test(line))[0];
      Logger.log(ORIGINAL_TO);  // the original message header "To:"
    
      const DRAFT_ID = THREAD.createDraftReply('Hello, This is a reminder to the previous email').getId();
      // https://developers.google.com/gmail/api/reference/rest/v1/users.drafts/get
      raw = Gmail.Users.Drafts.get("me", DRAFT_ID, {format: "raw"}).message.raw;
      var msg = raw.reduce(bytesToString_, ""), headerChanged = false;
      // "To:" header replacement 
      msg = msg.split("\n").map(function (line) {
        if (!headerChanged && /^To: /.test(line)) {
          headerChanged = true;
          return ORIGINAL_TO;
        }
        return line;
      }).join("\n");
      Logger.log(msg);  // ready to send message (headers+body)
    
      const RESOURCE = {
        id: DRAFT_ID,
        message: {
          threadId: THREAD_ID,
          raw: Utilities.base64EncodeWebSafe(msg)
        }
      };
      // https://developers.google.com/gmail/api/reference/rest/v1/users.drafts/update
      const DRAFT = Gmail.Users.Drafts.update(RESOURCE, "me", DRAFT_ID);
      // https://developers.google.com/gmail/api/reference/rest/v1/users.drafts/send
      Gmail.Users.Drafts.send({id: DRAFT.id}, "me");
    }
    
    function bytesToString_(acc, byte) {
      return acc + String.fromCharCode(byte);
    }
    

    We've used Gmail service, exact method links are in code. General steps in the above code are:

    1. Find the original message and get the exact "To:" header from here.
    2. Create a new draft for the same thread.
    3. Get draft message in raw format for a header replacement.
    4. Replace "To:" header by the original "To:" in the draft message.
    5. Create draft resource for updating.
    6. Update the existing draft via API.
    7. Send the updated draft.

    At last we've used the additional bytesToString_ function for convertion.