Запускать вызов API при редактировании ячейки

Работа с Google Таблицами, где каждая строка содержит значение ID и раскрывающийся список. Пример: Google Sheet.

Я пытаюсь запустить пользовательскую функцию, когда кто-то редактирует ячейку списка выбора. Функция принимает два аргумента, значение из идентификатора и ячейку раскрывающегося списка в той же строке, а затем выполняет запрос HTTP POST для обновления записи в нашей CRM.

//When STAGE cell on Google Sheet is updated, run this function:

function updateProjectStage(status, id) {
  var baseURL = 'https://crm.zoho.com/crm/private/json/Potentials/updateRecords?authtoken=xxx&scope=crmapi&id=', // see docs https://www.zoho.com/crm/help/api/updaterecords.html
      recordID = id, // building id from A column
      stage = '<Potentials><row no="1"><FL val="Stage">' + status + '</FL></row></Potentials>'; // status from B column

  var postURL = baseURL + recordID + '&xmlData=' + stage;
  Logger.log(postURL);

  var response = UrlFetchApp.fetch(postURL); // update record in crm
  var sanitizedResponse = JSON.parse(response.getContentText()); // get confirmation/failure
  Logger.log(sanitizedResponse);
}

Я не знаю, как запустить функцию для этого типа ячеек из раскрывающегося списка - я не могу просто ввести =updateProjectStage(status, id) в ячейку, как я привык делать, потому что она выдает ошибку.

Пример: Сообщение об ошибке.

Это вообще возможно?


person Deven Blackburn    schedule 10.08.2018    source источник
comment
Похоже, у вас нет проблем с кодом Go, просто как сделать вызов API из Google Таблиц, так что это может быть лучше подходит для суперпользователя.   -  person Adrian    schedule 10.08.2018
comment
Ну, это должно быть написано на голанге, поэтому я не знаю, почему вы так сказали - это именно то, с чем у меня проблемы. Я даже не знаю, что написать; Конечно, должны быть какие-то вспомогательные функции для обработки событий - но можно ли их использовать в скрипте пользовательской функции Google Таблиц?   -  person Deven Blackburn    schedule 10.08.2018
comment
Скрипты Google Sheets запускаются в браузере, Go - нет. Я думал, что вы запускаете этот код Go в каком-то сервисе, возможно, я плохо понимаю ваш вопрос.   -  person Adrian    schedule 10.08.2018


Ответы (1)


Ваш ответ заключается в захвате события редактирования, когда пользователь изменяет любую ячейку на листе. Разумеется, пользователь может изменять любую ячейку. Ваша задача - определить, находится ли эта ячейка в интересующем вас диапазоне. Событие onEdit можно зафиксировать с помощью этой функции:

function onEdit(eventObj) {
  //--- check if the edited cell is in range, then call your function
  //    with the appropriate parameters
}

Объект, переданный в событие, описывает редактируемую ячейку. Итак, мы устанавливаем «контрольный диапазон», а затем сравниваем этот диапазон с той ячейкой, которая была отредактирована. Вот функция:

function isInRange(checkRange, targetCell) {
  //--- check the target cell's row and column against the given
  //    checkrange area and return True if the target cell is
  //    inside that range
  var targetRow = targetCell.getRow();
  if (targetRow < checkRange.getRow() || targetRow > checkRange.getLastRow()) return false;

  var targetColumn = targetCell.getColumn();
  if (targetColumn < checkRange.getColumn() || targetColumn > checkRange.getLastColumn()) return false;

  //--- the target cell is in the range!
  return true;
}

Полная функция события для события редактирования будет

function onEdit(eventObj) {
  //--- you could set up a dynamic named range for this area to make it easier
  var checkRange = SpreadsheetApp.getActiveSheet().getRange("B2:B10");  
  if (isInRange(checkRange, eventObj.range)) {
    //--- the ID cell is on the same row, one cell to the left
    var idCell = eventObj.range.offset(0,-1);
    //--- the status cell is the one that was edited
    var statusCell = eventObj.range;
    updateProjectStage(statusCell, idCell);
  }
}

Вот все вместе:

function isInRange(checkRange, targetCell) {
  Logger.log('checking isInRange');

  //--- check the target cell's row and column against the given
  //    checkrange area and return True if the target cell is
  //    inside that range
  var targetRow = targetCell.getRow();
  if (targetRow < checkRange.getRow() || targetRow > checkRange.getLastRow()) return false;
  Logger.log('not outside the rows');

  var targetColumn = targetCell.getColumn();
  if (targetColumn < checkRange.getColumn() || targetColumn > checkRange.getLastColumn()) return false;
  Logger.log('not outside the columns');

  //--- the target cell is in the range!
  return true;
}

function onEdit(eventObj) {
  //--- you could set up a dynamic named range for this area to make it easier
  var checkRange = SpreadsheetApp.getActiveSheet().getRange("B2:B10");  
  if (isInRange(checkRange, eventObj.range)) {
    Logger.log('cell is in range');
    //--- the ID cell is on the same row, one cell to the left
    var idCell = eventObj.range.offset(0,-1);
    //--- the status cell is the one that was edited
    var statusCell = eventObj.range;
    updateProjectStage(statusCell, idCell);
  }  else {
    Logger.log('must be outside the range');
  }
}

function updateProjectStage(status, id) {
  Logger.log('we are updating');
}
person PeterT    schedule 10.08.2018
comment
Хм, в основном я заставил его работать в соответствии с вашей логикой, но последняя функция updateProjectStage не запускает HTTP-запрос Post. У меня возникает какая-то ошибка Недействительный идентификатор билета. Если я регистрирую sanitizedResponse, он отлично распечатывается в журналах - я могу вручную ввести его в новую вкладку, и он обновит запись CRM. Но он не запускает этот URL. Хм, что это может быть ...?! - person Deven Blackburn; 14.08.2018
comment
Похоже, это отдельный вопрос. Пример, который я опубликовал, должен привести вас к функции updateProjectStage, чтобы сделать ваш HTTP-запрос Post. Вы можете зарегистрировать параметры status и id и / или весь postURL, чтобы проверить формат запроса и информацию. Но похоже, что это больше проблема с вашими данными, имеющими доступ к вашей частной учетной записи на сервере crm, с чем я не могу вам помочь, учитывая приведенную выше информацию. - person PeterT; 14.08.2018
comment
Да, ты прав. У меня все работает, используя ваше решение, но вы перепутали две переменные. statusCell на самом деле idCelll и наоборот. Если бы вы могли их отредактировать, я отмечу этот вопрос как решенный. thumbs_up - person Deven Blackburn; 15.08.2018
comment
Ответ отредактирован и обновлен. Извините за путаницу - person PeterT; 15.08.2018