Google Apps 脚本每日计划触发器失败
Google Apps Script daily schedule trigger failing
我已经设置了一个函数来调用 Bitly API 来跟踪我的 link 的总点击次数。它设置在一个列中以跟踪每个人的点击次数 link。每次我打开点差时它都会完美更新sheet.
这是此代码
function bitlyStats(bitlink_url) {
var bitlink_url_parts = bitlink_url.split('://');
var bitlink = bitlink_url_parts[1];
var accessToken = 'token';
var fetchUrl = 'https://api-ssl.bitly.com/v4/bitlinks/' + bitlink + '/clicks/summary?unit=day&units=1';
var headers = {
'Authorization': 'Bearer '+ accessToken,
'Content-Type': 'application/json',
};
var params = {
'method' : 'get',
'headers' : headers,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch(fetchUrl, params);
var clickCount = JSON.parse(response).total_clicks;
return clickCount;
}
我设置了第二个函数,每天将这些结果附加到 sheet 中的第二个选项卡。我已经为 BitlyStats 设置了一个触发器以在一夜之间更新,然后到 运行 追加功能。但是我在 BitlyStats 的触发器上收到错误..
TypeError: bitlink_url.split 不是函数
在 bitlyStats(BitlyStats:10:39)
这会导致追加函数复制“#NAME?”在第二个选项卡上的每个单元格中。
我不确定为什么函数在打开时发现错误?
如有任何建议,我们将不胜感激!谢谢。
编辑
在一些反馈和潜在答案之后,很明显,基于时间的触发器将无法与引用单元格中输入内容的函数一起使用。我现在正在尝试为“bitlink_url”创建一个 API 调用函数,因此它会创建一个位 link 的列表,而不是已经在 sheet 中的列表。
但是我运行正在处理新代码的问题,如有任何建议,我们将不胜感激。我对此还是很陌生。谢谢!这是我使用的参考指南https://dev.bitly.com/api-reference#getBitlinksByGroup
日志显示“null”
function getBitly() {
var accessToken = 'x'; //access token
var groupID = 'x' ; //group ID
var fetchUrl2 = 'https://api-ssl.bitly.com/v4/groups/' + groupID + '/bitlinks?size=10';
var headers = {
'Authorization': 'Bearer '+ accessToken,
'Content-Type': 'application/json',
};
var params = {
'method' : 'get',
'headers' : headers,
'muteHttpExceptions' : true
};
var response2 = UrlFetchApp.fetch(fetchUrl2, params);
var bitlinkList = JSON.parse(response2).link;
Logger.log(bitlinkList);
##EDIT2 - 已解决##
感谢@lamblichus,我能够修改代码并解决在使用地图函数时必须引用 Bit.ly URL 保存的每个单元格的问题。下面的最终代码。我还将附加值代码合并到同一函数中。
function getStats() {
var sheet = SpreadsheetApp.getActive().getSheetByName("VV Bitly Links");
var bitlyurls = sheet.getRange(2,12,sheet.getLastRow()-1).getValues().flat();
var clickCounts = bitlyurls.map(bitlink => [bitlyStats2(bitlink)]);
sheet.getRange(2,6,clickCounts.length).setValues(clickCounts);
var sheet2 = SpreadsheetApp.getActive().getSheetByName("Bitly Reporting");
var data = sheet.getRange(2,6,sheet.getLastRow()-1,6).getValues();
var lastrow = sheet2.getLastRow();
sheet2.getRange(lastrow+1,1,data.length,data[0].length).setValues(data);
}
function bitlyStats2(bitlink) {
var accessToken = 'xx'; //token
var fetchUrl = 'https://api-ssl.bitly.com/v4/bitlinks/' + bitlink + '/clicks/summary?unit=day&units=1';
var headers = {
'Authorization': 'Bearer '+ accessToken,
'Content-Type': 'application/json',
};
var params = {
'method' : 'get',
'headers' : headers,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch(fetchUrl, params);
var clickCount = JSON.parse(response).total_clicks;
return clickCount;
}
function installTrigger() {
ScriptApp.newTrigger("getStats")
.timebased()
.atHour(3)
.everyDays(1)
.create();
}
最后,由于这引用了很多 Bit.ly link,其中一些不再活跃并且 return 一天点击 0 次,我创建了另一个从第二个选项卡中删除空单元格的函数 "Bitly Reporting"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Bitly Reporting");
var range = sh.getDataRange();
var delete_val = ""
var col_to_search = 1;
function deleteEmptys(){
var rangeVals = range.getValues();
for (var i = rangeVals.length-1; i >=0; i--){
if(rangeVals[i][col_to_search] === delete_val){
sh.deleteRow(i+1);
};
};
};
function installTrigger2() {
ScriptApp.newTrigger("deleteEmptys")
.timebased()
.atHour(5)
.everyDays(1)
.create();
问题:
您不能将参数传递给通过时间驱动触发器触发的函数。正因为如此,bitlink_url
未定义,所以bitlink_url.split('://')
报错。
解决方案:
- 为
bitlyStats
设置默认参数:
function bitlyStats(bitlink_url = "YOUR_URL") {
- 或者在触发器中调用包装函数,以便定义
bitlink_url
:
function timeTriggeredFunction() {
var bitlink_url = "YOUR_URL";
bitlyStats(bitlink_url);
}
更新:
您在 A
列中有一系列 URL,您希望根据这些 URL 定期更新 B
列(使用 bitlyStats
).
在这种情况下,我建议不要使用 custom functions,它不能通过时间驱动的触发器调用,而是安装一个触发器来调用一个函数(名为 triggeredFunction
下面的示例)将:
- 从 A 列中检索 URLs。
- 对于每个 URL,检索其
clickCounts
,使用 bitlyStats
。
- 将结果
clickCounts
写入 B 列。
代码示例:
function triggeredFunction() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
var bitlink_urls = sheet.getRange(2,1,sheet.getLastRow()-1).getValues().flat();
var clickCounts = bitlink_urls.map(bitlink_url => [bitlyStats(bitlink_url)]);
sheet.getRange(2,2,clickCounts.length).setValues(clickCounts);
}
function installTrigger() {
ScriptApp.newTrigger("triggeredFunction")
.timeBased()
.atHour(3)
.everyDays(1)
.create();
}
注:
- 上面的示例中,安装了时间驱动触发器programmatically by running
installTrigger
once, and by this, triggeredFunction
would run every day between 3 and 4 AM. You could also install it manually,根据自己的情况修改触发器设置。
- 在上面的示例中,假设带有数据的 sheet 被命名为
Sheet1
。如果不是这样,请更改它。
我已经设置了一个函数来调用 Bitly API 来跟踪我的 link 的总点击次数。它设置在一个列中以跟踪每个人的点击次数 link。每次我打开点差时它都会完美更新sheet.
这是此代码
function bitlyStats(bitlink_url) {
var bitlink_url_parts = bitlink_url.split('://');
var bitlink = bitlink_url_parts[1];
var accessToken = 'token';
var fetchUrl = 'https://api-ssl.bitly.com/v4/bitlinks/' + bitlink + '/clicks/summary?unit=day&units=1';
var headers = {
'Authorization': 'Bearer '+ accessToken,
'Content-Type': 'application/json',
};
var params = {
'method' : 'get',
'headers' : headers,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch(fetchUrl, params);
var clickCount = JSON.parse(response).total_clicks;
return clickCount;
}
我设置了第二个函数,每天将这些结果附加到 sheet 中的第二个选项卡。我已经为 BitlyStats 设置了一个触发器以在一夜之间更新,然后到 运行 追加功能。但是我在 BitlyStats 的触发器上收到错误..
TypeError: bitlink_url.split 不是函数 在 bitlyStats(BitlyStats:10:39)
这会导致追加函数复制“#NAME?”在第二个选项卡上的每个单元格中。 我不确定为什么函数在打开时发现错误?
如有任何建议,我们将不胜感激!谢谢。
编辑 在一些反馈和潜在答案之后,很明显,基于时间的触发器将无法与引用单元格中输入内容的函数一起使用。我现在正在尝试为“bitlink_url”创建一个 API 调用函数,因此它会创建一个位 link 的列表,而不是已经在 sheet 中的列表。
但是我运行正在处理新代码的问题,如有任何建议,我们将不胜感激。我对此还是很陌生。谢谢!这是我使用的参考指南https://dev.bitly.com/api-reference#getBitlinksByGroup
日志显示“null”
function getBitly() {
var accessToken = 'x'; //access token
var groupID = 'x' ; //group ID
var fetchUrl2 = 'https://api-ssl.bitly.com/v4/groups/' + groupID + '/bitlinks?size=10';
var headers = {
'Authorization': 'Bearer '+ accessToken,
'Content-Type': 'application/json',
};
var params = {
'method' : 'get',
'headers' : headers,
'muteHttpExceptions' : true
};
var response2 = UrlFetchApp.fetch(fetchUrl2, params);
var bitlinkList = JSON.parse(response2).link;
Logger.log(bitlinkList);
##EDIT2 - 已解决## 感谢@lamblichus,我能够修改代码并解决在使用地图函数时必须引用 Bit.ly URL 保存的每个单元格的问题。下面的最终代码。我还将附加值代码合并到同一函数中。
function getStats() {
var sheet = SpreadsheetApp.getActive().getSheetByName("VV Bitly Links");
var bitlyurls = sheet.getRange(2,12,sheet.getLastRow()-1).getValues().flat();
var clickCounts = bitlyurls.map(bitlink => [bitlyStats2(bitlink)]);
sheet.getRange(2,6,clickCounts.length).setValues(clickCounts);
var sheet2 = SpreadsheetApp.getActive().getSheetByName("Bitly Reporting");
var data = sheet.getRange(2,6,sheet.getLastRow()-1,6).getValues();
var lastrow = sheet2.getLastRow();
sheet2.getRange(lastrow+1,1,data.length,data[0].length).setValues(data);
}
function bitlyStats2(bitlink) {
var accessToken = 'xx'; //token
var fetchUrl = 'https://api-ssl.bitly.com/v4/bitlinks/' + bitlink + '/clicks/summary?unit=day&units=1';
var headers = {
'Authorization': 'Bearer '+ accessToken,
'Content-Type': 'application/json',
};
var params = {
'method' : 'get',
'headers' : headers,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch(fetchUrl, params);
var clickCount = JSON.parse(response).total_clicks;
return clickCount;
}
function installTrigger() {
ScriptApp.newTrigger("getStats")
.timebased()
.atHour(3)
.everyDays(1)
.create();
}
最后,由于这引用了很多 Bit.ly link,其中一些不再活跃并且 return 一天点击 0 次,我创建了另一个从第二个选项卡中删除空单元格的函数 "Bitly Reporting"
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("Bitly Reporting");
var range = sh.getDataRange();
var delete_val = ""
var col_to_search = 1;
function deleteEmptys(){
var rangeVals = range.getValues();
for (var i = rangeVals.length-1; i >=0; i--){
if(rangeVals[i][col_to_search] === delete_val){
sh.deleteRow(i+1);
};
};
};
function installTrigger2() {
ScriptApp.newTrigger("deleteEmptys")
.timebased()
.atHour(5)
.everyDays(1)
.create();
问题:
您不能将参数传递给通过时间驱动触发器触发的函数。正因为如此,bitlink_url
未定义,所以bitlink_url.split('://')
报错。
解决方案:
- 为
bitlyStats
设置默认参数:
function bitlyStats(bitlink_url = "YOUR_URL") {
- 或者在触发器中调用包装函数,以便定义
bitlink_url
:
function timeTriggeredFunction() {
var bitlink_url = "YOUR_URL";
bitlyStats(bitlink_url);
}
更新:
您在 A
列中有一系列 URL,您希望根据这些 URL 定期更新 B
列(使用 bitlyStats
).
在这种情况下,我建议不要使用 custom functions,它不能通过时间驱动的触发器调用,而是安装一个触发器来调用一个函数(名为 triggeredFunction
下面的示例)将:
- 从 A 列中检索 URLs。
- 对于每个 URL,检索其
clickCounts
,使用bitlyStats
。 - 将结果
clickCounts
写入 B 列。
代码示例:
function triggeredFunction() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
var bitlink_urls = sheet.getRange(2,1,sheet.getLastRow()-1).getValues().flat();
var clickCounts = bitlink_urls.map(bitlink_url => [bitlyStats(bitlink_url)]);
sheet.getRange(2,2,clickCounts.length).setValues(clickCounts);
}
function installTrigger() {
ScriptApp.newTrigger("triggeredFunction")
.timeBased()
.atHour(3)
.everyDays(1)
.create();
}
注:
- 上面的示例中,安装了时间驱动触发器programmatically by running
installTrigger
once, and by this,triggeredFunction
would run every day between 3 and 4 AM. You could also install it manually,根据自己的情况修改触发器设置。 - 在上面的示例中,假设带有数据的 sheet 被命名为
Sheet1
。如果不是这样,请更改它。