Google Apps Script API 单独迭代/循环通过 ID
我有一个端点需要经过 X 次(取决于有多少个 ID),每次调用都需要分配其单独的 LineItem ID 并返回 JSON 响应。
我尝试了以下代码,似乎我可以调用 API,但似乎无法弄清楚如何将响应转换回我的工作表,因此在下面的情况下,我可能有最多 10 个 LI ID 需要单独调用 > 返回结果>复制到特定范围的最后一行,然后使用下一个 LI ID 进行下一个 API 调用,等等...
function ListLI360API_Agetest(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('MySheet');
var adID = 1558211;
var LIs =sheet.getRange(2, 3, sheet.getLastRow(), 1).getValues().filter(String);
var LIArrayLength = LIs.length;
for (var i = 0; i <= LIArrayLength; i++) {
if(LIs[i]!== undefined){
var url = 'https://displayvideo.googleapis.com/v1/advertisers/'+adID+'/lineItems/'+LIs[i]+'/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions'
//Logger.log(url);
var response = callApi5 (url, 'GET');
//Logger.log(response);
var content = response.getContentText();
//Logger.log(content);
var json = JSON.parse(content);
//Logger.log(json);
var ageData = json["assignedTargetingOptions"];
//Logger.log(ageData);
var rows = [],
data;
for (i = 0; i <= ageData.length; i++) {
data = ageData[i];
rows.push([data.name]);
}
//save results to spreadsheet in the next blank column and then API for next LI ID
Logger.log(rows);
}
}//endfor
}
我似乎无法读取结果,我尝试将以下内容添加到上面的脚本中,但出现错误
"TypeError: Cannot read property "name" from undefined", im guessing there are some nulls/ blanks being returned in the JSON and hence it cant read the length
JSON 看起来像...
[20-06-24 21:34:57:159 BST] {
"assignedTargetingOptions": [
{
"name": "advertisers/1558211/lineItems/36917016/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions/503004",
"assignedTargetingOptionId": "503004",
"targetingType": "TARGETING_TYPE_AGE_RANGE",
"inheritance": "NOT_INHERITED",
"ageRangeDetails": {
"ageRange": "AGE_RANGE_45_54",
"targetingOptionId": "503004"
}
},
{
"name": "advertisers/1558211/lineItems/36917016/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions/503005",
"assignedTargetingOptionId": "503005",
"targetingType": "TARGETING_TYPE_AGE_RANGE",
"inheritance": "NOT_INHERITED",
"ageRangeDetails": {
"ageRange": "AGE_RANGE_55_64",
"targetingOptionId": "503005"
}
},
{
"name": "advertisers/1558211/lineItems/36917016/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions/503006",
"assignedTargetingOptionId": "503006",
"targetingType": "TARGETING_TYPE_AGE_RANGE",
"inheritance": "NOT_INHERITED",
"ageRangeDetails": {
"ageRange": "AGE_RANGE_65_PLUS",
"targetingOptionId": "503006"
}
}
]
}
[20-06-24 21:34:57:694 BST] {
"assignedTargetingOptions": [
{
"name": "advertisers/1558211/lineItems/36917017/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions/503004",
"assignedTargetingOptionId": "503004",
"targetingType": "TARGETING_TYPE_AGE_RANGE",
"inheritance": "NOT_INHERITED",
"ageRangeDetails": {
"ageRange": "AGE_RANGE_45_54",
"targetingOptionId": "503004"
}
},
{
"name": "advertisers/1558211/lineItems/36917017/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions/503005",
"assignedTargetingOptionId": "503005",
"targetingType": "TARGETING_TYPE_AGE_RANGE",
"inheritance": "NOT_INHERITED",
"ageRangeDetails": {
"ageRange": "AGE_RANGE_55_64",
"targetingOptionId": "503005"
}
},
{
"name": "advertisers/1558211/lineItems/36917017/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions/503006",
"assignedTargetingOptionId": "503006",
"targetingType": "TARGETING_TYPE_AGE_RANGE",
"inheritance": "NOT_INHERITED",
"ageRangeDetails": {
"ageRange": "AGE_RANGE_65_PLUS",
"targetingOptionId": "503006"
}
}
]
}
从这个例子中,有 2 个 LI ID,所以有 2 个单独的输出,我需要取出这些输出的部分并将它们打印到电子表格中
API 函数看起来像...
function callApi5(url, methodType, requestBody) {
var service = getService();
if (service.hasAccess()) {
var headers = {
'Content-Type': 'application/json',
'Accept' :'application/json',
'Authorization': 'Bearer ' + getService().getAccessToken()
};
var options = {
method: methodType,
headers : headers,
muteHttpExceptions: true
};
if (requestBody) {
options.payload = requestBody;
}
return UrlFetchApp.fetch(url, options);
} else {
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s',
authorizationUrl);
}
}
function getService() {
// Create a new service with the given name. The name will be used when
// persisting the authorized token, so ensure it is unique within the
// scope of the property store.
return OAuth2.createService('MyService')
// Set the endpoint URLs, which are the same for all Google services.
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the client ID and secret, from the Google Developers Console.
.setClientId("xxxxx.apps.googleusercontent.com")
.setClientSecret("xxxxxx")
// Set the name of the callback function in the script referenced
// above that should be invoked to complete the OAuth flow.
.setCallbackFunction('authCallback')
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getUserProperties())
// Set the scopes to request (space-separated for Google services).
// this is blogger read only scope for write access is:
.setScope('https://www.googleapis.com/auth/display-video')
// Below are Google-specific OAuth2 parameters.
// Sets the login hint, which will prevent the account chooser screen
// from being shown to users logged in with multiple accounts.
.setParam('login_hint', '[email protected]')
// Requests offline access.
.setParam('access_type', 'offline')
// Forces the approval prompt every time. This is useful for testing,
// but not desirable in a production application.
.setParam('approval_prompt', 'force');
}
我认为您的目标如下。
-
您想要从所有使用
'https://displayvideo.googleapis.com/v1/advertisers/'+adID+'/lineItems/'+LIs[i]+'/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions'
创建的 URL 的请求中检索值,并将它们放入电子表格中。
对此,这个答案怎么样?从您的问题来看,我认为您的
callApi5()
脚本有效,并且
var json = JSON.parse(content);
的
json
是您在问题中显示的值。因此我建议修改
ListLI360API_Agetest
函数。
修改点:
-
当在for循环中使用数组时,请从
0 循环到 array.length - 1
。因为数组的第一个索引是0
。所以,当使用for (var i = 0; i <= LIArrayLength; i++)
时,在LIArrayLength
的最后一个循环处会出现错误。在这种情况下,请修改为for (var i = 0; i < LIArrayLength; i++)
。同样,对于for (i = 0; i <= ageData.length; i++) {
也可以这样说。 -
在您的脚本中,for循环中包含了1个for循环。而且,每个循环都使用变量
i
。在这种情况下,每个循环的i
变量都会受到影响。因此,循环无法正常工作。-
我认为您的
TypeError: Cannot read property "name" from undefined
错误可能是由于以上 2 点造成的。
-
我认为您的
-
LIs
中的var LIs =sheet.getRange(2, 3, sheet.getLastRow(), 1).getValues().filter(String);
是二维数组。所以在这种情况下,我认为LIs[i][0]
比LIs[i]
更合适。
当以上几点反映到您的脚本中时,它变成如下形式。
修改后的脚本:
请复制并粘贴以下脚本,并将目标工作表名称设置为
ss.getSheetByName("###").getRange(1, 10, result.length, 1).setValues(result);
的最后一行。
function ListLI360API_Agetest(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('MySheet'); // Modified
var adID = 1558211;
var LIs = sheet.getRange(2, 3, sheet.getLastRow(), 1).getValues().filter(String);
var LIArrayLength = LIs.length;
var result = []; // Added
for (var i = 0; i < LIArrayLength; i++) { // Modified
if (LIs[i][0] !== undefined) { // Modified
var url = 'https://displayvideo.googleapis.com/v1/advertisers/'+adID+'/lineItems/'+LIs[i][0]+'/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions' // Modified
var response = callApi5 (url, 'GET');
var content = response.getContentText();
var json = JSON.parse(content);
var ageData = json["assignedTargetingOptions"];
for (var j = 0; j < ageData.length; j++) { // Modified
var data = ageData[j];
result.push([data.name]); // Modified
}
}
}
// Please set the destination sheet name.
ss.getSheetByName("###").getRange(1, 1, result.length, 1).setValues(result); // Added
}
-
如果
data.name
不存在,您不想输入值,请将result.push([data.name]);
修改为if (data.name) result.push([data.name]);
。
注意:
-
在此修改后的脚本中,假设从每个 URL 检索的 JSON 对象的结构相同。如果
LIs[i][0]
创建的每个 URL 的结构不同,则需要修改脚本。请注意这一点。 - 我无法从您的问题中理解将值放入电子表格的结果情况。因此在此修改后的脚本中,将值放入目标工作表。如果这与您的实际情况不同,请修改脚本。
参考:
我测试了 Tanike 提供的答案,并修改了最后一部分以便能够打印到电子表格中。我从 JSON 中添加了更多字段来测试这一点,最后添加了:
dataRange = sheet.getRange(lr+1, 17, result.length,result[0].length).setValues(result);
以打印到电子表格上。
function ListLI360API_Agetest(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('MySheet'); // Modified
var adID = 1558211;
var LIs = sheet.getRange(2, 3, sheet.getLastRow(), 1).getValues().filter(String);
var LIArrayLength = LIs.length;
var result = []; // Added
var lr = sheet.getRange('Q1').getDataRegion().getLastRow(); //Added
for (var i = 0; i < LIArrayLength; i++) { // Modified
if (LIs[i][0] !== undefined) { // Modified
var url = 'https://displayvideo.googleapis.com/v1/advertisers/'+adID+'/lineItems/'+LIs[i][0]+'/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions' // Modified
var response = callApi5 (url, 'GET');
var content = response.getContentText();
var json = JSON.parse(content);
var ageData = json["assignedTargetingOptions"];
for (var j = 0; j < ageData.length; j++) { // Modified
var data = ageData[j];
result.push([
data.name,
data.assignedTargetingOptionId,
data.ageRangeDetails.ageRange]); // Modified
}
}
}
// Each Set of results is pushed one after another
dataRange = sheet.getRange(lr+1, 17, result.length,result[0].length).setValues(result);//Modified
}