Google Ads Script for Low‑Spending Shopping Products
Most Shopping accounts have a long tail of products that get impressions and a few clicks, but never enough spend to generate statistically significant data. These products stagnate in the background while your budget keeps flowing into a small set of items. The result is missed revenue opportunities and a distorted view of what really works in your catalog.
The low‑spending products script tackles this by systematically identifying items with very low ad spend over a defined period and surfacing them so you can optimize them separately. Instead of letting Google allocate budget blindly, you create a controlled environment where promising products can finally ramp up.
How does this custom script work?
This script scans your Pmax campaigns and looks for products that:
• Have accumulated only a small amount of spend in the selected date range.
• Label low‑spending items so you can group and manage them in dedicated campaigns.
• Export them to a spreadsheet, giving you a clear list of IDs that need attention.
• This turns what was previously a hidden issue into something visible, measurable, and optimizable.
// Low performing IDs Script by Francesco Azzarone
// custom requests? francesco.azzarone@foxdatax.com
// Enter your data here;
// CONFIG
const MERCHANT_ID = Merchant id number;
const SPREADSHEET_URL = "Spreadsheet URL";
const SHEET_NAME_SUFFIX = "Low Spending Products";
const COST_THRESHOLD = 3; // Here you can choose the amount
const DAYS_AGO = 30;
const LABEL_VALUE = "Low Spending Products"; // custom label Value
const CUSTOM_LABEL = "custom_label_4"; // Choose your custom label
function main() {
try {
const accountName = AdWordsApp.currentAccount().getName();
const sheetName = accountName + " " + SHEET_NAME_SUFFIX;
Logger.log("Analysis for account: " + accountName);
const productIdsMerchant = getProductIds(MERCHANT_ID);
const lowCostProducts = getLowCostProducts(DAYS_AGO, COST_THRESHOLD);
const updatedProducts = updateProductIds(lowCostProducts, productIdsMerchant);
pushToSpreadsheet(updatedProducts, sheetName);
Logger.log("Script completed.");
} catch (error) {
Logger.log("Error: " + error.toString());
}
}
function getProductIds(merchantId) {
let productIds = [];
let pageToken;
do {
let response = ShoppingContent.Products.list(merchantId, { pageToken: pageToken });
if (response && response.resources) {
response.resources.forEach(product => {
let idParts = product.id.split(':');
productIds.push(idParts[idParts.length - 1]);
});
pageToken = response.nextPageToken;
} else {
break;
}
} while (pageToken);
return productIds;
}
function getLowCostProducts(daysAgo, costThreshold) {
const today = new Date();
const startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - daysAgo);
const dateFrom = Utilities.formatDate(startDate, AdWordsApp.currentAccount().getTimeZone(), 'yyyyMMdd');
const dateTo = Utilities.formatDate(today, AdWordsApp.currentAccount().getTimeZone(), 'yyyyMMdd');
const query = `
SELECT OfferId, Cost, Conversions, ConversionValue
FROM SHOPPING_PERFORMANCE_REPORT
DURING ${dateFrom},${dateTo}
`;
const products = [];
const report = AdsApp.report(query);
const rows = report.rows();
while (rows.hasNext()) {
const row = rows.next();
const offerId = row['OfferId'];
const cost = parseFloat(row['Cost'].replace(",", ""));
const conversions = parseFloat(row['Conversions'].replace(",", ""));
const conversionValue = parseFloat(row['ConversionValue'].replace(",", ""));
const roas = cost > 0 ? (conversionValue / cost) * 100 : 0;
if (cost < costThreshold) {
products.push([
offerId,
LABEL_VALUE,
cost.toFixed(2) + " €",
conversionValue.toFixed(2) + " €",
roas.toFixed(2) + " %",
conversions.toFixed(2)
]);
}
}
return products;
}
function updateProductIds(productsGoogle, productIdsMerchant) {
const idMap = {};
productIdsMerchant.forEach(id => {
idMap[id.toLowerCase()] = id;
});
return productsGoogle.map(product => {
product[0] = idMap[product[0].toLowerCase()] || product[0];
return product;
});
}
function pushToSpreadsheet(data, sheetName) {
const spreadsheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
let sheet = spreadsheet.getSheetByName(sheetName);
if (!sheet) {
sheet = spreadsheet.insertSheet(sheetName);
} else {
sheet.clear();
}
// Updated headers
sheet.appendRow(["id", CUSTOM_LABEL, "Cost (€;)", "Conversion Value (€)", "ROAS (%)", "Conversions"]);
if (data.length > 0) {
const range = sheet.getRange(2, 1, data.length, 6);
range.setValues(data);
sheet.getRange('A2:A' + (data.length + 1)).setNumberFormat("@");
Logger.log("Inseriti " + data.length + " prodotti.");
} else {
Logger.log("No products with cost lower than " + COST_THRESHOLD + "€.");
}
}
How to install the script
To install this Google Ads script in your account, follow these steps:
- Sign in to your Google Ads account.
- Click the Tools and settings icon in the top menu.
- Under Bulk actions, click Scripts to open the Scripts workspace.
- On the Scripts page, click the blue + button to create a New script.
- Give the script a clear name (for example: “Low Spending Products – Shopping”), so it’s easy to identify later.
- Paste the script code
- Delete any placeholder code that appears in the editor.
- Copy the full script and paste it into the Google Ads script editor.
- Replace the placeholder values in the config section, such as:`MERCHANT_ID` with your Merchant Center ID, `SPREADSHEET_URL` with the URL of your Google Sheets document (important: the sheet must have edit access so the script can write into it).
- On Advanced API, flag the option “Shopping Content“
- Authorize the script
- Click Save in the top right of the editor.
- Click “Authorize” above the editor to grant the script permission to access and modify your Google Ads account and linked services.
- Run and schedule the script when you are satisfied with the preview, click Run to apply it for the first time.
- Check the “Logs” and “Changes” panel to verify that: No errors are thrown.
- Back on the Scripts list, set the Frequency (running it on the first day of the month is suggested; once per month is enough)
- Save the schedule so the script keeps updating your low-spending products and the spreadsheet automatically.
- Last Thing is to import the spreadsheet in Merchant Center as a supplemental feed
- After few hours, the new label should start appearing in Merchant Center and then in Google Ads.
At that point, you can build a dedicated campaign for these products to give them extra visibility.