How to use multiple date ranges for different metrics in a single keyword selector?

91 views
Skip to first unread message

Doug

unread,
Mar 25, 2016, 2:59:35 PM3/25/16
to AdWords Scripts Forum
Is there a way to get all keywords with ConvertedClicks=0 ALL_TIME and AveragePosition > 3 YESTERDAY?

Basically I want to use multiple forDateRange clauses in a single keyword selector like this:

  var keywordsToLower = AdWordsApp.keywords()  

 .withCondition('AveragePosition < ' + (TARGET_AVERAGE_POSITION - TOLERANCE))
 .forDateRange('LAST_&_DAYS')

 .withCondition('Cost >= xxx')
 .forDateRange('LAST_30_DAYS)

 .withCondition('ConvertedClicks = 0')
 .forDateRange('ALL_TIME')

 .get();

How would I go about pulling keywords using different date ranges for different metrics such as the above?

Tyler Sidell (AdWords Scripts Team)

unread,
Mar 25, 2016, 4:48:43 PM3/25/16
to AdWords Scripts Forum
Hi Doug,

You would have to set up separate selectors for this scenario, one for each.
var keywordsToLower = AdWordsApp.keywords().withCondition("ConvertedClicks = 0").forDateRange("ALL_TIME").get();
var keywordsToLower2 = AdWordsApp.keywords().withCondition("AveragePosition > 3").forDateRange("YESTERDAY").get();
  
Thanks,
Tyler Sidell
AdWords Scripts Team

Doug

unread,
Mar 25, 2016, 6:01:13 PM3/25/16
to AdWords Scripts Forum
So how would I make changes to the keywords that were found in both selectors? Nested loops?

foreach keyword in keywordsToLower {
foreach keyword2 in keywordsToLower2 {
if keyword2=keyword then {
make bid change
}
}
}

Or is there a better way to do it? Basically I just want to find the keywords that exist in both keywordsToLower and keywordsToLower2 and then make changes to them.

Tyler Sidell (AdWords Scripts Team)

unread,
Mar 28, 2016, 10:42:37 AM3/28/16
to AdWords Scripts Forum
Hi Doug,

The best way to accomplish your particular use case would be to add two withConditions for the stats.  Since, Yesterday is part of All time couldn't you just use ALL TIME instead?

Example:
var keywordsToLower = AdWordsApp.keywords().withCondition("ConvertedClicks = 0").withCondition("AveragePosition > 3").forDateRange("ALL_TIME").get();

Thanks,
Tyler Sidell
AdWords Scripts Team

Doug

unread,
Mar 28, 2016, 1:51:17 PM3/28/16
to AdWords Scripts Forum
When the script lowers the bid, the avg position should go down. If you keep looking at all time the historical data it's going to give you an average position that is higher than the recent avg position as the keyword gets bid down.

For example, if all time position is 1.0, and after the bid change the position drops to 2.0, the all time avg position might only drop to 1.1.

I need a long history of data to analyze for bid changes (all time, last 30 days) but I need a recent view of impact from the bid changes when it comes to continuing to meet the bid rules.

Make sense?

Tyler Sidell (AdWords Scripts Team)

unread,
Mar 28, 2016, 4:15:16 PM3/28/16
to AdWords Scripts Forum
Hi Doug,

The best option would be to set these up as the two separate selectors with some nesting between them.

Thanks,
Tyler Sidell 
AdWords Scripts Team

Doug

unread,
Mar 28, 2016, 6:50:22 PM3/28/16
to AdWords Scripts Forum
That sounds like the right thing to do. Do you have any example code that I can use to help get me started with that?

Thanks!

AussieWeb Conversion

unread,
Mar 28, 2016, 9:21:38 PM3/28/16
to AdWords Scripts Forum
Hi Doug

Don't use a nested loop.  If keywords has 1000 items and keywords2 has 100 items, it'll end up doing 100,000 iterations.

If you can, place all keywords in a dictionary object then when looping through keywords2 check if it is contained within the dictionary.

var Dict = {};
foreach keyword in keywordsToLower {
   Dict[keyword] = true;
}
foreach keyword2 in keywordsToLower2 {
   if Dict[keyword2] then {
     make bid change
   }
}

or something similar.

Regards
Nigel

Doug

unread,
Mar 29, 2016, 6:23:01 PM3/29/16
to AdWords Scripts Forum
Hi Nigel,

I get an error message saying "
Missing ; before statement. (line 79)
Dismiss"

Line 79 is "foreach keyword in keywordsToLower {" and the line before it is "var Dict = {};"

Any idea why the semicolon from "var Dict = {};" isnt getting recognized?

Thanks,

Doug

Tyler Sidell (AdWords Scripts Team)

unread,
Mar 30, 2016, 9:56:01 AM3/30/16
to AdWords Scripts Forum
Hi Doug,

The semicolon in Nigel's code is being recognized. If you just leave var Dict = {}; you will get no errors. The error you are receiving is due to foreach as this is not supported in AdWords Scripts. I believe Nigel might have been referring to the forEach method.

Example:
keywordsToLower.forEach(lowerBid function);

Where lowerBid would be the function that you have set up that adjusts the bid.


Thanks,
Tyler Sidell
AdWords Scripts Team

AussieWeb Conversion

unread,
Mar 30, 2016, 10:44:17 PM3/30/16
to AdWords Scripts Forum

Hi Doug

Sorry - I gave my example in pseudocode, essentially copying & modifying what you had given previously.
I did not mean for it to be applied as is.  I should've specified that. My apologies.

Regards
Nigel

Doug

unread,
Mar 31, 2016, 7:24:35 PM3/31/16
to AdWords Scripts Forum
No worries, thanks for the clarification guys. I'll try to work with what you gave me but am not a programmer by trade so appreciate the help.

Doug

unread,
Apr 5, 2016, 9:24:12 PM4/5/16
to AdWords Scripts Forum
I think I got the functionality to work correctly but its not returning all the keywords that it should be.

I manually pulled an all time performance report for all our keywords and ran another keyword report for yesterday, and ended up with a combined report that contains all time cost, conversions, and yesterday's avg pos and the MaxCPC by keyword.

There are 39 keywords in the combined report that match the criteria below. But the script is only finding 1 keyword of the 39. Any idea why it wouldnt find the other 38? Is the code below not working as I'm intending it to? Is it not looking through all keywords in our account? I'm surprised that it completes in only 27 seconds.

Have a look:

function lowerKeywordBids() {
  var keywordsToLower1 = AdWordsApp.keywords()  
 .withCondition('Status = ENABLED')
 .withCondition('Cost >=50')

 .withCondition('ConvertedClicks = 0')
 .withCondition('MaxCpc >= 0.20')
 .orderBy('Impressions DESC')
 .forDateRange('ALL_TIME')
 .get();
 
  var keywordsToLower2 = AdWordsApp.keywords()  
 .withCondition('AveragePosition < 3')
 .withCondition('Status = ENABLED')
 .orderBy('Impressions DESC')
 .forDateRange('YESTERDAY')
 .get();
 
Logger.log('Script|Date|Campaign|Ad Group|Keyword|Previous Bid|New Bid');
while (keywordsToLower1.hasNext()) {
  var keyword1 = keywordsToLower1.next();
  var keyword1_2 = keyword1.getText();


while (keywordsToLower2.hasNext()) { 
  var keyword2 = keywordsToLower2.next();
  var keyword2_2 =keyword2.getText();

  if(keyword2_2==keyword1_2) {

var prevBid = keyword2.getMaxCpc();
var newBid = keyword2.getMaxCpc() * (1 - BID_ADJUSTMENT_COEFFICIENT)
newBid = Math.round(newBid * 100) / 100
Logger.log('Lower Keyword Bids'+'|'+mm+'/'+dd+'/'+yyyy+'|'+keyword2.getCampaign()+'|'+keyword2.getAdGroup()+'|'+keyword2.getText()+'|'+prevBid+'|'+newBid);
keyword2.setMaxCpc(keyword2.getMaxCpc() * (1 - BID_ADJUSTMENT_COEFFICIENT));
} //if
} //while
} //while
} //function

Tyler Sidell (AdWords Scripts Team)

unread,
Apr 6, 2016, 2:20:49 PM4/6/16
to AdWords Scripts Forum
Hi Doug,

I'm not seeing anything returned from your script except
Script|Date|Campaign|Ad Group|Keyword|Previous Bid|New Bid

Also, what is the report query that you are using for the report?  You could supply your CID (reply privately to the author) with the name of the script.

Thanks,
Tyler Sidell
AdWords Scripts Team

Doug McConnaughhay

unread,
Apr 8, 2016, 9:16:43 AM4/8/16
to AdWords Scripts Forum
Hi Tyler,

I replied privately. Did you see my message?

Thanks,

Doug

Anthony Madrigal

unread,
Apr 8, 2016, 10:12:25 AM4/8/16
to AdWords Scripts Forum
Hi Doug,

Tyler is out today. He responded to your message. This is what he had said:
I've taken a look at your code and the issue that you are facing is that the code you have is only outputting one iterator and there is no combination of the two.

Logger.log('Lower Keyword Bids'+'|'+mm+'/'+dd+'/'+yyyy+'|'+keyword2.getCampaign()+'|'+keyword2.getAdGroup()+'|'+keyword2.getText()+'|'+prevBid+'|'+newBid); 
keyword2.setMaxCpc(keyword2.getMaxCpc() * (1 - BID_ADJUSTMENT_COEFFICIENT));
However, I've discussed with other members of the team as well and there is no supported way to combine the two iterators in Scripts.  Usually you could use an OR operator, but this is not available in Scripts.

Regards,
Anthony
AdWords Scripts Team 
Reply all
Reply to author
Forward
0 new messages