0

I want to check every second for an exclamation point, and highlight text if one is found. Currently the function fires every second, but it only checks whether there's an exclamation point on the first fire.

I saw this on GitHub, but it requires adding a sidebar and inserting HTML, which I'd rather not do.

This answer discusses an onEdit workaround, but it still has the trigger fire every 60 seconds, rather than every second.

This answer lays out how to call a function every second, and I'm trying to get it to work, but I can't figure it out.

This answer to my earlier question helped me avoid the error message of too many triggers, but I still can't get it to check on each fire whether the user has added an exclamation point.

function myFunction () {
var numIterations = 10
for (var i = 0; i < numIterations; i++) {
var doc = DocumentApp.openByUrl('doc url');
var body = doc.getBody();
var text = body.editAsText();
Logger.log (body.findText('!'))
if (body.findText ('!') != null){
text.setBackgroundColor(13,50,'#FFFF00'); 
}
else {
Utilities.sleep(1000);
if (ScriptApp.getProjectTriggers() == null){
 ScriptApp.newTrigger("myFunction")
.timeBased()
.after(1000)
.create();
}
}
}
}
jacob.in.nyc
  • 119
  • 1
  • 2
  • 10
  • 1
    There's a runtime quota of 90minutes/day. Even if you trigger it every second and your function runs only a second, you still won't be able to check after 90 minutes. Your best bet is still calling from client side html – TheMaster Dec 20 '22 at 15:58
  • 1
    The function will create new triggers exponentially so it will error out after about three seconds. See my [previous answer](https://stackoverflow.com/a/74856014/13045193). – doubleunary Dec 20 '22 at 21:35

1 Answers1

1

ScriptApp.getProjectTriggers() will get an array of triggers. An array object will never match a scalar such as null or a primitive such as 0.

Try this simpler pattern:

function payLoad() {
  const body = DocumentApp.getActiveDocument().getBody();
  if (body.editAsText().findText('!')) {
    console.log('Y');
  } else {
    console.log('N');
  }
}

function run() {
  payLoad();
  if (!ScriptApp.getProjectTriggers().length) {
    ScriptApp
      .newTrigger('run')
      .timeBased()
      .after(3000)
      .create();
  }
}

function stop() {
  ScriptApp.getProjectTriggers()
    .forEach(trigger => ScriptApp.deleteTrigger(trigger));
}

First test the payLoad() function in isolation and make it does what you want. When you are sure it works correctly, you can run it repeatedly through run() and stop the repetition through stop().

As TheMaster mentioned, you should observe the Triggers total runtime quota. You may want to implement a sidebar and run the search from there, as demonstrated by Tanaike's Pseudo onEdit.

doubleunary
  • 13,842
  • 3
  • 18
  • 51