Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google apps script 应用程序脚本-创建可安装的OneEdit触发器以调用发出API请求的函数-不工作_Google Apps Script_Triggers_Urlfetch_Google Apps Script Api - Fatal编程技术网

Google apps script 应用程序脚本-创建可安装的OneEdit触发器以调用发出API请求的函数-不工作

Google apps script 应用程序脚本-创建可安装的OneEdit触发器以调用发出API请求的函数-不工作,google-apps-script,triggers,urlfetch,google-apps-script-api,Google Apps Script,Triggers,Urlfetch,Google Apps Script Api,所以我对应用程序脚本比较陌生,已经成功地使用urlFetchApp发出API请求,并将数据拉到我的google工作表上。现在我感兴趣的是在编辑特定单元格的内容时运行此API请求代码。单元格的内容将集成到请求查询中。 更具体地说,我通过API提取公司财务报告,我希望能够在单元格中输入新的公司股票代码,并通过API请求立即将该公司的财务数据提取到我的工作表中 我(根据经验)了解,由于权限问题,简单触发器OneEdit(e)无法工作,我需要创建一个可安装的触发器。但出于某种原因,即使UrlFetchA

所以我对应用程序脚本比较陌生,已经成功地使用urlFetchApp发出API请求,并将数据拉到我的google工作表上。现在我感兴趣的是在编辑特定单元格的内容时运行此API请求代码。单元格的内容将集成到请求查询中。 更具体地说,我通过API提取公司财务报告,我希望能够在单元格中输入新的公司股票代码,并通过API请求立即将该公司的财务数据提取到我的工作表中

我(根据经验)了解,由于权限问题,简单触发器OneEdit(e)无法工作,我需要创建一个可安装的触发器。但出于某种原因,即使UrlFetchApp在从脚本编辑器运行时工作正常,但在由我创建的可安装触发器触发时,它也无法提取相同的数据。任何关于如何让这项工作和我做错了什么的建议都将非常感谢

这是我的代码:

// make an API request and pull the historical income statements 
// for the company ticker in cell B1 of my sheet
function getIncomeStatement() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var url = 'https://www.alphavantage.co/query?function=INCOME_STATEMENT&symbol='
    + SpreadsheetApp.getActiveSheet().getRange('B1').getValue()
    + '&apikey=*****************';
  var response = UrlFetchApp.fetch(url);
  var financials = JSON.parse(response.getContentText());
  return financials;
}

// get the company's ticker and historic annual income statement reports 
// and print them to the active sheet
function getKeysVals() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var financials = getIncomeStatement();

  // get ticker and paste to sheet
  var symbol = financials['symbol'];
  rgMyRange = sheet.getRange(2, 1, 1, 1);
  rgMyRange.setValue('Requested Ticker');
  rgMyRange = sheet.getRange(2, 2, 1, 1);
  rgMyRange.setValue(symbol);

  // get Income Statement annual reports
  var annualReport = financials['annualReports'];

  // loop over nested objects in annualReports
  colToPaste = 1;
  for (var i = 1; i < annualReport.length; i++) {
    yearKeys = [];
    yearValues = [];

    // loop over keys/values within a specific year and paste keys/values to arrays
    var currentYear = annualReport[i];
    for (var key in currentYear) {
      yearKeys.push(key);
      yearValues.push(currentYear[key]);
    }

    // Combine the 2 arrays into one 2-Dimensional array and paste to sheet
    var values = yearKeys.map(function (e, i) { return [e, yearValues[i]] });
    rgMyRange = sheet.getRange(3, colToPaste, values.length, values[0].length);
    rgMyRange.setValues(values);

    // Move the range by 2 columns to the right avoid overwriting the next year's figures 
    colToPaste = colToPaste + 3;
  }
}

// create an installable trigger for onEdit
function createSpreadsheetEditTrigger() {
  var ss = SpreadsheetApp.getActive();
  ScriptApp.newTrigger('newOnEdit')
      .forSpreadsheet(ss)
      .onEdit()
      .create();
}

// create a new onEdit function to look for changes in cell B1
function newOnEdit(e) {
  var cellAddress = e.range.getA1Notation();
  if (cellAddress === 'B1') {
    getKeysVals();
  }
}
//发出API请求并提取历史损益表
//我的工作表B1单元格中的公司股票代码
函数getIncomeStatement(){
var sheet=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var url='1〕https://www.alphavantage.co/query?function=INCOME_STATEMENT&symbol='
+SpreadsheetApp.getActiveSheet().getRange('B1').getValue()
+“&apikey=****************”;
var response=UrlFetchApp.fetch(url);
var financials=JSON.parse(response.getContentText());
返回财务报表;
}
//获取公司的股票行情和历史年度损益表报告
//并将其打印到活动工作表中
函数getKeysVals(){
var sheet=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var financials=getIncomeStatement();
//获取ticker并粘贴到工作表
var symbol=金融类[‘symbol’];
rgMyRange=sheet.getRange(2,1,1,1);
rgMyRange.setValue('请求的Ticker');
rgMyRange=sheet.getRange(2,2,1,1);
rgMyRange.setValue(符号);
//获取损益表年度报告
var annualReport=财务[‘annualReports’];
//在年度报告中的嵌套对象上循环
colToPaste=1;
对于(变量i=1;i
API受突发保护的速率限制 对于许多API,当他们说,例如:

每分钟最多5个API请求

这实际上意味着每12秒只能发出一个请求。您不能在10秒内发出5个请求,然后等待50秒再发出5个请求

我不知道为什么有些API在文档中没有明确说明这一点,因为很容易假设如果他们说每分钟5个请求,如果您愿意,您可以在0.5秒内发出5个请求

这可能是因为它可以抵御DDOS攻击。想象一下,如果有人获得了数千个免费API密钥,然后设置为协调每个API密钥以同时发送5个请求。这可能会破坏服务器

变通办法 除了获得高级会员资格,您还可以设置一个时间驱动触发器,每12秒发送一次请求,以检查是否有任何股票价格需要检查,这样,就可以一点一点地填写它们。如果它没有找到库存,那么它不会提出请求

或者您可以尝试使用
onEdit
触发器,该触发器使用
PropertiesService

函数onEdit(e){
//获取当前编辑时间
让时间=新日期();
//获取上次请求的时间
让scriptProperties=PropertiesService.getScriptProperties()
let property=scriptProperties.getProperty(“lastRequest”)
let lastRequest=新日期(属性)
//计算自上次请求以来的时间
让timeSinceLastRequest=time.getTime()-lastRequest.getTime()
//如果超过12秒,请发出请求并重新分配属性
如果(TimesInclastRequest>12000){
//在这里提出请求
scriptProperties.setProperty(“lastRequest”,新日期())
}
}
//首先运行此命令以首次设置属性。
函数init(){
让scriptProperties=PropertiesService.getScriptProperties()
scriptProperties.setProperty(“lastRequest”,新日期())
}
工具书类

执行页面中出现的错误是什么?要查看OneEdit触发器的错误,需要转到执行页面。在新编辑器中,您可以通过单击脚本编辑器左侧的报警图标和设置图标之间的按钮找到执行页面。除非提供事件对象,否则无法从脚本编辑器运行OneEdit函数OK found it:TypeError:无法读取getKeysVals处未定义的属性“length”(AlphaVantage:49:36)在newOnEdit(AlphaVantage:104:5)中,如果我从