Search code examples
google-sheetsgoogle-apps-scriptgoogle-sheets-api

Appscript How to trigger onChange when editing a sheet from a script?


I'm using doPost() in my appscript to handle a elementor form submission.

Once I add the fields in the sheet I need to make an API call. I want to call my doApi() function with a onChange trigger. Only nothing happens...

If I call doApi() in doPost(), I think it times out on the client side and the elementor form fails with a False negative.

I guess using setValue doesn't trigger the onChange or onEdit triggers as they only work for user input when the document is open, but not when a change is done by a function call in AppScript.

Any clues how I could hack onChange to be triggered by the onPost new line insert ?

const doPostCell = [2,15]
const apiCell = [2,16]
const editCell = [2,18]
function onEdit(){
  modifyTriggerCell(editCell)
}

// create a new contact in rentman
function DoApi () {
  const spreadSheet = SpreadsheetApp.getActiveSheet()
  const configSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('configuration');
  const configRowData = configSheet.getDataRange().getValues()
  // We get the different ID's from the second line (index[1])
  const configRow = configRowData[1]
  Logger.log(configRow)
  
  const token = configRow[0]
  modifyTriggerCell(apiCell)


  return 
}



function modifyTriggerCell(e) {
  const datatSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Formulaire elementor');
  const values = datatSheet.getDataRange().getValues()[datatSheet.getLastRow() - 1]
  const counterCell = datatSheet.getRange(e[0], e[1])
  const counterCellVal = counterCell.getValue()
  counterCell.setValue(counterCellVal + 1)
}

Solution

  • As no trigger works with appscript function calls i found out with this post i could build a trigger so that the doPost function could resolve and answer to the form that wont timeout thank to that. And my doApi function is executed 1second later. Run function asynchronously in Google Apps Script

    So now my script looks like this :

    const runAfter1s = func =>
      ScriptApp.newTrigger(func)
        .timeBased()
        .after(1000)
        .create();
    
    /**
    * this is a function that fires when the webapp receives a GET request
    * Not used but required.
    */
    function doGet( e ) {
      return HtmlService.createHtmlOutput( "Yepp this is the webhook URL, request received" );
    }
    
    // Webhook Receiver - triggered with form webhook to pusblished App URL.
    function doPost( e ) {
      if(e){
        var params = JSON.stringify(e.parameter);
        params = JSON.parse(params);
        insertToSheet(params);
      }
    
      modifyTriggerCell(doPostCell)
    
      runAfter1s('doApi')
    
      // HTTP Response
      return HtmlService.createHtmlOutput( "post request received" );
    }
    

    My only question left is on how to delete the trigger as stated in the original post ?

    Make sure to delete the created trigger inside everyDay2 after being triggered.