Google Ads Script (JavaScript)
/**
* Goodlabs Google Ads Script: Quality Score Tracker
* Schedule: Daily at 05:00
*/
var CONFIG = {
SPREADSHEET_URL: "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit",
MIN_IMPRESSIONS: 10
};
function main() {
var report = AdsApp.report(
"SELECT Criteria, CampaignName, AdGroupName, QualityScore, SearchPredictedCtr, CreativeQualityScore, PostClickQualityScore " +
"FROM KEYWORDS_PERFORMANCE_REPORT " +
"WHERE Status = ENABLED AND Impressions > " + CONFIG.MIN_IMPRESSIONS + " " +
"DURING YESTERDAY"
);
var ss = SpreadsheetApp.openByUrl(CONFIG.SPREADSHEET_URL);
var sheet = ss.getSheetByName("QS_Log") || ss.insertSheet("QS_Log");
if (sheet.getLastRow() === 0) {
sheet.appendRow(["Date", "Keyword", "Campaign", "Ad Group", "Quality Score", "Expected CTR", "Ad Relevance", "Landing Page Exp"]);
}
var rows = report.rows();
var batch = [];
var dateStr = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd");
while (rows.hasNext()) {
var row = rows.next();
batch.push([
dateStr,
row["Criteria"],
row["CampaignName"],
row["AdGroupName"],
row["QualityScore"],
row["SearchPredictedCtr"],
row["CreativeQualityScore"],
row["PostClickQualityScore"]
]);
}
if (batch.length > 0) {
sheet.getRange(sheet.getLastRow() + 1, 1, batch.length, 8).setValues(batch);
}
}How it works
- Queries
KEYWORDS_PERFORMANCE_REPORTextractingQualityScore,CreativeQualityScore(Ad Relevance),PostClickQualityScore(Landing Page Experience), andSearchPredictedCtr(Expected CTR). - Appends daily snapshot rows into Google Sheets to visualize degradation or improvements after landing page updates.
Step-by-step installation
- Create a new script under Google Ads Tools & Settings > Scripts.
- Paste the code and set your Google Sheet URL.
- Schedule daily at 05:00 AM.
Frequently asked questions
How much history fits?
A Google Sheet holds 10 million cells. At eight columns that is roughly 1.2 million keyword-days — years for a small account, months for a large one.