Cannot retrieve the next object: iterator has reached the end. (line 79)
Am I doing something wrong to modify the campaign label to only check labels that have "ooss" and ignoring the other?
For reference, here is line 79:
var label = AdWordsApp.labels().withCondition("Name = '"+CAMPAIGN_LABEL+"'").get().next();
Thanks for the help on this! Here is the script I am trying to use:
/************************************
* Item Out Of Stock Checker
* Version 1.1
* ChangeLog v1.1 - Filtered out deleted Campaigns and AdGroups
* Created By: Russ Savage
* FreeAdWordsScripts.com
***********************************/
var URL_LEVEL = 'Ad'; // or Keyword
var ONLY_ACTIVE = true; // set to false for all ads or keywords
var CAMPAIGN_LABEL = 'ooss'; // set this if you want to only check campaigns with this label
var STRIP_QUERY_STRING = true; // set this to false if the stuff that comes after the question mark is important
var WRAPPED_URLS = true; // set this to true if you use a 3rd party like Marin or Kenshoo for managing you account
// This is the specific text to search for
// on the page that indicates the item
// is out of stock.
var OUT_OF_STOCK_TEXT = 'This product is currently not available';
function main() {
var alreadyCheckedUrls = {};
var iter = buildSelector().get();
while(iter.hasNext()) {
var entity = iter.next();
var url = cleanUrl(entity.urls().getFinalUrl());
if(alreadyCheckedUrls[url]) {
if(alreadyCheckedUrls[url] === 'out of stock') {
entity.pause();
} else {
entity.enable();
}
} else {
var htmlCode;
try {
htmlCode = UrlFetchApp.fetch(url).getContentText();
} catch(e) {
Logger.log('There was an issue checking:'+url+', Skipping.');
continue;
}
if(htmlCode.indexOf(OUT_OF_STOCK_TEXT) >= 0) {
alreadyCheckedUrls[url] = 'out of stock';
entity.pause();
} else {
alreadyCheckedUrls[url] = 'in stock';
entity.enable();
}
}
Logger.log('Url: '+url+' is '+alreadyCheckedUrls[url]);
}
}
function cleanUrl(url) {
if(WRAPPED_URLS) {
url = url.substr(url.lastIndexOf('http'));
if(decodeURIComponent(url) !== url) {
url = decodeURIComponent(url);
}
}
if(STRIP_QUERY_STRING) {
if(url.indexOf('?')>=0) {
url = url.split('?')[0];
}
}
if(url.indexOf('{') >= 0) {
//Let's remove the value track parameters
url = url.replace(/\{[0-9a-zA-Z]+\}/g,'');
}
return url;
}
function buildSelector() {
var selector = (URL_LEVEL === 'Ad') ? AdWordsApp.ads() : AdWordsApp.keywords();
selector = selector.withCondition('CampaignStatus != DELETED').withCondition('AdGroupStatus != DELETED');
if(ONLY_ACTIVE) {
selector = selector.withCondition('CampaignStatus = ENABLED').withCondition('Status = ENABLED');
if(URL_LEVEL !== 'Ad') {
selector = selector.withCondition('AdGroupStatus = ENABLED');
}
}
if(CAMPAIGN_LABEL) {
var label = AdWordsApp.labels().withCondition("Name = '"+CAMPAIGN_LABEL+"'").get().next();
var campIter = label.campaigns().get();
var campaignNames = [];
while(campIter.hasNext()) {
campaignNames.push(campIter.next().getName());
}
selector = selector.withCondition("CampaignName IN ['"+campaignNames.join("','")+"']");
}
return selector;
}
var ONLY_ACTIVE = true; // set to false for all ads or keywordswithCondition("LabelNames..." type. Would you know a way to set up a variable to the script to exclude those ad level labels that = "forced pause" for this to not activate the wrong ads? Again I appreaciate all the help Tyler.Such as something like: var OUT_OF_STOCK_TEXT = 'This product is currently not available' OR 'did not return an exact match'
var CAMPAIGN_LABEL = 'forced pause'; // set this if you want to only check campaigns with this label
var OUT_OF_STOCK_TEXT = ['Text1', 'Text2'];
forced pause'
Another thought I had, it would be nice to add a label to the text ads that are paused because the LP was recognized as Out of Stock. This way we can create documentation and reports based on the label. So if we are able to create a script that recognizes text ad level labels, then it would be nice to also assign a text ad level label "OOS" when a text ad is paused. This is not necessary, but I think it would also remove a lot of potential confusion if something was forcibly paused or the script paused it. To be clear, I would only need to set up a variable to excluse text ads with the label "forced pause" from being included in this script. The script would include this 'OOS' label by default as it does not match 'forced pause'function buildSelector() {
var selector = (URL_LEVEL === 'Ad') ? AdWordsApp.ads() : AdWordsApp.keywords();
selector = selector.withCondition('CampaignStatus != DELETED').withCondition('AdGroupStatus != DELETED');
if(ONLY_ACTIVE) {
selector = selector.withCondition('CampaignStatus = ENABLED').withCondition('Status = ENABLED');
if(URL_LEVEL !== 'Ad') {
selector = selector.withCondition('AdGroupStatus = ENABLED').withCondition("LabelNames CONTAINS_ANY ['forced pause', 'label 2 if necessary']");
}
}