Инициировать электронное письмо, когда ячейка записана из другого приложения (IFTTT)

Итак, вот над чем я работаю. Я - тренер по баскетболу, и у меня есть таблица, в которую попадают все твиты моих игроков с IFTTT.com (в основном это RSS-канал из списка твиттеров, а когда он обновляется, он обновляет таблицу).

Я работал над кодированием, которое в основном говорит: "Если игрок пишет в Твиттере неподходящее слово, немедленно напишите мне".

Я понял, что если я просто напишу неуместное слово, он покраснеет и отправит мне электронное письмо. Однако я не понял, как получить код для отправки мне электронного письма после того, как IFTTT автоматически обновит электронную таблицу с помощью твитов.

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

function onEdit(e) {
    var ss = SpreadsheetApp.getActiveSpreadsheet();//Get the spreadsheet
    var sheet = ss.getActiveSheet()//Get the active sheet
    var cell = ss.getActiveCell().activate();//Get the active cell. 
    var badCell = cell.getA1Notation();//Get the cells A1 notation.
    var badCellContent = cell.getValue();//Get the value of that cell. 


    if (badCellContent.match("players")){
        cell.setBackgroundColor("red")
        MailApp.sendEmail("antadrag@gmail.com", "Notice of possible inappropriate tweet", "This tweet       says: " + badCellContent + ".");
    }
}

Вот ссылка на таблицу, с которой я сейчас работаю: https://docs.google.com/spreadsheets/d/1g5XaIycy69a3T2YcWhcbBy0hYrxSfoEEz8c4-zP63O8/edit Любая помощь или руководство по этому вопросу очень ценится! Спасибо!

1 ответ

Решение

Первоначально я написал этот ответ для вашего предыдущего вопроса, поэтому он включает ответы на некоторые ваши комментарии оттуда, но, поскольку вы продолжаете просить сообщество написать этот шаг за шагом, вот следующий шаг.


Проблема, с которой я сталкиваюсь, заключается в том, что если в таблицу одновременно попадают три твита с моим кодом, обновляются только самые последние ячейки, а не все три. Имеет ли это смысл?

Да, это имеет смысл.

Когда onEdit() Функция триггера вызывает функцию Spreadsheet Service, чтобы получить текущую информацию из листа, она входит в "Состояние гонки". Если какие-либо изменения происходят на листе после изменения, которое вызвало onEdit()и время, когда оно запланировано, эти изменения будут видны при запуске. Это то, что вы видите, когда предполагаете, что обрабатываемое вами изменение находится в последней строке - к тому времени, когда вы его обрабатываете, может появиться новая последняя строка.

Хорошая новость - атрибуты объекта события переданы onEdit содержать детали изменения. (Параметр e.) См. Объекты событий.

Используя e.range а также e.value вы обнаружите, что у вас есть местоположение и содержание отредактированной ячейки, которая нажала на курок. Если до обслуживания триггера поступят дополнительные твиты, ваша функция не будет обманута обработкой последней строки.

В новых листах onEdit() может быть запущен для изменений нескольких ячеек, таких как вырезать и вставить. Однако маловероятно, что это может случиться, но это стоит осветить.

Что ж, после того, как электронная таблица полностью настроена и фактически использует триггер из IFTTT, она не работает.:(Я предполагаю, что он не дублирует его как активную ячейку всякий раз, когда он автоматически вытягивает ее в электронную таблицу. Есть какие-нибудь идеи по поводу этого?

Q: Когда редактирование не редактирование? A: Когда это сделано по сценарию. В этом случае это изменение. Вы можете добавить устанавливаемый on Change функция, чтобы поймать эти события. К сожалению, событие изменения менее многословно, чем событие редактирования, поэтому вы вынуждены читать электронную таблицу, чтобы выяснить, что изменилось. Моя привычка состоит в том, чтобы обработчик изменений имитировал редактирование, создавая поддельное событие (как мы это делали для тестирования) и передавая его onEdit функция.

Так что попробуйте. Этот скрипт:

  • обрабатывает список "плохих слов". (Может так же легко отслеживать упоминания о вашем продукте или причине.)
  • имеет onEdit() функция, которая использует объект события для оценки строки (строк), которые вызвали вызов функции.
  • цвета "плохих" твитов
  • имеет функцию для проверки триггера onEdit(), основанную на Как я могу проверить функцию триггера в GAS?
  • включает в себя playCatchUp(e)устанавливаемая триггерная функция (изменение и / или на основе времени), которая будет оценивать любые строки, которые не были оценены ранее. Свойство скрипта "Last Processed Row" используется для отслеживания этого значения строки. (Если вы планируете удалять строки, вам нужно настроить свойство.)
  • Функция sendMail закомментирована.

Наслаждайтесь!

// Array of bad words. Could be replaced with values from a range in spreadsheet.
var badWords = [
  "array",
  "of",
  "unacceptable",
  "words",
  "separated",
  "by",
  "commas"
];

function onEdit(e) {
  if (!e) throw new Error( "Event object required. Test using test_onEdit()" );

  Logger.log( e.range.getA1Notation() );

  // e.value is only available if a single cell was edited
  if (e.hasOwnProperty("value")) {
    var tweets = [[e.value]];
  }
  else {
    tweets = e.range.getValues();
  }
  var colors = e.range.getBackgrounds();

  for (var i=0; i<tweets.length; i++) {
    var tweet = tweets[i][0];
    for (var j=0; j< badWords.length; j++) {
      var badWord = badWords[j];
      if (tweet.match(badWord)) {
        Logger.log("Notice of possible inappropriate tweet: " + tweet);
        colors[i][0] = "red";
        //MailApp.sendEmail(myEmail, "Notice of possible inappropriate tweet", tweet);
        break;
      }
    }
  }
  e.range.setBackgrounds(colors);
  PropertiesService.getDocumentProperties()
                   .setProperty("Last Processed Row",
                                (e.range.getRowIndex()+tweets.length-1).toString());
}

// Test function, adapted from https://stackru.com/a/16089067/1677912
function test_onEdit() {
  var fakeEvent = {};
  fakeEvent.authMode = ScriptApp.AuthMode.LIMITED;
  fakeEvent.user = "amin@example.com";
  fakeEvent.source = SpreadsheetApp.getActiveSpreadsheet();
  fakeEvent.range = fakeEvent.source.getActiveSheet().getDataRange();
  // e.value is only available if a single cell was edited
  if (fakeEvent.range.getNumRows() === 1 && fakeEvent.range.getNumColumns() === 1) {
    fakeEvent.value = fakeEvent.range.getValue();
  }

  onEdit(fakeEvent);
}

// Installable trigger to handle change or timed events
// Something may or may not have changed, but we won't know exactly what
function playCatchUp(e) {
  // Check why we've been called
  if (!e)
    Logger.log("playCatchUp called without Event");
  else {
    // If onChange and the change is an edit - no work to do here
    if (e.hasOwnProperty("changeType") && e.changeType === "EDIT") return;

    // If timed trigger, nothing special to do.
    if (e.hasOwnProperty("year")) {
      var date = new Date(e.year, e.month, e["day-of-month"], e.hour, e.minute, e.second); 
      Logger.log("Timed trigger: " + date.toString() );
    }
  }

  // Find out where to start processing tweets
  // The first time this runs, the property will be null, yielding NaN
  var lastProcRow = parseInt(PropertiesService.getDocumentProperties()
                         .getProperty("Last Processed Row"));
  if (isNaN(lastProcRow)) lastProcRow = 0;

  // Build a fake event to pass to onEdit()
  var fakeEvent = {};
  fakeEvent.source = SpreadsheetApp.getActiveSpreadsheet();
  fakeEvent.range = fakeEvent.source.getActiveSheet().getDataRange();
  var numRows = fakeEvent.range.getLastRow() - lastProcRow;
  if (numRows > 0) {
    fakeEvent.range = fakeEvent.range.offset(lastProcRow, 0, numRows);
    onEdit(fakeEvent);
  }
  else {
    Logger.log("All caught up.");
  }  
}

Скриншот

Другие вопросы по тегам