Service Details

Google Apps Script Debugging

In this tutorial, we will look at real-world strategies for debugging Google Apps Script webhooks. You'll learn how to instrument your code with Logger.log and console.log statements, review detailed execution logs in the Apps Script dashboard, and set breakpoints to step through your script in the IDE. We'll also show you how to simulate webhook requests with cURL or Postman—inspecting request payloads, headers, and HTTP responses.

Debugging a Google Apps Script is easy and straightforward - if you are not familiar with it yet, there are many tutorials. In this tutorial, we'll skip over the basic debugging procedures like opening the execution log or using breakpoints, and instead jump straight into an example suited for production environments. The code sample in Sample 1 below show a basic debugging using the logger. This is not always ideal for production environments and can be addressed by directing the log to a text file or sheet. Sample 2 shows some basic code to do so.

              
  function TestDebug()
  {
    let n = 1;
    if (n == 1)
      console.log('1=1');
    if (n === 1)
      Logger.log('1===1');
  }
              
            
Sample 1: Basic debug logging


Firstly, we define a simple flag to toggle debugging on or off. This approach is handy because it allows you to enable or disable debug logging by changing just one value — keeping your code clean and easy to maintain. You can customize the logging to suit your project's needs, by changing the parameters of the function. Remember you can pass variables and not only constants as parameters. Since this code runs on every log execution, it's important to keep it short and efficient. To scale the idea, consider storing constants like your sheet ID and sheet name in a global config sheet for centralized control. For added robustness, you could implement a revolving log system: before writing a new entry, check how many rows already exist in the log sheet and clear or archive older entries if needed. This helps you stay within Google Sheets' data limits while maintaining a reliable audit trail.

                              
  //Global debug flag
  const cDebugOn = true;


  function LogDebugMsg(aModule, aClass, aMethod, aNote)
  {
    if (!cDebugOn)
      return
    
    //Replace below with your sheet ID and name:
    const cSheetID = 'YOUR_SHEET_ID';
    const cSheetName = 'YOUR_WORKSHEET_NAME'

    var ss = SpreadsheetApp.openById(cSheetID);
    var sheet = ss.getSheetByName(cSheetName);
    //Date is automatically logged for every entry
    sheet.appendRow([(new Date()), aModule, aClass, aMethod, aNote]);
  }



  function TestDebugSheet()
  {
    LogDebugMsg('MyModule', 'MyClass', 'MyMethod', 'This is a debug note...')
  }
              
            
Sample 2: Logging to a sheet


Lastly, let's look at debugging webhooks. Since we can't step through a webhook in real time—especially when it's triggered externally—we need to simulate the request ourselves. Tools like curl, Postman, or even browser-based fetch scripts allow us to manually trigger GET or POST requests with custom payloads, headers, and parameters. This gives us full control over the input and timing, making it easier to test and refine our webhook logic. To step through the webhook code in debug mode, we simulate the input by either logging the incoming parameters with Logger.log() or dumping them directly to the screen using ContentService.createTextOutput(). Sample 3 demonstrate how to implement dumping output parameters to the screen. (Remember, when debugging with curl, be sure to allow redirects by using the -L flag—this ensures you follow any HTTP 3xx responses and reach the final destination endpoint.)

                              
  //input: https://script.google.com/macros/s/YOUR_SCRIPT_ID/exec?parameter1=1¶meter2=%22two%22

  function doGet(e)
  {
    return ContentService.createTextOutput(JSON.stringify(e));
  }
              
            
Sample 3: Logging the input of a webhook


Sample 4 demonstrates how to set the input parameter and assign it the value of the screen dump. This allows us to debug the webhook as a normal function.

                              
  //output: {"contentLength":-1,"parameter":{"parameter1":"1","parameter2":"\"two\""},"contextPath":"","queryString":"parameter1=1¶meter2=%22two%22","parameters":{"parameter2":["\"two\""],"parameter1":["1"]}}

  function doGet(e)
  {
    //return ContentService.createTextOutput(JSON.stringify(e));
    e = {"contentLength":-1,"parameter":{"parameter1":"1","parameter2":"\"two\""},"contextPath":"","queryString":"parameter1=1¶meter2=%22two%22","parameters":{"parameter2":["\"two\""],"parameter1":["1"]}}
    //Assign the input to the e parameter and debug the webhook as you would debug a normal function!                  
  }
              
            
Sample 4: Using the saved input to debug a webhook


Unfortunately, Google currently does not support accessing HTTP headers in doPost() webhooks within Google Apps Script. This limitation means you won’t be able to retrieve custom headers—such as authorization tokens or content-type indicators—directly from the request object. Developers often work around this by passing critical data in the request body or query parameters instead.

This concludes our quick tutorial on debugging webhooks using Google Apps Script. We hope it helps you streamline your development process and gain confidence in handling real-world integrations. Keep experimenting, stay curious, and let innovaITon support your journey toward smarter automation.

Download Sample Code


Updated: 8 August 2025