显示带有标签的帖子 帐户清理. 显示所有帖子
显示带有标签的帖子 帐户清理. 显示所有帖子

2013年4月10日,星期三

报告帐户中的破损网址

注意:如果您正在寻找此脚本的版本以在MCC级别上运行,请签出 使用MCC级别脚本监视断开的链接.

更新时间:2013-05-20:基于读者的评论,该脚本现在仅检查活动的广告系列和广告组,并且仅检查每个网址一次。

更新时间:2013-04-28:基于读者的评论,我对该脚本进行了一些更新,包括将响应代码添加到电子邮件中并将结果格式化为附件。

它发生在我们最好的人身上。有时,我们会删除网站上的页面或更新链接,而忘记对我们的SEM帐户进行相应的更改。因此,今晚我整理了一个快速脚本来遍历您的所有广告和关键字,并创建一个包含以下内容的电子邮件报告: 找不到404 或一个 500服务器错误 响应码。您可以通过在脚本开头将它们添加到BAD_CODES数组中来轻松添加更多错误代码以进行检查。

谢谢,
拉斯

/****************************
* Find Broken Urls In Your Account
* Version 1.1
* ChangeLog v1.1
*  - Updated to only see Text Ads
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
****************************/
function main() {
  // You can 广告 d more if you want: http://goo.gl/VhIX
  var BAD_CODES = [404,500];
  var TO = ['[email protected]'/*,'[email protected]'*/];
  var SUBJECT = 'Broken Url Report - ' + _getDateString();
  var HTTP_OPTIONS = {
    muteHttpExceptions:true
  };
   
  //Let's look 在 广告 and 关键字 for 网址
  var iters = [
    //For Ad Level Urls
    AdWordsApp.ads()
      .withCondition("Status = 'ENABLED'")
      .withCondition("AdGroupStatus = 'ENABLED'")
      .withCondition("CampaignStatus = 'ENABLED'")
      .withCondition("Type = 'TEXT_AD'")
      .get(),
    //For Keyword Level Urls
    AdWordsApp.keywords()
      .withCondition("Status = 'ENABLED'")
      .withCondition("DestinationUrl != ''")
      .withCondition("AdGroupStatus = 'ENABLED'")
      .withCondition("CampaignStatus = 'ENABLED'")
      .get()
    ];
  
  var already_checked = {}; 
  var bad_entities = [];
  for(var x in iters) {
    var iter = iters[x];
    while(iter.hasNext()) {
      var 实体 = iter.next();
      if(entity.getDestinationUrl() == null) { continue; }
      var url = 实体.getDestinationUrl();
      if(url.indexOf('{') >= 0) {
        //Let's 去掉 the value track parameters
        url = url.replace(/\{[0-9a-zA-Z]+\}/g,'');
      }
      if(already_checked[url]) { continue; }
      var response_code;
      try {
        Logger.log("Testing url: "+url);
        response_code = UrlFetchApp.fetch(url, HTTP_OPTIONS).getResponseCode();
      } catch(e) {
        //Something is wrong here, we should know about it.
        bad_entities.push({e : 实体, code : -1});
      }
      if(BAD_CODES.indexOf(response_code) >= 0) {
        //This 实体 has an issue.  Save it for later. 
        bad_entities.push({e : 实体, code : response_code});
      }
      already_checked[url] = true;
    }
  }
  var column_names = ['Type','CampaignName','AdGroupName','Id','Headline/KeywordText','ResponseCode','DestUrl'];
  var 在tachment = column_names.join(",")+"\n";
  for(var i in bad_entities) {
    在tachment += _formatResults(bad_entities[i],",");
  }
  if(bad_entities.length > 0) {
    var options = { 附件: [Utilities.newBlob(attachment, 'text/csv', 'bad_urls_'+_getDateString()+'.csv')] };
    var 电子邮件_body = "There are " + bad_entities.length + " 网址 that are 破碎. See 在tachment for details.";
     
    for(var i in TO) {
      MailApp.sendEmail(TO[i], SUBJECT, 电子邮件_body, options);
    }
  }  
}
 
//Formats a row of results separated by SEP
function _formatResults(entity,SEP) {
  var e = 实体.e;
  if(typeof(e['getHeadline']) != "undefined") {
    //this is an 广告  实体
    return ["Ad",
            e.getCampaign().getName(),
            e.getAdGroup().getName(),
            e.getId(),
            e.getHeadline(),
            实体.code,
            e.getDestinationUrl()
           ].join(SEP)+"\n";
  } else {
    // and this is a 关键词
    return ["Keyword",
            e.getCampaign().getName(),
            e.getAdGroup().getName(),
            e.getId(),
            e.getText(),
            实体.code,
            e.getDestinationUrl()
           ].join(SEP)+"\n";
  }
}
 
//Helper function to format todays date
function _getDateString() {
  return Utilities.formatDate((new Date()), AdWordsApp.currentAccount().getTimeZone(), "yyyy-MM-dd");
}

2013年3月4日,星期一

修复广告中的大写错误

营销人员在拥有从Feed中自动构建广告素材的系统时面临的问题之一是质量控制。最近,我遇到了一个问题,我制作了大约1000个新广告,城市名称全部为大写。 Google当然不那么喜欢,我不喜欢必须手动更新1,000个广告的想法,因此我整理了以下脚本。

该脚本会在您的帐户中运行所有被拒登的广告,并尝试在ALL CAPS中查找带有单词的广告。我不确定Google的上限是多少,但是在下面的脚本中,它将查找连续三个或三个以上大写字母的任何内容。然后替换它们,创建一个新广告,如果成功,则删除旧广告。

我在确定广告被拒登的原因时遇到了麻烦。 API中尚不提供此功能,但具有 被要求。另一个问题是,有时您创建的新广告会失败,这将导致您删除旧广告而不创建新广告。为了解决这一问题,我在制作新广告之前和之后对广告组中的广告进行了计数,以确保我的广告已创建。再说一次 发布功能请求 在adwords脚本论坛中。

谢谢,
拉斯

//-----------------------------------
// Fix Ads with EXCESSIVE CAPITALIZATION
// Created By: 拉斯 Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
  var find_caps = /[A-Z]{3,}/g;
  var SEP = '[email protected]~~'; // this needs to be something you would never put in your 广告.
  var 广告 _iter = AdWordsApp.ads().withCondition("ApprovalStatus = 'DISAPPROVED'").get();
  
  while(ad_iter.hasNext()) {
    var 广告  = 广告 _iter.next();
    var old_ad_cnt = get_ad_count(ad.getAdGroup());
    var old_ad_str = [ad.getHeadline(),ad.getDescription1(),ad.getDescription2(),ad.getDisplayUrl()].join(SEP);
    var new_ad_str = old_ad_str;
    Logger.log("Before:"+old_ad_str);
    var m = "";
    while((m = find_caps.exec(new_ad_str)) != null) {
      new_ad_str = replace_all(new_ad_str,m[0],init_cap(m[0]),false);
    }
    Logger.log("After:"+new_ad_str);
    if(old_ad_str != new_ad_str) {
      var [new_headline,new_desc1,new_desc2,new_disp_url] = new_ad_str.split(SEP);
      广告 .getAdGroup().createTextAd(new_headline, new_desc1, new_desc2, new_disp_url, 广告 .getDestinationUrl());
      var new_ad_cnt = get_ad_count(ad.getAdGroup());
      if(new_ad_cnt == (old_ad_cnt+1)) {
        广告 .remove();
      }
    } else {
      Logger.log("Skipping because no changes were made."); 
    }
  }
  
  function init_cap(s) {
    return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
  }
  
  // This function was 广告 apted from: http://dumpsite.com/forum/index.php?topic=4.msg8#msg8 
  function replace_all(original,str1, str2, ignore) {
    return original.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
  }
  
  function get_ad_count(ad_group) {
    var 广告 _iter = 广告 _group.ads().get();
    var new_ad_cnt = 0;
    while(ad_iter.hasNext()) {
      广告 _iter.next();
      new_ad_cnt++;
    }
    return new_ad_cnt;
  }
}

2012年12月11日,星期二

自动将ValueTrack参数添加到所有目标网址

今天,我们有了一个脚本,可以帮助确保您所有的关键字都已标记有适当的 价值追踪 parameters.  您可以使用它来确保将所有跟踪参数正确地添加到URL中。

您可以将自己的查询字符串参数添加到脚本顶部的映射中。 例如,如果帐户中的所有关键字都需要在其目标网址中包含参数“ channel = sem”,则可以将其添加到文件顶部的URL_PARAMS_TO_ADD映射中,并将其添加到所有网址中。

另外,我更新了脚本,允许您将帐户中想要的任何值添加到url中。如果愿意,请参见将广告系列和广告组名称添加到网址的示例。

谢谢,
拉斯

/******************************************
* Auto Add 价值追踪 (and other) Params If Not There
* Created By: 拉斯 Savage
* Version 1.1
* ChangeLog v1.1
*  - Added the ability to 广告 d function 呼叫s into the parameters to 广告 d
* FreeAdWordsScripts.com
******************************************/
function main() {
   
  var URL_PARAMS_TO_ADD = { 
    "kw" : "{keyword}",
    "crid" : "{creative}",
    "mt" : "{matchtype}",
    "ntwk" : "{network}",
    "ap" : "{adposition}",
    "dv" : "{device}",
    "dvm" : "{devicemodel}",
    //"camp" : getCampaignName,  <----- This function is defined below
    //"ag" : getAdGroupName  <----- and so is this one
  };
   
  var kw_iter = AdWordsApp.keywords()
                  .withCondition("DestinationUrl != ''")
                  .get();
  
  while(kw_iter.hasNext()) {
    var kw = kw_iter.next();
    var destUrl = kw.getDestinationUrl();
    if(!destUrl || destUrl === '') { continue; }
    var toAppend = [];
    for(var key in URL_PARAMS_TO_ADD) {
      if(destUrl.indexOf(key) >= 0) { continue; }
      var value = URL_PARAMS_TO_ADD[key];
      
      //check to see if we should 呼叫 a function
      if(typeof(value) === 'function') {
        value = encodeURI(value(kw));
      }
      toAppend.push(key+"="+value);
    }
    if(destUrl.indexOf('?') >= 0) {
      kw.setDestinationUrl(destUrl + "&"+toAppend.join('&'));
    } else {
      kw.setDestinationUrl(destUrl + "?"+toAppend.join('&'));
    }
    Logger.log(kw.getDestinationUrl());
  }
}

// As long as the function 呼叫 is passed a kw object, you can insert
// whatever value you want into the url
function getCampaignName(kw) {
  return kw.getCampaign().getName();
}

function getAdGroupName(kw) {
  return kw.getAdGroup().getName();
}

2012年11月26日,星期一

新年广告更新

这是我先前有关以下内容之一的同伴 更新新年的关键字.  您可以轻松浏览所有广告,并使用以下脚本在新的一年中全部更新它们。 它还会暂停旧广告,以确保您与客户保持联系。 如果您的广告严重依赖过时的流量,则应安排在每年的1月1日投放。

谢谢,
拉斯

//-----------------------------------
// Update Ads for 2012
// Created By: 拉斯 Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
  var OLD_YEAR = "2011";
  var NEW_YEAR = "2012";
  //You probably shouldn't 更新 目标网址 unless you know what you are doing.
  var FIELDS_CONTAINING_YEAR = ["Headline","Description1",
                                "Description2","DisplayUrl"
                                /*,"DestinationUrl"*/
                               ];
  
  for(i in FIELDS_CONTAINING_YEAR) {
    var field_iter = AdWordsApp.ads()
        .withCondition(FIELDS_CONTAINING_YEAR[i] + " CONTAINS " + OLD_YEAR)
        .withCondition("Status = ENABLED")
        .get();
    
    _iterateThroughAds(field_iter);
  }

  //---------------
  // Private Helper Functions
  //---------------  
  function _iterateThroughAds(ad_iter) {
    while (ad_iter.hasNext()) {
      var 广告  = 广告 _iter.next();
      var ag = 广告 .getAdGroup();
      _createNewAdFromOldAd(ag,ad);
    }
  }
  
  function _createNewAdFromOldAd(adgroup, old_ad) {
    //get the 更新d 广告  texts replacing all the old years with the 新年s
    var new_headline = old_ad.getHeadline().replace(OLD_YEAR,NEW_YEAR);
    var new_desc1 = old_ad.getDescription1().replace(OLD_YEAR,NEW_YEAR);
    var new_desc2 = old_ad.getDescription2().replace(OLD_YEAR,NEW_YEAR);
    var new_display_url = old_ad.getDisplayUrl().replace(OLD_YEAR,NEW_YEAR);
    var new_dest_url = old_ad.getDestinationUrl();/*.replace(OLD_YEAR,NEW_YEAR);*/
    
    //now 创造 the new 广告  and 暂停 the old one.
    广告群组.createTextAd(new_headline,new_desc1,new_desc2,new_display_url,new_dest_url);
    old_ad.pause();
  }
}

2012年11月23日,星期五

自动暂停点击率低的广告

最近,布拉德(Brad)在 CertifiedKnowledge.com 发表了一些有关大规模测试的提示。 他提到的最常见的测试技术之一是制作大量广告,然后让Google为您优化轮播。 这种技术的问题在于失败者很少被删除。 好吧,使用下面的脚本,您可以在所有广告组中找到效果最差的广告并将其暂停(如果该广告组中至少有其他广告)。

谢谢,
拉斯


//-----------------------------------
// Pause Ads with Low CTR
// Created By: 拉斯 Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
  // Let's start by getting all of the 广告 Groups that are active
  var ag_iter = AdWordsApp.adGroups()
  .withCondition("Status = ENABLED")
  .get();

  // Then we will go through each one
  while (ag_iter.hasNext()) {
    var ag = ag_iter.next();
    var 广告 _iter = ag.ads()
      .withCondition("Status = ENABLED")
      .forDateRange("ALL_TIME")
      .orderBy("Ctr DESC")
      .get();
    var 广告 _array = new Array();
    while(ad_iter.hasNext()) {
      广告 _array.push(ad_iter.next());
    }
    if(ad_array.length > 1) {
      for(var i = 1; i < 广告 _array.length; i++) {
        广告 _array[i].pause(); //or .remove(); to 删除 them 
      }
    }
  }
}

2012年11月22日,星期四

删除帐户中的所有拒登广告

同样,另一个简单的脚本仅关注帐户维护。随着时间的流逝,大型帐户可能会使用可能被拒登的广告来构建数千个广告组。有时,删除这些内容然后缓慢地构建和部署新的广告素材是很有意义的(稍后我们将提供脚本来构建新的广告素材)。希望这对您有用。

谢谢,
拉斯
//-----------------------------------
// Delete Ads That Are Disapproved
// Created By: 拉斯 Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
  // Let's start by getting all of the 广告  that are 被拒登
  var 广告 _iter = AdWordsApp.ads()
  .withCondition("ApprovalStatus != APPROVED")
  .get();

  // Then we will go through each one
  while (ad_iter.hasNext()) {
    var 广告  = 广告 _iter.next();
    // now we 删除 the 广告 
    Logger.log("Deleteing 广告 : " + 广告 .getHeadline());
    广告 .remove();
  }
}

2012年11月21日,星期三

暂停没有有效关键字的广告组

这是一个快速脚本,可以暂停所有没有有效关键字的广告组。不确定这是否超级有用,但是对于大型帐户,它可能有助于确定您可以删除的广告组。

谢谢,
拉斯

/*********************************************
* 暂停没有有效关键字的广告组
* Version 1.1
* Changelog v1.1
*   - Updated for speed and 广告 ded 评论s 
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
**********************************************/
function main() {
  // Let's start by getting all of the active AdGroups
  var agIter = AdWordsApp.adGroups()
    .withCondition('CampaignStatus = ENABLED')
    .withCondition('Status = ENABLED')
    .get();
 
  // It is faster to store them and process them all 在 once later
  var toPause = [];
  // Then we will go through each one
  while(agIter.hasNext()) {
    var ag = agIter.next();
    //get all the 关键字 that are enabled
    var kwIter = ag.keywords()
      .withCondition("Status = ENABLED")
      .get();
    
    //If .hasNext() is true, there is 在 least 1 kw in the AdGroup
    var hasKw = kwIter.hasNext(); 
    if(!hasKw) {
      toPause.push(ag);
    }
  }
  
  // Now we process them all 在 once to take 广告 vantage of batch processing
  for(var i in toPause) {
    toPause[i].pause();
  }
}

2012年11月20日,星期二

更新假期的关键字

另一天, RKGBlog 刊登了一篇很棒的文章,介绍了如何在假期期间更新关键字。其中提到的一项是将关键字中的所有年份更新为当前年份。这是一个小脚本,可以找到上一个年份的所有关键字,并在与当前年份相同的广告组中创建新的关键字。

谢谢,
拉斯
/*********************************************
* Update Keywords for the New Year
* Version 1.1
* Changelog v1.1
*   - Updated for speed and 广告 ded 评论s 
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
**********************************************/
function main() {
  var sameDayLastYear = new Date();
  sameDayLastYear.setYear(sameDayLastYear.getYear()-1);
  var oldYearStr = sameDayLastYear.getYear().toString();
  var newYearStr = new Date().getYear().toString();
  
  Logger.log('Updating 关键字 with old year: '+oldYearStr+' to 新年: '+newYearStr);
  
  // Let's start by getting all of the 关键字
  var kwIter = AdWordsApp.keywords()
    .withCondition("Text CONTAINS " + oldYearStr)
    .withCondition("Status = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .withCondition("CampaignStatus = ENABLED")
    .get();
 
  // It is always better to store and batch process afterwards
  var toPause = [];
  var toCreate = [];
  while (kwIter.hasNext()) {
    var kw = kwIter.next();
    var ag = kw.getAdGroup();
    var oldText = kw.getText();
    var newText = oldText.replace(oldYearStr,newYearStr);
    // Save the info so that we can 创造 them as a batch later
    toCreate.push({ ag: ag, text: newText, cpc:kw.getMaxCpc(), destUrl : kw.getDestinationUrl() });
    // Same with the ones we want to 暂停
    toPause.push(kw) 
  }
  // Now we 创造 the new 关键字 all 在 once
  for(var i in toCreate) {
    var elem = toCreate[i];
    elem.ag.createKeyword(elem.text, elem.cpc, elem.destUrl);
  }
  // And 暂停 the old ones all 在 once
  for(var i in toPause) {
    toPause[i].pause();
    //or toPause[i].remove(); to 删除 the old 关键词
  }
}

2012年11月19日,星期一

暂停所有没有印象的关键字

让我们从一个非常简单的脚本开始。此关键字将找到您帐户中从未留下任何印象的所有关键字,并暂停(或删除,如果您看到下面的评论)该关键字,以免对质量得分造成负面影响。 根据Google的说法,帐户中存在的内容和停滞时间越长,对质量得分的影响就越大。 正如读者指出的那样, 第四个子弹在这里 似乎与这一说法相矛盾。这是一个很棒的脚本,可以每隔几个月安排一次,以确保您减少了帐户中的所有净额。

谢谢,
拉斯
/*********************************************
* Pause Keywords With No Impressions All Time
* Version 1.1
* Changelog v1.1
*   - Updated for speed and 广告 ded 评论s 
* Created By: 拉斯 Savage
* FreeAdWordsScripts.com
**********************************************/
var TO_NOTIFY = "[email protected]";
function main() {
  // Let's start by getting all of the 关键字 with 没有印象
  var kwIter = AdWordsApp.keywords()
    .withCondition("Impressions = 0") // could be "Clicks = 0" also
    .forDateRange("ALL_TIME") // could use a specific date range like "20130101","20131231"
    .withCondition("Status = ENABLED")
    .withCondition("CampaignStatus = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .get();
 
  // It is much faster to store all the 关键字 you want to process
  // and then make the changes all 在 once. This takes 广告 vantage
  // of the batch processing behind the scenes.
  var toPause = [];
  while (kwIter.hasNext()) {
    var kw = kwIter.next();
    toPause.push(kw);
    // This is to make sure you see things during the preview
    // When you run it for real, you can 去掉 this clause to
    // increase speed.
    if(AdWordsApp.getExecutionInfo().isPreview() &&
       AdWordsApp.getExecutionInfo().getRemainingTime() < 10) {
      break;
    }
  }
  
  // Now go through each one and 暂停 them.
  for(var i in toPause) {
    toPause[i].pause();
    //Or you could use toPause[i].remove(); to 删除 the 关键词 altogether
  }
  
  // Sent an 电子邮件 to 通知 you of the changes
  MailApp.sendEmail(TO_NOTIFY, 
                    "AdWords Script Paused "+toPause.length+" Keywords.", 
                    "Your AdWords Script 暂停d "+toPause.length+" 关键字.");
}