从另一个应用程序(IFTTT)写入单元格时触发电子邮件

时间:2014-10-24 18:05:04

标签: google-apps-script google-sheets google-apps

所以这就是我一直在做的事情。我是一名篮球教练,并有一个电子表格可以吸引我所有的球员。来自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#gid=0 非常感谢任何帮助或指导!谢谢!

1 个答案:

答案 0 :(得分:7)

我最初为your previous question写了这个答案,所以它包含了你的一些评论的答案,但是由于你继续要求社区逐步写下这里, #39;下一步。


  

我遇到的问题是,如果有三条推文同时进入电子表格,使用我的代码,它只会更新最近的单元格,而不是全部三条。这有意义吗?

是的,确实有意义。

onEdit()触发器函数调用电子表格服务函数以从工作表中获取当前信息时,它会进入"竞争条件"。如果在触发onEdit()的更改后的工作表中发生任何更改,并且计划的时间发生变化,则这些更改将在运行时显示。当您认为您正在处理的更改位于最后一行时,您所看到的内容 - 当您进行处理时,可能会有新的最后一行。

好消息 - 传递给onEdit的事件对象的属性包含更改的详细信息。 (参数e。)请参阅Event objects

通过使用e.rangee.value,您会发现您拥有触发触发器的已编辑单元格的位置和内容。如果在触发器服务之前有其他推文到达,那么您的功能将不会被欺骗处理最后一行。

在新的工作表中,onEdit()可以触发多个单元格的更改,例如cut&糊。但不太可能发生,它值得报道。

  

好了,在获得电子表格后,所有设置和放大实际上使用IFTTT的触发器,它不起作用。 :(我假设它没有将它作为活动单元复制,只要它自动将其复制到电子表格中。有任何关于解决方法的想法吗?

问:什么时候编辑不是编辑?答:当它由脚本制作时。在这种情况下,它是更改。您可以添加可安装的on Change函数来捕获这些事件。不幸的是,更改事件比编辑事件更简洁,因此您不得不阅读电子表格以找出已更改的内容。我的习惯是让变更处理程序通过构造虚假事件来模拟编辑(正如我们为测试所做的那样),并将其传递给onEdit函数。

所以试一试。这个脚本:

  • 处理一个"坏词"的列表。 (可以很容易地监控您的产品或原因。)
  • 有一个onEdit()函数,它使用事件对象来计算触发函数调用的行。
  • 颜色"坏"鸣叫
  • 具有基于How can I test a trigger function in GAS?
  • 测试onEdit()触发器的功能
  • 包括playCatchUp(e),一个可安装的触发器功能(更改和/或基于时间),它将评估之前未评估过的任何行。 Script property "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://stackoverflow.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.");
  }  
}

screenshot