簡體   English   中英

Google Apps 腳本 API 逐個遍歷/循環 ID

[英]Google Apps Script API iterate/ loop through ID individually

我有一個端點,我需要 go 通過 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:無法從未定義中讀取屬性“名稱”,我猜 JSON 中返回了一些空值/空白,因此它無法讀取長度

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 看起來像……

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', 'xxxx@xxxs.com')
      
      // 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 'https://displayvideo.googleapis.com/v1/advertisers/'+adID+'/lineItems/'+LIs[i]+'/targetingTypes/TARGETING_TYPE_AGE_RANGE/assignedTargetingOptions' ,並將它們放入電子表格。

為此,這個答案怎么樣? 根據您的問題,我認為您的callApi5()腳本有效,而jsonvar json = JSON.parse(content); 是您在問題中顯示的值。 所以我想建議修改 ListLI360API_Agetest 的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 點。
  • var 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 object 的結構相同。 如果 LIs 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

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM