使用Google Apps Script调用CoinMarketCap API遇'quote未定义'错误求助
排查CoinMarketCap API调用的TypeError问题
在使用Google Apps Script通过CoinMarketCap API获取加密货币报价到Google表格时,持续触发以下错误:
Error
TypeError: Cannot read properties of undefined (reading 'quote')
coin_price @ Code.gs:37
以下是原错误代码:
function coin_price() { const myGoogleSheetName = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Coins"); const coinMarketCapAPICall = { method: "GET", uri: "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest", qs: { start: "1", limit: "200", convert: "USD", }, headers: { "X-CMC_PRO_API_KEY": "here-I-insert-my-API" }, json: true, gzip: true, }; // Get the coins I want from spreadsheet let myCoinSymbols = []; const getValues = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); for (let i = 0; i < getValues.length; i++) { // 1 = Column B in the spreadsheet. const coinSymbol = getValues[i][1]; if (coinSymbol) { myCoinSymbols.push(coinSymbol); } } for (let i = 0; i < myCoinSymbols.length; i++) { const ticker = myCoinSymbols[i]; const coinMarketCapUrl = `https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=${ticker}`; const result = UrlFetchApp.fetch(coinMarketCapUrl, coinMarketCapAPICall); const txt = result.getContentText(); const d = JSON.parse(txt); const row = i + 2; myGoogleSheetName .getRange(row, 12) .setValue(d.data[ticker].quote.USD.price); } }
问题根源
- 请求参数格式错误:你使用了
uri、qs这类第三方HTTP库(如request)专属的参数,但Google Apps Script的UrlFetchApp.fetch不支持这些属性,会导致请求配置失效,干扰API调用。 - 缺少错误检查:直接访问
d.data[ticker].quote.USD.price,如果API返回的data中没有对应代币的数据(比如代币符号错误、API调用超限、网络问题),就会触发undefined读取错误。 - 行号匹配错误:循环索引
i+2的行号计算逻辑不合理,若提取代币时跳过空行,会导致行号与实际表格行错位。
修复后的代码
function coin_price() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Coins"); if (!sheet) { console.log("找不到名为「Coins」的工作表"); return; } const apiKey = "here-I-insert-my-API"; // 替换为你的API密钥 const baseApiUrl = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest"; // 提取代币符号及对应表格行号 const dataRange = sheet.getDataRange().getValues(); const coinRecords = []; for (let rowIndex = 0; rowIndex < dataRange.length; rowIndex++) { const coinSymbol = dataRange[rowIndex][1]; // 读取B列数据 if (coinSymbol && typeof coinSymbol === "string") { coinRecords.push({ symbol: coinSymbol.trim().toUpperCase(), sheetRow: rowIndex + 1 // 表格行号从1开始 }); } } // 批量获取并写入价格 for (const record of coinRecords) { try { // 构造合法的API请求URL const requestUrl = `${baseApiUrl}?symbol=${record.symbol}&convert=USD`; const requestOptions = { method: "GET", headers: { "X-CMC_PRO_API_KEY": apiKey }, muteHttpExceptions: true // 允许捕获HTTP错误状态 }; const response = UrlFetchApp.fetch(requestUrl, requestOptions); const responseCode = response.getResponseCode(); // 检查HTTP响应状态 if (responseCode !== 200) { console.log(`获取${record.symbol}数据失败,状态码:${responseCode},响应内容:${response.getContentText()}`); continue; } const responseData = JSON.parse(response.getContentText()); // 检查API返回的数据结构 if (!responseData.data || !responseData.data[record.symbol]) { console.log(`未查询到${record.symbol}的报价数据`); continue; } const usdPrice = responseData.data[record.symbol].quote.USD.price; sheet.getRange(record.sheetRow, 12).setValue(usdPrice); // 写入L列 } catch (error) { console.log(`处理${record.symbol}时发生错误:${error.message}`); } } }
关键修复点
- 移除了
UrlFetchApp不支持的uri、qs等参数,改用标准URL拼接方式传递查询参数 - 增加工作表存在性检查,避免后续操作无意义报错
- 记录每个代币对应的原始表格行号,确保写入位置准确
- 启用
muteHttpExceptions捕获HTTP错误,便于排查API调用问题 - 增加多层数据结构检查,防止因API返回异常触发
undefined读取错误 - 加入
try-catch块捕获意外错误,保证脚本不会因单个代币处理失败而终止
内容的提问来源于stack exchange,提问作者fedmar
相关产品推荐
相关产品推荐

