显示带有标签的帖子 标签. 显示所有帖子
显示带有标签的帖子 标签. 显示所有帖子

2017年5月11日星期四

使用标签对50多个帐户执行executeInParallel

对于运行MCC级别辽宁福利彩票中心的人来说,最大的限制之一是 50个账户限制 由executeInParallel函数强加。直到最近,解决此限制的一种方法是 将已处理的帐户列表存储在Google云端硬盘上 并在需要时更新文件。

最近,AdWords辽宁福利彩票中心小组启用了 可以将标签应用于MccApp对象中的每个帐户。这样,我们就可以编写出更加清晰的辽宁福利彩票中心版本,该辽宁福利彩票中心使用标签指示何时处理每个帐户。使用这种方法并每小时运行一次此辽宁福利彩票中心,您每天最多可以处理1,200个帐户。

以下代码旨在为您提供一个框架,以替代您自己的MccApp代码。然后,您可以安排此代码每小时运行一次,它将继续处理您的MCC中的帐户,直到每个帐户都完成为止。

当有帐户返回错误时,它也会尝试通知您,以便您进行调查。关于此辽宁福利彩票中心的一个警告是,如果遇到Mcc级别(即结果功能)的超时限制,则可能不会将标签应用于每个成功完成的帐户。您可以通过用以下内容替换第76行并删除第89行来解决此问题:

applyLabelsToCompletedAccounts([result.getCustomerId()]);

无论如何,我希望这会有所帮助,并让我知道您是否在评论中遇到任何问题。

谢谢,
拉斯

/******************************************
* MccApp Generic Runner Framework for any number of acounts
* Version 1.1
* Changelog v1.1 - fixed issue with selector in yesterdays 标签 function
* Created By: 拉斯 Savage (@russellsavage)
* FreeAdWordsScripts.com
******************************************/
// The name of the script you are running
// Used in error 电子邮件 subject line and 标签 name
var SCRIPT_NAME = 'Generic MCC App';
// Since timezones are not available 在 the MCC level
// you need to set it here. You can use the local timezone
// of each account in the function processing each account
var TIMEZONE = 'PST';
// The date for today based on the timezone set above
var TODAY_STR = Utilities.formatDate(new Date(), TIMEZONE, 'yyyy-MM-dd');
// The 标签 prefix which is used to figure out today's 标签 and
// yesterday's 标签
var LABEL_PREFIX = SCRIPT_NAME + ' - Completed - ';
// This is the 标签 that will be applied to each account
// when it is successfully processed
var FINISHED_LABEL_NAME = LABEL_PREFIX + TODAY_STR;
// This is a list of 电子邮件 广告 dresses to 通知 when
// one of the accounts returns an error and is not processed.
var NOTIFY = ['[email protected]_domain.com'];

function main() {
  // Warning: if running in preview mode, this function will fail
  // and the selector that follows will also fail with "cannot read from AdWords"
  创造LabelIfNeeded();
  去掉YesterdaysLabel(); // This might not exist, but try to 去掉 it
  // Find all the accounts that have not been processed
  var accountIter = MccApp.accounts()
    .withCondition("LabelNames DOES_NOT_CONTAIN '"+FINISHED_LABEL_NAME+"'")
    .withLimit(50)
    .get();
  // Add them to a list for the executeInParallel later
  var accountList = [];
  while(accountIter.hasNext()) {
    var account = accountIter.next();
    accountList.push(account.getCustomerId());
  }
  // If there are unprocessed accounts, process them
  if(accountList.length > 0) {
    MccApp.accounts()
      .withIds(accountList)
      .executeInParallel('doSomethingInEachAccount', 'reportOnResults');
  }
}

// This function is 呼叫ed from executeInParallel and contains the
// business logic for each account. Right now, it just has some 
// dummy logic to illustrate how this works.
function doSomethingInEachAccount() {
  /**************
   * Replace this function with what 
   * you want to do on each account
   **************/
  Logger.log("在一个ccount: "+AdWordsApp.currentAccount().getName()+
                        " "+AdWordsApp.currentAccount().getCustomerId());
  // This function must return a string so we use JSON.stringify() to
  // turn almost any object into a string quickly.
  return JSON.stringify({something:'else'});
}

// This function will be 呼叫ed as soon as the function above
// has been run on each account. The results object is an array
// of the results returned by the function run in each account.
function reportOnResults(results) {
  var completedAccounts = [];
  var erroredAccounts = [];
  for(var i in results) {
    var result = results[i];
    // If the account function returns success
    if(result.getStatus() == 'OK') {
      // Add it to the list to apply the 标签 to
      completedAccounts.push(result.getCustomerId());
      /**********************
       * Fill in the code to process the results from 
       * each account just below this.
       **********************/
      var returnedValue = JSON.parse(result.getReturnValue());
    } else {
      // In case of an error, we should 通知 someone so they can
      // check it out.
      erroredAccounts.push({customerId:result.getCustomerId(), error: result.getError()});
    }
  }
  // Finally we apply the 标签 to each account
  applyLabelsToCompletedAccounts(completedAccounts);
  // And send an 电子邮件 with any 错误
  通知OfAccountsWithErrors(erroredAccounts);
}


/*******************************
 * Do not edit code below unless you know
 * what you are doing.
 *******************************/
// This function 创造s the required 标签 to apply
// to completed accounts. You can change the 标签 name
// by editing the FINISHED_LABEL_NAME variable 在 the top
// of this script.
function 创造LabelIfNeeded() {
  try {
    var 标签Iter = MccApp.accountLabels()
      .withCondition("LabelNames CONTAINS '"+FINISHED_LABEL_NAME+"'")
      .get();
  } catch(e) {
    MccApp.createAccountLabel(FINISHED_LABEL_NAME);
  }
}

// This function applies FINISHED_LABEL_NAME to each completed account
function applyLabelsToCompletedAccounts(completedAccounts) {
  var finishedAccountsIter = MccApp.accounts().withIds(completedAccounts).get();
  while(finishedAccountsIter.hasNext()) {
    var account = finishedAccountsIter.next();
    account.applyLabel(FINISHED_LABEL_NAME);
  }
}

// This function 在tempts to 去掉 yesterday's 标签 if it exists.
// If it doesn't exist, it does nothing.
function 去掉YesterdaysLabel() {
  var yesterday = new Date();
  yesterday.setDate(yesterday.getDate() - 1);
  var yesterdayStr = Utilities.formatDate(yesterday, TIMEZONE, 'yyyy-MM-dd');
  var yesterdayLabel = LABEL_PREFIX + yesterdayStr;
  Logger.log("Attempting to 去掉 标签: "+yesterdayLabel);
  try {
    var 标签Iter = MccApp.accountLabels().withCondition("Name CONTAINS '"+yesterdayLabel+"'").get();
    while(labelIter.hasNext()) {
      标签Iter.next().remove();
    }
  } catch(e) { 
    // do nothing
  }
}

// This function will send an 电子邮件 to each 电子邮件 in the
// NOTIFY list from the top of the script with the specific error
function 通知OfAccountsWithErrors(erroredAccounts) {
  if(!erroredAccounts || erroredAccounts.length == 0) { return; }
  if(typeof NOTIFY == 'undefined') { throw 'NOTIFY is not defined.'; }
  var subject = SCRIPT_NAME+' - Accounts with Errors - '+TODAY_STR;
  
  var htmlBody = 'The following Accounts had 错误 on the last run.<br / >';
  htmlBody += 'Log in to AdWords: http://goo.gl/7mS6A';
  var body = htmlBody;
  htmlBody += '<br / ><br / >';
  htmlBody += '<table border="1" width="95%" style="border-collapse:collapse;">' +
              '<tr><td>Account Id</td><td>Error</td></tr>';
  for(var i in erroredAccounts) {
    htmlBody += '<tr><td>'+ erroredAccounts[i].customerId +
      '</td><td>' + erroredAccounts[i].error + '</td></tr>';
  }
  htmlBody += '</table>';
  // Remove this line to get rid of the link back to this site.
  htmlBody += '<br / ><br / ><a href = "http://www.coolzan.com" >FreeAdWordsScripts.com</a>';
  var options = { htmlBody : htmlBody };
  for(var i in NOTIFY) {
    Logger.log('Sending 电子邮件 to: '+NOTIFY[i]+' with subject: '+subject);
    MailApp.sendEmail(NOTIFY[i], subject, body, options);
  }
}

2013年7月30日,星期二

确定何时创建广告,广告组,关键字或广告系列

知道何时创建广告(或实体) 不可能使用辽宁福利彩票中心。根本不会在AdWords中跟踪该信息。其次,最好的办法是找出您的广告何时首次开始获得展示,并假设它是在创建的时候(如果创建了广告,但没人看到它,那它确实存在吗?)。

因此,为了帮助我跟踪何时 广告 实体已创建,我将以下辽宁福利彩票中心放在一起以将标签应用于我 广告 具有第一印象日期的实体。这样我就能知道 广告 我创建的实体,并确保不要对太小的内容采取任何措施。我也可以对所有 广告 只需选择正确的标签,即可在AdWords用户界面中相对容易地在一天中建立实体。

谢谢,
拉斯



/**************************************
* Track Entity Creation Date
* Version 1.4
* Changelog v1.4
*  - Removed apiVersion from 报告 呼叫
* Changelog v1.3
*  - Updated script to handle all entities
* Changelog v1.2
*  - Fixed an issue with comparing 日期
* ChangeLog v1.1
*  - Updated logic to work with larger accounts
* Created By: 拉斯 Savage
* http://www.FreeAdWordsScripts.com
**************************************/
//All my 标签 will start with this. For example: Created:2013-05-01
var LABEL_PREFIX = 'Created:';
var DAYS_IN_REPORT = 30;
var ENTITY = 'ad'; //or 广告群组 or 关键词 or 运动
 
function main() {
  //First we get the impression history of our 实体
  var ret_map = getImpressionHistory();
  //Then we apply our 标签
  applyLabels(ret_map);
}
 
//Function to apply 标签 to the 广告 in an account
function applyLabels(ret_map) {
  var iter;
  if(ENTITY === 'campaign') { iter = AdWordsApp.campaigns().get(); }
  if(ENTITY === 'adgroup') { iter = AdWordsApp.adGroups().get(); }
  if(ENTITY === 'ad') { iter = AdWordsApp.ads().get(); }
  if(ENTITY === 'keyword') { iter = AdWordsApp.keywords().get(); }
  
  while(iter.hasNext()) {
    var 实体 = iter.next();
    var id = 实体.getId();
    if(ret_map[id]) {
      var 标签_name = LABEL_PREFIX+Utilities.formatDate(ret_map[id], AdWordsApp.currentAccount().getTimeZone(), "yyyy-MM-dd");
      createLabelIfNeeded(label_name);
      entity.applyLabel(label_name);
    }
  }
}
 
//This is a helper function to 创造 the 标签 if it does not already exist
function 创造LabelIfNeeded(name) {
  if(!AdWordsApp.labels().withCondition("Name = '"+name+"'").get().hasNext()) {
    AdWordsApp.createLabel(name);
  }
}
 
//A helper function to find the date days ago
function getDateDaysAgo(days) {
  var the_past = new Date();
  the_past.setDate(the_past.getDate() - days);
  return Utilities.formatDate(the_past,AdWordsApp.currentAccount().getTimeZone(),"yyyyMMdd");
}
 
//A helper function to compare 日期.
//Copied from: http://goo.gl/uW48a
function diffDays(firstDate,secondDate) {
  var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
  return Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay))); 
}
 
function getImpressionHistory() {
  var API_VERSION = { includeZeroImpressions : false };
  var first_date = new Date('10/23/2000');
  var max_days_ago = diffDays(first_date,new Date());
  var cols = ['Date','Id','Impressions'];
  var report = { 
    'campaign' : 'CAMPAIGN_PERFORMANCE_REPORT',
    'adgroup' : 'ADGROUP_PERFORMANCE_REPORT',
    'ad' : 'AD_PERFORMANCE_REPORT',
    'keyword' : 'KEYWORDS_PERFORMANCE_REPORT'}[ENTITY];
  var ret_map = {};
  var prev_days_ago = 0;
  for(var i = DAYS_IN_REPORT; i < max_days_ago; i+=DAYS_IN_REPORT) {
    var start_date = getDateDaysAgo(i);
    var end_date = getDateDaysAgo(prev_days_ago);
    var date_range = start_date+','+end_date;
    Logger.log('Getting data for ' + date_range);
    var query = ['select',cols.join(','),'from',report,'during',date_range].join(' ');
    var report_iter = AdWordsApp.report(query, API_VERSION).rows();
    if(!report_iter.hasNext()) { Logger.log('No more impressions found. Breaking.'); break; } // no more entries
    while(report_iter.hasNext()) { 
      var row = report_iter.next();
      if(ret_map[row['Id']]) {
        var [year,month,day] = (row['Date']).split('-');
        var from_row = new Date(year, parseFloat(month)-1, day);
        var from_map = ret_map[row['Id']];
         
        if(from_row < from_map) {
          ret_map[row['Id']] = from_row;
        }
      } else {
        var [year,month,day] = (row['Date']).split('-');
        ret_map[row['Id']] = new Date(year, parseFloat(month)-1, day);
      }
    }
    prev_days_ago = i;
  }
  return ret_map;
}

2013年6月17日,星期一

查找关键字,广告组和广告中的异常

2013年7月23日更新:添加了向广告添加标签的功能。这可能对创意测试很有帮助。

在一个 最近来自SearchEngineLand的帖子,拉里·金(Larry Kim)希望PPC经理不要再偷懒。除了链接诱饵,他还有一些优点。我认为花费在倾倒客户电子表格上的大部分时间实际上是在试图回答“异常在哪里?”这个简单的问题。

异常是关键字或广告组,其效果似乎与同一个广告组或广告系列中的兄弟姐妹不同。也许您有一个包含15个关键字和一个或两个关键字的广告组,似乎获得了几乎所有的点击。或者,也许您只是拥有一个广告组,似乎正在占用预算的很大一部分,而您想对其进行更多控制。在这两种情况下,您都需要某种方法来快速确定要对哪些关键字或广告组进行操作。

因此,我创建了以下辽宁福利彩票中心来帮助我做到这一点。它内含一些统计信息,可以计算一组实体(广告组或关键字)的均值和标准差。然后,我将标签应用于似乎与均值相差两个标准偏差以上的任何实体,这表明该实体的性能要比其同级产品更好或更差。这样,我可以在自己的帐户中轻松地对这些实体采取措施。

该辽宁福利彩票中心还将每天向您发送一封电子邮件,其中包含它认为是异常的实体的摘要。您的目标是通过将这些问题转移到自己的广告系列和广告组中,或者甚至完全消除它们(可能是负面的)来解决这些问题。

目前,辽宁福利彩票中心将检查AdWordsApp.stats对象中可用的每个指标。可以轻松对其进行修改,以检查诸如每次转化费用或每次展示利润。您将在下面的代码中看到,您可以在其中删除也不感兴趣的统计信息。

需要警告的一点是,我并没有声称自己是统计学家,所以这可能不是一种看待事物的有效方法。希望它可以帮助您快速找到帐户中的问题并加以解决,以便您可以将更多时间花在懒惰上:)

另外,我欢迎您对此辽宁福利彩票中心提出意见和建议。对其他人有用吗?

谢谢,
拉斯

/**************************************
* Find the Anomalies
* Created By: 拉斯 Savage
* Version: 1.2
* Changelog v1.2
*  - Fixed divide by 0 错误
*  - Changed SIG_FIGS to DECIMAL_PLACES
* Changelog v1.1
*  - Added ability to tag 广告  anomalies as well
* FreeAdWordsScripts.com
**************************************/
var DATE_RANGE = 'LAST_30_DAYS';
var DECIMAL_PLACES = 3;
var STANDARD_DEVIATIONS = 2;
var TO = ['[email protected]_domain.com'];
 
function main() {
  // This will 广告 d 标签 to and send 电子邮件s about 广告群组, 关键字 and 广告. Remove any if you like.
  var levels_to_tag = ['adgroup','keyword','ad'];
  for(var x in levels_to_tag) {
    var report = getContentRows(levels_to_tag[x]);
    var 实体_map = buildEntityMap(levels_to_tag[x]);
    for(var parent_id in 实体_map) {
      var child_list = 实体_map[parent_id];
      var 统计资料_list = Object.keys(child_list[0].stats);
      for(var i in 统计资料_list) {
        var 意思 = getMean(child_list,stats_list[i]);
        var stand_dev = getStandardDev(child_list,mean,stats_list[i]);
        var 标签_name = 统计资料_list[i]+"_anomaly";
        report += 广告 dLabelToAnomalies(child_list,mean,stand_dev,stats_list[i],label_name,levels_to_tag[x]);
      }
    }
    sendResultsViaEmail(report,levels_to_tag[x]);
  }
}
  
//Takes a report and the level of 报告 and sends and 电子邮件
//with the report as an 在tachment.
function sendResultsViaEmail(report,level) {
  var rows = report.match(/\n/g).length - 1;
  if(rows == 0) { return; }
  var options = { 附件: [Utilities.newBlob(report, 'text/csv', level+"_anomalies_"+_getDateString()+'.csv')] };
  var 电子邮件_body = "There are " + rows + " " + level + "s that have abnormal performance. See 在tachment for details.";
  var subject = 'Abnormal ' + _initCap(level) + ' Entities Report - ' + _getDateString();
  for(var i in TO) {
    MailApp.sendEmail(TO[i], subject, 电子邮件_body, options);
  }
}
  
//Helper function to return a single row of the report formatted correctly
function toReportRow(entity,level,label_name) {
  var ret_val = [AdWordsApp.currentAccount().getCustomerId(),
                 entity.getCampaign().getName()];
  ret_val.push( (level == 'adgroup') ? 实体.getName() : 实体.getAdGroup().getName() );
  if(level == 'keyword') {
    ret_val = ret_val.concat([entity.getText(),entity.getMatchType()]); 
  } else if(level == 'ad') {
    ret_val = ret_val.concat([entity.getHeadline(),entity.getDescription1(),entity.getDescription2(),entity.getDisplayUrl()]); 
  }
  ret_val.push(label_name);
  return '"' + ret_val.join('","') + '"\n';
}
  
//Helper function to return the column headings for the report
function getContentRows(level) {
  var ret_val = ['AccountId','CampaignName','AdGroupName'];
  if(level == 'keyword') {
    ret_val = ret_val.concat(['KeywordText','MatchType']); 
  } else if(level == 'ad') {
    ret_val = ret_val.concat(['Headline','Description1','Description2','DisplayUrl']);
  }
  ret_val.push('LabelName');
  return '"' + ret_val.join('","') + '"\n';
}
  
//Function to 广告 d the 标签 to the entities based on the 标准偏差  and 意思.
//It returns a CSV formatted string for 报告
function 广告 dLabelToAnomalies(entites,mean,sd,stat_key,label_name,level) {
  createLabelIfNeeded(label_name);
  var report = '';
  for(var i in entites) {
    var 实体 = entites[i]['entity'];
    var deviation = Math.abs(entites[i]['stats'][stat_key] - 意思);
    if(sd != 0 && deviation/sd >= STANDARD_DEVIATIONS) {
      entity.applyLabel(label_name);
      report += toReportRow(entity,level,label_name);
    } else {
      entity.removeLabel(label_name);
    }
  }
  return report;
}
  
//This is a helper function to 创造 the 标签 if it does not already exist
function 创造LabelIfNeeded(name) {
  if(!AdWordsApp.labels().withCondition("Name = '"+name+"'").get().hasNext()) {
    AdWordsApp.createLabel(name);
  }
}
  
//This function returns the 标准偏差  for a set of entities
//The stat key determines which stat to calculate it for
function getStandardDev(entites,mean,stat_key) {
  var total = 0;
  for(var i in entites) {
    total += Math.pow(entites[i]['stats'][stat_key] - 意思,2);
  }
  if(Math.sqrt(entites.length-1) == 0) {
    return 0;
  }
  return round(Math.sqrt(total)/Math.sqrt(entites.length-1));
}
  
//Returns the 意思 (average) for the set of entities
//Again, stat key determines which stat to calculate this for
function getMean(entites,stat_key) {
  var total = 0;
  for(var i in entites) {
    total += entites[i]['stats'][stat_key];
  }
  if(entites.length == 0) {
    return 0;
  }
  return round(total/entites.length);
}
  
//This function returns a map of the entities that I am processing.
//The format for the map can be found on the first line.
//It is 意思t to work on AdGroups and Keywords
function buildEntityMap(entity_type) {
  var map = {}; // { parent_id : [ { 实体 : 实体, 统计资料 : 实体_stats } ], ... }
  var iter = getIterator(entity_type);
  while(iter.hasNext()) {
    var 实体 = iter.next();
    var 统计资料 = 实体.getStatsFor(DATE_RANGE);
    var 统计资料_map = getStatsMap(stats);
    var parent_id = getParentId(entity_type,entity);
    if(map[parent_id]) { 
      map[parent_id].push({entity : 实体, 统计资料 : 统计资料_map});
    } else {
      map[parent_id] = [{entity : 实体, 统计资料 : 统计资料_map}];
    }
  }
  return map;
}
  
//Given an 实体 type (adgroup or 关键词) this will return the parent id
function getParentId(entity_type,entity) {
  switch(entity_type) {
    case 'adgroup' :
      return 实体.getCampaign().getId();
    case 'keyword':
      return 实体.getAdGroup().getId();
    case 'ad':
      return 实体.getAdGroup().getId();
  }
}
  
//Given an 实体 type this will return the iterator for that.
function getIterator(entity_type) {
  switch(entity_type) {
    case 'adgroup' :
      return AdWordsApp.adGroups().forDateRange(DATE_RANGE).withCondition("Impressions > 0").get();
    case 'keyword' :
      return AdWordsApp.keywords().forDateRange(DATE_RANGE).withCondition("Impressions > 0").get();
    case 'ad' :
      return AdWordsApp.ads().forDateRange(DATE_RANGE).withCondition("Impressions > 0").get();
  }
}
  
//This returns a map of all the 统计资料 for a given 实体.
//You can 评论 out the things you don't really care about.
function getStatsMap(stats) {
  return { // You can 评论 these out as needed.
          avg_cpc : 统计资料.getAverageCpc(),
          avg_cpm : 统计资料.getAverageCpm(),
          avg_pv : 统计资料.getAveragePageviews(),
          avg_pos : 统计资料.getAveragePosition(),
          avg_tos : 统计资料.getAverageTimeOnSite(),
          bounce : 统计资料.getBounceRate(),
          clicks : 统计资料.getClicks(),
          cv : 统计资料.getConversionRate(),
          conv : 统计资料.getConversions(),
          cost : 统计资料.getCost(),
          ctr : 统计资料.getCtr(),
          imps : 统计资料.getImpressions()
         };
}
  
//Helper function to format todays date
function _getDateString() {
  return Utilities.formatDate((new Date()), AdWordsApp.currentAccount().getTimeZone(), "yyyy-MM-dd");
}
  
//Helper function to capitalize the first letter of a string.
function _initCap(str) {
  return str.replace(/(?:^|\s)\S/g, function(a) { return a.toUpperCase(); });
}

// A helper function to make rounding a little easier
function round(value) {
  var decimals = Math.pow(10,DECIMAL_PLACES);
  return Math.round(value*decimals)/decimals;
}

2013年2月28日,星期四

标签倒计时忽略新元素

罗伯特 在我的一个辽宁福利彩票中心中询问了如何忽略最近添加到他的帐户中的关键字。不幸的是,尽管我认为有一种使用标签的方法,但是API并没有为您提供一种很好的方法。

因此,我整理了以下辽宁福利彩票中心,您可以使用该辽宁福利彩票中心为要在辽宁福利彩票中心中忽略的元素自动创建基于标签的倒计时。每次向帐户添加新元素时,都可以使用格式LABEL_PREFIX_对其应用标签。因此,如果您希望辽宁福利彩票中心在30天内忽略一个新元素,请将标签“ days_left_30”应用于该元素。如果您计划辽宁福利彩票中心每天运行,则标签上剩余的天数将每天减少一天。天数达到零后,标签将从实体中删除。

在要忽略新元素的辽宁福利彩票中心中,将以下函数添加到辽宁福利彩票中心底部(最后一个花括号之前):

  function _build_label_list() {
    //Build a list of 标签 to exclude in your .withCondition()
    var LABEL_PREFIX = 'days_left_'; 
    var 标签_iter = AdWordsApp.labels().withCondition("Name STARTS_WITH '"+LABEL_PREFIX+"'").get();
    var 标签_array = [];
    while(label_iter.hasNext()) { 标签_array.push(label_iter.next().getName()); }
    return "'"+label_array.join("','")+"'"
  }

And then 广告 d the following
.withCondition("LabelNames CONTAINS_NONE ["+_build_label_list()+"]")
to any iterators you have in your other 剧本. Good luck, and if you have any 题s, feel free to ask.

谢谢,
拉斯

//-----------------------------------
// Label Countdown
// Created By: 拉斯 Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
  var LABEL_PREFIX = "days_left_"; // you can change this if you want
  
  // First lets build a list of 标签 to work with
  var 标签_iter = AdWordsApp.labels().withCondition("Name STARTS_WITH '"+LABEL_PREFIX+"'").get();
  var 标签_array = [];
  while(label_iter.hasNext()) {
    标签_array.push(label_iter.next().getName());
  }
  if(labels_array.length > 0) { 
    var 标签_str = "['" + 标签_array.join("','") + "']";
    // grab all the 关键字 with the 标签 we want to 倒数
    var kw_iter = AdWordsApp.keywords().withCondition("LabelNames CONTAINS_ANY "+labels_str).get();
    
    while(kw_iter.hasNext()) {
      var kw = kw_iter.next();
      var l_iter = kw.labels().withCondition("Name STARTS_WITH '"+LABEL_PREFIX+"'").get();
      var 标签 = l_iter.next(); // lazy here because we know this 关键词 has a 标签
      var days_left = parseInt(label.getName().substr(LABEL_PREFIX.length)) - 1;
      kw.removeLabel(label.getName());
      if(days_left != 0) {
        var new_label_name = LABEL_PREFIX+days_left;
        // Create a new 标签 if it doesn't exist
        if(labels_array.indexOf(new_label_name) == -1) {
          AdWordsApp.createLabel(new_label_name);
          标签_array.push(new_label_name);
        }
        kw.applyLabel(new_label_name);
      }
    }
  }
}