Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Last active December 23, 2022 17:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanaikech/f27d427f07b20ca9fedec21e643c4a3e to your computer and use it in GitHub Desktop.
Save tanaikech/f27d427f07b20ca9fedec21e643c4a3e to your computer and use it in GitHub Desktop.
Pseudo OnEdit Trigger for Google Document using Google Apps Script

Pseudo OnEdit Trigger for Google Document using Google Apps Script

This is a sample script for achieving the pseudo OnEdit trigger for Google Document using Google Apps Script.

In the current stage, there is not OnEdit trigger for Google Document. Ref But I sometimes have the case that I want to use OnEdit trigger. So, as the current workaround, I created this sample script. I think that this workaround can be also used for Google Slides, Google Form and also Google Spreadsheet. In the case of Spreadsheet, what the existing OnEdit trigger and the time-driven trigger cannot do can be achieved.

The flow of this workaround is as follows.

  1. Open a sidebar.
    • This workaround uses Javascript. So the sidebar is used.
  2. Run Javascript every 1 second, and check the change of document body.
    • This cycle can be adjusted for your situation.
  3. When the document body is changed, the script of Google Apps Script is run.

By this flow, the pseudo OnEdit trigger can be achieved.

Usage.

1. Sample script.

Google Apps Script side: Code.gs

Please copy and paste the following script to the script editor of Document as a script.

// Please run this function.
function openSidebar() {
  DocumentApp.getUi().showSidebar(
    HtmlService.createHtmlOutputFromFile("index").setTitle("Sample")
  );
}

function main() {
  //
  // do something
  //
  // Here, as a sample script, the background color of text of "sample" is changed.
  // This is a simple sample script for explaining this workaround. So please change this for your actual situation.
  //

  const search = "sample";
  const color = "#5DF957";
  const doc = DocumentApp.getActiveDocument();
  const body = doc.getBody();
  let s = body.findText(search);
  if (!s) return "Search value was not found.";
  let n = 0;
  while (s) {
    const res = s.getElement().asText();
    const offset = [s.getStartOffset(), s.getEndOffsetInclusive()];
    if (res.getBackgroundColor(offset[0]) != color) {
      res.setBackgroundColor(...offset, color);
      n++;
    }
    s = body.findText(search, s);
  }
  return n == 0 ? "New value was not found." : "Done.";
}

HTML and Javascript side: index.html

Please copy and paste the following script to the script editor of the Document as HTML.

<input type="button" onclick="start()" id="b1" value="start" />
<input type="button" onclick="stop()" id="b2" value="stop" disabled />
<script>
  let run;
  const runGoogleScript = (_) =>
    new Promise((resolve, reject) =>
      google.script.run
        .withFailureHandler(reject)
        .withSuccessHandler(resolve)
        .main()
    );
  const main = (_) =>
    new Promise((resolve, reject) =>
      setTimeout(
        async () => await runGoogleScript().then(resolve).catch(reject),
        1000
      )
    );

  const start = async () => {
    const b1 = document.getElementById("b1");
    const b2 = document.getElementById("b2");
    b1.disabled = true;
    b2.disabled = false;
    run = true;
    console.log("Start.");
    while (run) console.log(await main());
    console.log("End.");
    b1.disabled = false;
    b2.disabled = true;
  };

  const stop = (_) => (run = false);
</script>

2. Testing.

When you run openSidebar, a sidebar is opened on Google Document. And, when you click "start" button, the script is run.

In this sample script, the background color of text of "sample" is changed. This is a simple sample script for explaining this workaround. So please change this for your actual situation.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment