所以这就是我一直在做的事情。我是一名篮球教练并且有一个电子表格可以从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("[email protected]", "Notice of possible inappropriate tweet", "This tweet says: " + badCellContent + ".");
}
}
这是我正在使用的电子表格的链接:https://docs.google.com/spreadsheets/d/1g5XaIycy69a3T2YcWhcbBy0hYrxSfoEEz8c4-zP63O8/edit#gid=0非常感谢任何帮助或指导!谢谢!
我最初为your previous question写了这个答案,所以它包含了你的一些评论的答案,但是由于你继续要求社区逐步写下这一步,下面就是下一步。
我遇到的问题是,如果三条推文同时进入电子表格,使用我的代码,它只会更新最新的单元格,而不是全部三条。那有意义吗?
是的,它确实有意义。
当onEdit()
触发器函数调用Spreadsheet Service函数从工作表中获取当前信息时,它会进入“Race condition”。如果在触发onEdit()
的更改之后工作表中发生任何更改,并且计划时间更改,则这些更改将在运行时显示。当您假设您正在处理的更改位于最后一行时,您就会看到这一点 - 当您处理它时,可能会有一个新的最后一行。
但好消息是 - 传递给onEdit
的事件对象的属性包含更改的详细信息。 (参数e
。)见Event objects。
通过使用e.range
和e.value
,您将发现您拥有触发触发器的已编辑单元格的位置和内容。如果在触发器被服务之前有其他推文到达,则不会欺骗您的函数处理最后一行。
在新的工作表中,onEdit()
可以触发多个单元格更改,例如剪切和粘贴。不太可能发生,它值得覆盖。
好吧,在获得电子表格所有设置并实际使用IFTTT的触发器后,它不起作用。 :(我假设它不会将它作为活动单元复制,只要它自动将其拉入电子表格。任何关于解决方法的想法?
问:什么时候编辑不是编辑?答:当它由脚本制作时。在那种情况下,这是一个变化。您可以添加可安装的on Change
函数来捕获这些事件。不幸的是,更改事件比编辑事件更简洁,因此您不得不阅读电子表格以找出已更改的内容。我的习惯是让变更处理程序通过构造虚假事件来模拟编辑(正如我们为测试所做的那样),并将其传递给onEdit
函数。
所以试一试。这个脚本:
onEdit()
函数,它使用事件对象来计算触发函数调用的行。playCatchUp(e)
,一个可安装的触发器函数(更改和/或基于时间),它将评估之前未评估过的任何行。 Script property "Last Processed Row"
用于跟踪该行值。 (如果您打算删除行,则需要调整属性。)请享用!
// 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 = "[email protected]";
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.");
}
}