doPost (e) не вызывает onChange (e) - событие Trigger On Change в электронной таблице Google - PullRequest
0 голосов
/ 24 июня 2018

У меня есть очень простой проект сценария doPost (e), который работает как конечная точка webhook.Он просто записывает полученную полезную нагрузку JSON в ячейку A2 целевой таблицы.В целевой таблице у меня есть триггер onChange (e), который передает эту полезную нагрузку внешнему API.Хотя во время выполнения ошибки нет, мой скрипт onChange (e) вообще не запускается.При условии, что я вырезал / вставил содержимое ячейки на листе, onChange (e) затем корректно сработал.

На странице разработчиков Google здесь упоминаются некоторые ограничения, но также говорится, чтоэти ограничения не распространяются на doGet (e) и doPost (e).

Что мне не хватает?

Вот мой код doPost:

var SHEETID = "my_sheetID_here";

function doPost(e) {
  try {
    var data = JSON.parse(e.postData.contents);
    var sSht = SpreadsheetApp.openById(SHEETID);
    var sht = sSht.getSheetByName("TEMP");
    sht.getRange("A2").setValue(e.postData.contents);

    return ContentService    // return json success results
    .createTextOutput(
      JSON.stringify({"result":"success",
                  "data": JSON.stringify(data) }))
    .setMimeType(ContentService.MimeType.JSON);
  } catch (e) {
    MailApp.sendEmail("xx@xx.com,yy@xx.com", "FireStation Webhook Error Occured!", 
      "\r\nMessage: " + e.message
      + "\r\nFile: " + e.fileName
      + "\r\nLine: " + e.lineNumber);
    e = (typeof e === 'string') ? new Error(e) : e;
    Logger.severe('%s: %s (line %s, file "%s"). Stack: "%s" . While processing %s.',e.name||'', 
           e.message||'', e.lineNumber||'', e.fileName||'', e.stack||'', processingMessage||'');
    throw e;
  }
}

А здесьмой код onChange (e) на целевом листе:

function onChange(e) {
  try {
    var sheet = e.source.getActiveSheet();
    var sheetname = sheet.getName();
    Logger.log("Sheetname: "+sheetname);
    if (sheetname === "TEMP" && sheet.getRange("A2").getValue() !== "") {
      var payload = sheet.getRange("A2").getValue();
      var URL = "my_external_api_URL_here";
      var options =
      {
        "method"  : "POST",
        "payload" : payload,   
        "followRedirects" : true,
        "muteHttpExceptions": true
      };
      var result = UrlFetchApp.fetch(URL, options);
      Logger.log("HTTP Response: "+result.getResponseCode())
    }
  } catch (e) {
    MailApp.sendEmail("xx@xx.com,yy@xx.com", "FireStation Template GAS Error Occured!", 
      "\r\nMessage: " + e.message
      + "\r\nFile: " + e.fileName
      + "\r\nLine: " + e.lineNumber);
    e = (typeof e === 'string') ? new Error(e) : e;
    Logger.severe('%s: %s (line %s, file "%s"). Stack: "%s" . While processing %s.',e.name||'', 
           e.message||'', e.lineNumber||'', e.fileName||'', e.stack||'', processingMessage||'');
    throw e;
  }
}

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

РЕШЕНИЕ

Вместо использования встроенных служб Sheets, например SpreadsheetApp.openById (sheetid) и Range.setValue () , с использованием Sheets APIверсия 4 решает проблему и запускает onChange (e) в целевой электронной таблице.Обратите внимание, что для этого решения требуется, чтобы Advanced Google Services / Sheet API был включен из консоли разработчика.

Вот последняя версия моего вызова doPost (e), и он прекрасно работает:

var SHEETID = "my_sheet_id_here";

function doPost(e) {
  try {
    var data = e.postData.contents;
    var rowValues = [
      [data,""],
    ];

    var request = {
      'valueInputOption': 'USER_ENTERED',
      'data': [
        {
          "range": "TEMP!A2:B2",
          "majorDimension": "ROWS",
          "values": rowValues,
        },
      ],
    };

    var response = Sheets.Spreadsheets.Values.batchUpdate(request, SHEETID);

    return ContentService    // return json success results
    .createTextOutput(
      JSON.stringify({"result":"success",
                  "data": JSON.stringify(data) }))
    .setMimeType(ContentService.MimeType.JSON);
  } catch (e) {
    MailApp.sendEmail("levent@able3ventures.com,alkio@able3ventures.com", "FireStation Webhook Error Occured!", 
      "\r\nMessage: " + e.message
      + "\r\nFile: " + e.fileName
      + "\r\nLine: " + e.lineNumber);
      e = (typeof e === 'string') ? new Error(e) : e;
      Logger.severe('%s: %s (line %s, file "%s"). Stack: "%s" . While processing %s.',e.name||'', 
           e.message||'', e.lineNumber||'', e.fileName||'', e.stack||'', processingMessage||'');
      throw e;
  }
}
0 голосов
/ 24 июня 2018

Sheets API может использоваться для запуска события «On Change». Не используйте setValues(array). Удалите этот код и добавьте функцию для записи значения в электронную таблицу.

Возможно, вам потребуется установить области действия в файле appsscript.json (файл манифеста).

Файл манифеста (appsscript.json)

{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "webapp": {
    "access": "MYSELF",
    "executeAs": "USER_DEPLOYING"
  },
  "exceptionLogging": "STACKDRIVER",
  "oauthScopes": ["https://www.googleapis.com/auth/drive",
                  "https://www.googleapis.com/auth/script.external_request"]
}

Если вы используете другие области, найдите их на вкладке «Файл» «Свойства проекта» и «Области». Скопируйте их и поместите в файл appsscript.json, чтобы сохранить те же области.

Ваш код изменен:

function doPost(e) {
  try {
    var data = JSON.parse(e.postData.contents);

    writeToSheet({shName:"TEMP",ssFileID:SHEETID,data:data});//Write data to sheet using API

    return ContentService    // return json success results
    .createTextOutput(
      JSON.stringify({"result":"success",
                  "data": JSON.stringify(data) }))
    .setMimeType(ContentService.MimeType.JSON);
  } catch (e) {

    //code . . . .
}

Новая функция:

Функция, которая использует Sheets API v4 с опцией valueInputOption=USER_ENTERED:

function writeToSheet(po) {
  var id,options,range,response,sh,targetSheetName,ss,url,values;

  targetSheetName = po.shName;
  id = po.ssFileID;

  range = targetSheetName + "!A2:A2";

  values = {values: [[po.data]]}; 

  url = "https://sheets.googleapis.com/v4/spreadsheets/" +
    id + "/values/" + range + ":append?valueInputOption=USER_ENTERED";

  options = {
    "method":"post",
    "muteHttpExceptions": true,
    "headers": {
      "Authorization": "Bearer " + ScriptApp.getOAuthToken()
    },
    "contentType": "application/json", 
    "payload": JSON.stringify(values) 
  }

  response = UrlFetchApp.fetch(url,options)
  response = JSON.parse(response);

  Logger.log('response ' + JSON.stringify(response))
}
...