9

How can I programmatically delete a Google Apps Script time-based trigger by the triggered function's name, instead of triggerarray id?

I am creating a trigger and later on I want to delete the trigger by name. I tried this:

ScriptApp.deleteTrigger("myfunction");

but it does not work. I don't want to use this method:

var triggers = ScriptApp.getProjectTriggers();
    ScriptApp.deleteTrigger(triggers[0]);

Since I have more than one trigger at same time and might delete the wrong one! So how to delete trigger by its name instead of trigger array id?

function demo(){
  ScriptApp.newTrigger("myfunction")
    .timeBased()
    .everyMinutes(1)
    .create(); 
  }

  function myfunction(){
    // do some stuff here then stop the trigger by name
    ScriptApp.deleteTrigger("myfunction");
  }
}
tehhowch
  • 9,645
  • 4
  • 24
  • 42
user1788736
  • 2,727
  • 20
  • 66
  • 110

7 Answers7

12

If you loop through all the triggers you can access the handler function name with:

var triggers = ScriptApp.getProjectTriggers();
for ( var i in triggers ) {
  var funcName = triggers[i].getHandlerFunction()
}

...as shown in the docs.

Bryan P
  • 5,031
  • 3
  • 30
  • 44
9

@code-guy

 // Deletes all triggers in the current project.
 var triggers = ScriptApp.getProjectTriggers();
 for (var i = 0; i < triggers.length; i++) {
   ScriptApp.deleteTrigger(triggers[i]);
 }

From Docs

Free Boots
  • 123
  • 1
  • 6
4

Loop through the triggers searching for any that match on the handler function, then delete them.

Although the OP only mentioned one trigger, it's possible for multiple triggers to target the same handler function, so the following snippet caters for single and multiple matches.

function myfunction(){
    // do some stuff here then stop the trigger(s) by name
    var triggers = getProjectTriggersByName('myfunction');
    for (var i = 0; i < triggers.length; ++i)
        ScriptApp.deleteTrigger(triggers[i]);
}

function getProjectTriggersByName(name) {
    return ScriptApp.getProjectTriggers().filter(
        function(s) {return s.getHandlerFunction() === name;}
    );
}

See documentation on ScriptApp and Trigger.

Based on Bryan P's answer, but with code.

Paul Masri-Stone
  • 2,843
  • 3
  • 29
  • 51
4

You can delete it precisely when the trigger is triggered based on the unique id,code like:

function trigger4SendMediaGroup(event) {
try {
    var triggerUid = event.triggerUid;
    var triggers = ScriptApp.getProjectTriggers();
    if(triggers && triggers.length > 0){
        triggers.forEach(item=>{
            if(item.getUniqueId() == triggerUid){
                ScriptApp.deleteTrigger(item);
            }
        })
    }
    //other process
Victor
  • 69
  • 4
  • Thank you, this looks EXACTLY like what I need; can't understand why it's been so hard to track this down. Project I'm making is generating Forms intended for single use: once a user responds to the form, it is to stop taking any more responses. A function must get triggered when this happens, but we can't keep creating new Triggers without deleting old ones. Having the function delete the trigger that triggered it sounds PERFECT. – Atiq Zabinski Aug 31 '22 at 05:01
3

Go to Edit > Current Project Triggers. This is where all your triggers are stored and managed. The handlerFunction reflects the 'Run' name in the 'Current Project's Triggers'. Google kind of mixes these around in my experience so you have to cycle through, find the trigger by the handlerFunction, and then delete. If you have multiple triggers with the same 'Run' name you may have to break the loop and get more creative. But the following works for me.

function Delete() {
  var Triggers = ScriptApp.getProjectTriggers();
  for (var i = 0; i < Triggers.length; i++) {
    if (Triggers[i].getHandlerFunction() == "'Run' Name") {
      ScriptApp.deleteTrigger(Triggers[i])
    }
  }
}
Birminghamilton
  • 131
  • 2
  • 5
2

getHandlerFunction() returns function fully as a text(name, brackets, arguments, body).

Common solution: use indexOf.

For example,

  1. loop through triggers
  2. if triggers.getHandlerFunction().indexOf(name) != -1
  3. delete trigger

But be carefull, because in this case you can get another trigger by text in body. To avoid this problem, you can:

  1. add brackets, parameters or some unique chars to indexOf - .indexOf(name + "(){") and format your code.
  2. or/and create new function with unique name, like a triggerMyFunction, which will be call myFunction. Then you can delete trigger by name "triggerMyFunction"

Samples

this function delete by name ALL matched triggers

function deleteTriggersByName(name){
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++){ 
    if (triggers[i].getHandlerFunction().indexOf(name) != -1) 
    {
      ScriptApp.deleteTrigger(triggers[i]);
    }
}}

this function delete by name first matched trigger

function deleteTriggerByName(name){
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++){ 
    if (triggers[i].getHandlerFunction().indexOf(name) != -1) 
    {
      ScriptApp.deleteTrigger(triggers[i]);
      break;
    }
}}
Community
  • 1
  • 1
0
function setTrigger() {

deleteTriggers();  
scheduledTrigger(14,58);
}

function scheduledTrigger(hours,minutes){

var today_D = new Date();
var year = today_D.getFullYear();
var month = today_D.getMonth();
var day = today_D.getDate();

pars = [year,month,day,hours,minutes];

var scheduled_D = new Date(...pars);
var hours_remain=Math.abs(scheduled_D - today_D) / 36e5;
ScriptApp.newTrigger("orderFromSheet")
.timeBased()
.after(hours_remain * 60 *60 * 1000)
.create()
}

function deleteTriggers() {

var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
  if (   triggers[i].getHandlerFunction() == "orderFromSheet") {
    ScriptApp.deleteTrigger(triggers[i]);
  }
}
}
  • 1
    While this code snippet may be the solution, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – TheMaster Jun 18 '22 at 21:12