0

Here is a minimal reproducable example.

Code.gs:

function doGet() {
  return HtmlService.createTemplateFromFile('index').evaluate();
}

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

function sendTemplateEmail(replacements) {

  const template = DriveApp.getFileById('1boJRowTA90zy4CIn0DkK_9oERoEYk2iZRmuB7sSagKU');
  const copyFile = template.makeCopy('temp template')
  const copyDoc = DocumentApp.openById(copyFile.getId());
  const body = copyDoc.getBody();

  for(let i = 0; i < replacements.length; i++) {
    body.replaceText(replacements[i][0], replacements[i][1])
  }

  copyDoc.saveAndClose()

  let emailBody = docToHtml(copyFile.getId())
  copyFile.setTrashed(true);

  MailApp.sendEmail('nick@icarenetwork.com', 'testing', emailBody, {
    htmlBody: emailBody
  })
}

function docToHtml(docId) {
  // Downloads a Google Doc as an HTML string.
  let url = 'https://docs.google.com/feeds/download/documents/export/Export?id=' +
            docId + '&exportFormat=html';
  var param = {
    method: 'get',
    headers: {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()},
    muteHttpExceptions: true,
  };
  let doc = UrlFetchApp.fetch(url, param).getContentText();
  return doc;
}

index.html:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">

    <?!= include('script')?>
  </head>
  <body>
    My webapp content
  </body>
</html>

script.html:

<script>

  let replacements = [
    ['<<[[]Sample \(text\) & more sample text[]]>>', 'replacement1'],
    ['Regex', 'replacement2']
  ]

  google.script.run.sendTemplateEmail(replacements);

</script>

Here is the link to the template document which is simplified: https://docs.google.com/document/d/1RTFbfaveI2C9kzzPqeKwuy33a5BuNXlQtCom9pYNt88/edit?usp=sharing

I included the whole GAS project because I'm not sure if there is a difference between how Apps Script uses the replaceText method and regex vs. how it would work in JS. Also, my array was acting weird when I tried to populate it with raw regexps.

What I want is to replace the second line in the template document, which is <<[Sample-text that I am using (i.e., this, that)]>> with a string (in this example it's 'replacement2'). I want to replace the entire thing, including the <<[]>>

Note: I need the regex to target the brackets and the exact text within them, not just all the characters and symbols within them. This is because I will have lots of other lines of text in the Doc that is surrounded by the <<[]>> brackets that I will also neet to target individually. So a regex that selects the brackets and everything in between them will not work.

This program is supposed to be an Apps Script version of App Sheet's way of sending an email with a template file. I need to use the same structure of including variables in the template as is used in App Sheet. That's why I'm using <<[]>>

Nick
  • 15
  • 6

1 Answers1

2

I believe your goal is as follows.

  • In Google Document, you want to replace a value of a value enclosed by <<[ and ]>> like <<[Sample-text that I am using (i.e., this, that)]>> with replacement2.

In this case, how about the following sample script?

Sample script:

const doc = DocumentApp.openById("###"); // Please set your document ID.
doc.getBody().replaceText('<<\\[.*\\]>>', 'replacement2');
  • In this case, the searchPattern and replacement of replaceText(searchPattern, replacement) are <<\\[.*\\]>> and replacement2, respectively.

Reference:

Added:

From your following added information,

Note: I need the regex to target the brackets and the exact text within them, not just all the characters and symbols within them. This is because I will have lots of other lines of text in the Doc that is surrounded by the <<[]>> brackets that I will also neet to target individually. So a regex that selects the brackets and everything in between them will not work.

When your provided sample Document is used, when you want to individually replace each text of <<[Sample (text) & more sample text]>> and <<[Sample-text that I am using (i.e., this, that)]>>, how about the following sample script?

Sample script:

const obj = [
  ["<<[Sample (text) & more sample text]>>", "replacement1"],
  ["<<[Sample-text that I am using  (i.e., this, that)]>>", "replacement2"]
];
const doc = DocumentApp.getActiveDocument();
obj.forEach(([from, to]) => doc.getBody().replaceText(from.replace(/[()-\/\\^$*+?.{}|\[\]]/g, "\\$&"), to));
  • In this sample script, the text is replaced by escaping the regex meta characters.
    • I reffered this thead. Ref
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Yes, that is basically what I want to do. However, in a larger version of this file, there are going to be many different phrases that are enclosed in those brackets, and I'll have to target each phrase specifically. My problem comes when trying to target that second line/phrase in the doc because it includes regex patterns. I try to escape them, but it never works – Nick Feb 21 '23 at 14:52
  • @Nick Thank you for replying. From `Yes, that is basically what I want to do.`, I understood that your question was resolved. – Tanaike Feb 21 '23 at 23:04
  • @Nick About `However, in a larger version of this file, there are going to be many different phrases that are enclosed in those brackets, and I'll have to target each phrase specifically. My problem comes when trying to target that second line/phrase in the doc because it includes regex patterns. I try to escape them, but it never works`, unfortunately, I cannot know your this situation. Because I have only your provided question. So, can you provide more information to help understand your actual question? By this, I would like to confirm it. – Tanaike Feb 21 '23 at 23:04
  • Yes, thank you. I just updated the post to include this information. This should explain my problem in more detail. – Nick Feb 22 '23 at 00:09
  • @Nick Thank you for replying. In your situation, you want to individually search each text of `<<[Sample (text) & more sample text]>>` and `<<[Sample-text that I am using (i.e., this, that)]>>`. Is my understanding correct? – Tanaike Feb 22 '23 at 00:13
  • thank you, your sample script worked. Can you explain what the \\$& does? – Nick Feb 22 '23 at 15:59
  • @Nick Thank you for replying. I'm glad your issue as resolved. About `\\$&`, in this case, it means that `\\` is added to the searched regex metacharacter. By this, it can be used with `replaceText`. – Tanaike Feb 23 '23 at 00:11