简体   繁体   中英

Google Apps Script Error in Spreadsheets

As of yesterday we started getting an Error in Google Spreadsheets while making a REST API (urlfetch) into Zendesk. We've been using these for 1.5 years and not really had any problems. The Error it gives is generic - "Error encountered: We're sorry, a server error occurred. Please wait a bit and try again." Screenshot of the Error - http://support.prontomarketing.com/attachments/token/j1bjrnw1cpfu4tu/?name=2012-06-27_08-56-19.jpg

Has there been any recent changes to the Google Apps Script Spreadsheet Services API?

Does anyone have any ideas?

Here is our script: (note* url and token for zendesk has been removed)

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
   var menuEntries = [ {name: "Create Tickets", functionName: "oneToMany"},{name: "Reset Form", functionName: "resetForm"} ];
   ss.addMenu("Actions", menuEntries);
}
function resetForm(){

  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var currentIndex = doc.getActiveSelection().getRowIndex();

  var totalRow = findThelastRow('a',0);

  for (var count=2;count<totalRow;count++)
  {
      doc.getSheets()[0].getRange('a'+count).clear({contentsOnly:true});
      doc.getSheets()[0].getRange('h'+count).clear({contentsOnly:true});
      doc.getSheets()[0].getRange('h'+count).setBackgroundColor('#ffffff');
      doc.getSheets()[0].getRange('i'+count).clear({contentsOnly:true});
      doc.getSheets()[0].getRange('i'+count).setBackgroundColor('#ffffff');
      //doc.getSheets()[0].getRange('c'+count).setValue(clearA(doc.getSheets()[0].getRange('c'+count).getValue()));
  }

}
function continueRest(){
   var doc = SpreadsheetApp.getActiveSpreadsheet();
   var app = UiApp.createApplication().setTitle('Please Input Your Zendesk Username');
   app.setHeight('75');
   app.setWidth('400');
   // Create a grid with 3 text boxes and corresponding labels
   var grid = app.createGrid(1, 2);

   // Text entered in the text box is passed in to userName
   grid.setWidget(0, 0, app.createLabel('Username:'));
   var inputTextBox1 =  app.createTextBox().setName('username');
   inputTextBox1.setWidth('300px');
   grid.setWidget(0, 1,inputTextBox1 ); 

   // Create a vertical panel..
   var panel = app.createVerticalPanel();

   // ...and add the grid to the panel
   panel.add(grid);

   // Create a button and click handler; pass in the grid object as a callback element and the handler as a click handler
   // Identify the function b as the server click handler

   var button = app.createButton('submit').setId('button');
   var handler = app.createServerClickHandler('continueSentTheRest');
   handler.addCallbackElement(grid);
   button.addClickHandler(app.createServerClickHandler('pauseUI'));
   button.addClickHandler(handler);
   //button.setStyleAttribute('display', 'none');

   // Add the button to the panel and the panel to the application, then display the application app in the Spreadsheet doc
   panel.add(button);
   app.add(panel);
   doc.show(app);

}
function oneToMany(){
var doc = SpreadsheetApp.getActiveSpreadsheet();
   var app = UiApp.createApplication().setTitle('Please Input Your Zendesk Username');
   app.setHeight('75');
   app.setWidth('400');
   // Create a grid with 3 text boxes and corresponding labels
   var grid = app.createGrid(1, 2);

   // Text entered in the text box is passed in to userName
   grid.setWidget(0, 0, app.createLabel('Username:'));
   var inputTextBox1 =  app.createTextBox().setName('username');
   inputTextBox1.setWidth('300px');
   grid.setWidget(0, 1,inputTextBox1 ); 

   // Create a vertical panel..
   var panel = app.createVerticalPanel();

   // ...and add the grid to the panel
   panel.add(grid);

   // Create a button and click handler; pass in the grid object as a callback element and the handler as a click handler
   // Identify the function b as the server click handler

   var button = app.createButton('submit').setId('button');
   var handler = app.createServerClickHandler('authHandler');
   handler.addCallbackElement(grid);
   button.addClickHandler(app.createServerClickHandler('pauseUI'));
   button.addClickHandler(app.createServerClickHandler('mapValue'));
   button.addClickHandler(handler);
   //button.setStyleAttribute('display', 'none');

   // Add the button to the panel and the panel to the application, then display the application app in the Spreadsheet doc
   panel.add(button);
   app.add(panel);
   doc.show(app);
}
function pauseUI(e) {
  var app = UiApp.getActiveApplication();
  // try 'pausing' the app while we process the info
  app.setTitle('Please wait...');
  app.getElementById("button").setEnabled(false);
  return app;
}

var table = SpreadsheetApp.getActive().getSheets()[1].getDataRange().getValues();

function selectByIndex( index ) {
  Logger.log(table);
  for( var i in table )
    if( table[i][0] == index )
      return table[i];
  return null; //or throw exception
}

function mapValue(){
  //Get the key value sheet.
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[1];
  Logger.log('on the loop');
  if (sheet != null) {

    for (var i in table){
      var groupKey =table[i][0];
      var groupValue = table[i][1];
      //Logger.log(groupKey+' '+groupValue);
      if(groupKey!=''&&groupValue!='')
        ScriptProperties.setProperty(groupKey,groupValue.toString());

      var assigneeKey = table[i][2];
      var assigneeValue = table[i][3];
      if(assigneeKey!=''&&assigneeValue!='')
        ScriptProperties.setProperty(assigneeKey,assigneeValue.toString());
    }
    //Priority
    ScriptProperties.setProperty('P: Low','1');
    ScriptProperties.setProperty('P: Normal','2');
    ScriptProperties.setProperty('P: High','3');
    ScriptProperties.setProperty('P: Urgent','4');
    //Browser.msgBox(ScriptProperties.getProperty('Development'));
  }
  else
  {
    Browser.msgBox('There is no sheet contain id for the assignee and group.');
  }
  //Browser.msgBox(ScriptProperties.getProperty('P: Urgent'));
}
function createPayLoad(count){
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var requester = doc.getSheets()[0].getRange('a'+count).getValue();
  var ticketTitle = doc.getSheets()[0].getRange('b'+count).getValue().toString().replace('&','&#38;');
  var ticketComment = doc.getSheets()[0].getRange('c'+count).getValue().toString().replace('&','&#38;');
  ticketComment = replaceBR(ticketComment);
  ticketComment = replaceA(ticketComment);
  var assignee = ScriptProperties.getProperty(doc.getSheets()[0].getRange('d'+count).getValue());
  var group = ScriptProperties.getProperty(doc.getSheets()[0].getRange('e'+count).getValue());
  Logger.log(doc.getSheets()[0].getRange('f'+count).getValue());
  var priority = ScriptProperties.getProperty('P: '+doc.getSheets()[0].getRange('f'+count).getValue().trim());
  var tags = 'internal '+doc.getSheets()[0].getRange('g'+count).getValue();

        var payLoad  =  '\n';
        payLoad +=  '<ticket>'+'\n';
    payLoad +=  '<requester-email>'+requester+'</requester-email>'+'\n';
    payLoad +=  '<subject>'+ticketTitle+'</subject>'+'\n';
    payLoad +=  '<description>'+ticketComment+'</description>'+'\n';
    payLoad +=  '<assignee-id>'+assignee+'</assignee-id>'+'\n';
    payLoad +=  '<group-id>'+group+'</group-id>'+'\n';
    payLoad +=  '<priority-id>'+priority+'</priority-id>'+'\n';
    payLoad +=  '<set-tags>'+tags+'</set-tags>'+'\n';
    payLoad +=  '</ticket>';
  //Browser.msgBox(payLoad) 
  return payLoad;
}

function findThelastRow(column,index){
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var lastRow = doc.getLastRow();
  for(var i=2;i<=lastRow+1;i++)
  {
       if(doc.getSheets()[index].getRange(column+i).getValue()=="")
       {
         return i;
         break;
       }
  }
  return 0;
}
function authHandler(e){
  if(e.parameter.username=="")
  {
    Browser.msgBox('Username is required!');
    return;
  }
  var app = UiApp.getActiveApplication();

  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var currentIndex = doc.getActiveSelection().getRowIndex();
  var username = e.parameter.username;
  var encode = Utilities.base64Encode(username+'/token:SECRET);
  var totalRow = findThelastRow('a',0);


  for (var count=2;count<totalRow;count++)
  {
    if(doc.getSheets()[0].getRange('a'+count).getValue()=='')
    {
       Browser.msgBox('Requester is required!');
       return;
    }
    var isCreate =  doc.getSheets()[0].getRange('i'+count).getValue();
    var isNormalUpdate = false;
    if(isCreate=='')
    {
      var payLoad = createPayLoad(count);

      var options =
          {
            "method" : "post",
            "headers" : {"Content-type":"application/xml","Authorization":  "Basic "+encode},
            "payload" : payLoad
          };

      var result = UrlFetchApp.fetch("http://SECRET/tickets.xml",options);

      if(result.getResponseCode()==201) //This means success.
      {
        var mytool_array=result.getHeaders().toSource().split(",");
        Logger.log(mytool_array);
        //var ticketNumber=mytool_array[2].split("Location:");
         var ticketNumber=result.getHeaders().toSource().split("Location:");
        Logger.log(ticketNumber);
        var valueTicket=ticketNumber[1].split('.xml')[0].split('tickets/')[1];
        doc.getSheets()[0].getRange('h'+count).setValue('=hyperlink("http://SECRET/tickets/'+valueTicket+'";"'+valueTicket+'")');
        doc.getSheets()[0].getRange('h'+count).setBackgroundColor('#1BE039');
        doc.getSheets()[0].getRange('i'+count).setValue('OK');
        doc.getSheets()[0].getRange('i'+count).setBackgroundColor('#1BE039');
      }
      else
      {
        doc.getSheets()[0].getRange('i'+count).setValue('FAIL');
        break;
        return;
      }
    }
  }
  // Clean up - get the UiApp object, close it, and return
  app.close();
  // The following line is REQUIRED for the widget to actually close.
  return app;
}

function continueSentTheRest(e){
  var app = UiApp.getActiveApplication();
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var indexOfA = findThelastRow('h',0);


  if(doc.getSheets()[0].getRange('a'+indexOfA).getValue()=="")
  {
    Browser.msgBox('Requester is required!');
    doc.getSheets()[0].setActiveSelection('a'+indexOfA);
    return;
  }


  var username = e.parameter.username;
  username += ':'+e.parameter.password;
  var encode = Utilities.base64Encode(username);
  var totalRow = findThelastRow('a',0);

  for (var count=indexOfA;count<totalRow;count++)
  {
    var payLoad = createPayLoad(count);

    var options =
        {
          "method" : "post",
          "headers" : {"Content-type":"application/xml","Authorization":  "Basic "+encode},
          "payload" : payLoad
        };

    var result = UrlFetchApp.fetch("http://SECRET/tickets.xml",options);

    if(result.getResponseCode()==201) //This means success.
    {
      var mytool_array=result.getHeaders().toSource().split(",");
      var ticketNumber=mytool_array[2].split("Location:");
      var valueTicket=ticketNumber[1].split('.xml')[0].split('tickets/')[1];
      doc.getSheets()[0].getRange('h'+count).setValue('=hyperlink("http://SECRET/tickets/'+valueTicket+'";"'+valueTicket+'")');
      doc.getSheets()[0].getRange('h'+count).setBackgroundColor('#1BE039');
      doc.getSheets()[0].getRange('i'+count).setValue('OK');
      doc.getSheets()[0].getRange('i'+count).setBackgroundColor('#1BE039');
    }
    else
    {
      doc.getSheets()[0].getRange('i'+count).setValue('FAIL');
      break;
      return;
    }
  }
  // Clean up - get the UiApp object, close it, and return
  app.close();
  // The following line is REQUIRED for the widget to actually close.
  return app;
}


String.prototype.ReplaceAll = function(stringToFind,stringToReplace){
    var temp = this;
    var index = temp.indexOf(stringToFind);
        while(index != -1){
            temp = temp.replace(stringToFind,stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
}

function replaceBR(input)
{
   return input.ReplaceAll('<br>','&#xD;');
}

function replaceA(input)
{
  input = input.ReplaceAll('<a>',' ');
  input = input.ReplaceAll('</a>',' ');
  return input;
}

function clearA(input)
{
  return input.replace(/<a>.*<\/a>/g,'<a></a>');
}

Your original findThelastRow(column,index) function has a loop from 0 to lastRow of the active sheet but then addresses a range in an (eventually) other sheet using this loop value. There is a possibility that the row index doesn't exist in this other sheet.
You could have not any issue with this for years depending on how many rows are present in the different sheets but maybe now this situation is happening ...

To prevent this risk, I would suggest to try this in the findThelastRow function :

function findThelastRow(column,index){
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var lastRow = doc.getSheets()[index].getLastRow();// check last row on the appropriate sheet
  for(var i=2;i<=lastRow+1;i++)
  {
       if(doc.getSheets()[index].getRange(column+i).getValue()=="")
       {
         return i;
         break;
       }
  }
  return 0;
}

EDIT : this function could be written more efficiently without using getValue() in a loop which is rather slow ... here is a compatible version using array : (you can replace it without any change)

function findThelastRow(column,index){
          var doc = SpreadsheetApp.getActiveSpreadsheet();
          var lastRow = doc.getSheets()[index].getLastRow()+1;// check last row on the appropriate sheet
          var coldata = doc.getSheets()[index].getRange(column+2+':'+column+lastRow).getValues();// I begin on Row 2 just as you did
      for(i=coldata.length-1;i>=0;i--){
         if(coldata[i][0]!=''){return i+2;break}
      }
      return 0;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM