Quality Score Script Not Working

97 views
Skip to first unread message

Caroline Seow

unread,
Apr 4, 2023, 1:02:46 AM4/4/23
to Google Ads Scripts Forum
Hi there, 

I am trying to implement a new script for quality score in my account but getting some error messages. 

Below is my script: 


//-------------------------------------------------------------------------------------------------------------//
var EMAIL_ADDRESSES = ["caro...@axxx.au"];
// The address or addresses that will be emailed a list of low QS keywords
// eg ["al...@example.com", "b...@example.co.uk"] or ["e...@example.org"]
var QS_THRESHOLD = 3;
// Keywords with quality score less than or equal to this number are
// considered 'low QS'
var LABEL_KEYWORDS = true;
// If this is true, low QS keywords will be automatically labelled
var LOW_QS_LABEL_NAME = "Low QS Keyword";
// The name of the label applied to low QS keywords
var PAUSE_KEYWORDS = false;
// If this is true, low QS keywords will be automatically paused
// Set to false if you want them to stay active.

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// Functions
function main() {
  Logger.log("Pause Keywords: " + PAUSE_KEYWORDS);
  Logger.log("Label Keywords: " + LABEL_KEYWORDS);
  var keywords = findKeywordsWithQSBelow(QS_THRESHOLD);
  Logger.log("Found " + keywords.length + " keywords with low quality score");
  if (!labelExists(LOW_QS_LABEL_NAME)) {
    Logger.log(Utilities.formatString('Creating label: "%s"', LOW_QS_LABEL_NAME));
    AdWordsApp.createLabel(LOW_QS_LABEL_NAME, 'Automatically created by QS Alert', 'red');
  }
  var mutations = [
    {
      enabled: PAUSE_KEYWORDS,
      callback: function (keyword) {
        keyword.pause();
      }
    },
    {
      enabled: LABEL_KEYWORDS,
      callback: function (keyword, currentLabels) {
        if (currentLabels.indexOf(LOW_QS_LABEL_NAME) === -1) {
          keyword.applyLabel(LOW_QS_LABEL_NAME);
        }
      }
    }
  ];
  var chunkSize = 10000;
  var chunkedKeywords = chunkList(keywords, chunkSize);
  Logger.log("Making changes to keywords..");
  chunkedKeywords.forEach(function (keywordChunk) {
    mutateKeywords(keywordChunk, mutations);
  });
  if (keywords.length > 0) {
    sendEmail(keywords);
    Logger.log("Email sent.");
  } else {
    Logger.log("No email to send.");
  }
}
function findKeywordsWithQSBelow(threshold) {
  var query = 'SELECT Id, AdGroupId, CampaignName, AdGroupName, Criteria, QualityScore, Labels'
    + ' FROM KEYWORDS_PERFORMANCE_REPORT WHERE Status = "ENABLED" AND CampaignStatus = "ENABLED" AND AdGroupStatus = "ENABLED"'
    + ' AND HasQualityScore = "TRUE" AND QualityScore <= ' + threshold;
  var report = AdWordsApp.report(query);    
  var rows = report.rows();  
  var lowQSKeywords = [];
  while (rows.hasNext()) {
    var row = rows.next();
    var lowQSKeyword = {
      campaignName: row['CampaignName'],
      adGroupName: row['AdGroupName'],
      keywordText: row['Criteria'],
      labels: (row['Labels'].trim() === '--') ? [] : JSON.parse(row['Labels']),
      uniqueId: [row['AdGroupId'], row['Id']],
      qualityScore: row['QualityScore']
    };
    lowQSKeywords.push(lowQSKeyword);
  }
  return lowQSKeywords;
}
function labelExists(labelName) {
  var condition = Utilities.formatString('LabelName = "%s"', labelName);
  return AdWordsApp.labels().withCondition(condition).get().hasNext();
}
function chunkList(list, chunkSize) {
  var chunks = [];
  for (var i = 0; i < list.length; i += chunkSize) {
    chunks.push(list.slice(i, i + chunkSize));
  }
  return chunks;
}
function mutateKeywords(keywords, mutations) {
  var keywordIds = keywords.map(function (keyword) {
    return keyword['uniqueId'];
  });
  var mutationsToApply = getMutationsToApply(mutations);
  var adwordsKeywords = AdWordsApp.keywords().withIds(keywordIds).get();
  var i = 0;
  while (adwordsKeywords.hasNext()) {
    var currentKeywordLabels = keywords[i]['labels'];
    var adwordsKeyword = adwordsKeywords.next();
    mutationsToApply.forEach(function(mutate) {
      mutate(adwordsKeyword, currentKeywordLabels);
    });
    i++;
  }
}
function getMutationsToApply(mutations) {
  var enabledMutations = mutations.filter(function (mutation) {
    return mutation['enabled'];
  });
  return enabledMutations.map(function (condition) {
      return condition['callback'];
  });
}
function sendEmail(keywords) {
  var subject = "Low Quality Keywords Paused";
  var htmlBody =
      "<p>Keywords with a quality score of less than " + QS_THRESHOLD + "found.<p>"
      + "<p>Actions Taken:<p>"
      + "<ul>"
      + "<li><b>Paused</b>: " + PAUSE_KEYWORDS + "</li>"
      + "<li><b>Labelled</b> with <code>" + LOW_QS_LABEL_NAME + "</code>: " + LABEL_KEYWORDS + "</li>"
      + "</ul>"
      + renderTable(keywords);
  MailApp.sendEmail({
    to: EMAIL_ADDRESSES.join(","),
    subject: subject,
    htmlBody: htmlBody
  });
}
function renderTable(keywords) {
  var header = '<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">'
  + '<thead><tr>'
  + '<th>Campaign Name</th>'
  + '<th>Ad Group Name</th>'
  + '<th>Keyword Text</th>'
  + '<th>Quality Score</th>'
  + '</tr></thead><tbody>';
  var rows = keywords.reduce(function(accumulator, keyword) {
    return accumulator
      + '<tr><td>' + [
      keyword['campaignName'],
      keyword['adGroupName'],
      keyword['keywordText'],
      keyword['qualityScore']
    ].join('</td><td>')
      + '</td></tr>';
  }, "");
  var footer = '</tbody></table>';
  var table = header + rows + footer;
  return table;
}

and Error message below: 

04/04/2023 11:42:01

Pause Keywords: false

04/04/2023 11:42:01

Label Keywords: true

04/04/2023 11:42:01

InputError: undefined is not a filterable field. at new QH (adsapp_compiled:17842:13) at new gI (adsapp_compiled:18060:22) at UI.report (adsapp_compiled:18739:12) at VI.report (adsapp_compiled:18887:21) at findKeywordsWithQSBelow (Code:62:27) at main (Code:23:18) at Object.<anonymous> (adsapp_compiled:19716:54)


Can you please advise where is the error message and what should I need to do to get this working?

Thank you,
Regards,
Carol

Google Ads Scripts Forum

unread,
Apr 5, 2023, 4:52:31 AM4/5/23
to Google Ads Scripts Forum
Reposting the last inquiry (https://groups.google.com/g/adwords-scripts/c/ssK1-V5yj_4) from the forum as it wasn't routed to our support queue.

Regards,
Google Ads Scripts Team

Google Ads Scripts Forum Advisor

unread,
Apr 5, 2023, 6:10:32 AM4/5/23
to adwords...@googlegroups.com

Hi Carol,

Thank you for reaching out to the Google Ads Scripts forum.

I understand that you encountered an error with your script. Upon checking, it appears that you are still using the HasQualityScore field on your query. Please be informed that this field has been deprecated, more information here. Once the said field was deleted from your query, I was able to run your script successfully without errors. With that said, kindly remove the said deprecated field from your query.

Additionally, I noticed that you've not yet migrated your script to the new experience. The new Google Ads scripts experience has a completely rewritten backend to take advantage of new features in the Google Ads API. To help you in updating your scripts, here are some resources you can use:

  • Migration guide - refer here for more information regarding the migration to new experience
  • Resource Mapping - maps the AdWords API reports to the corresponding Google Ads API resources
  • Query migration tool - this tool can be used to translate AWQL queries into GAQL
  • Best Practices - covers various best practices for developing with Google Ads scripts


Let me know if you have any questions.

Regards,

Google Logo Google Ads Scripts Team


ref:_00D1U1174p._5004Q2kFWcg:ref
Reply all
Reply to author
Forward
0 new messages