By default, in Google Merchant Center, there is no way to use Pmax performance data; while Google does show the data in your reports, it does not show the data at the product level. By having PMax data on a per-product level, you can, for example, split your campaigns up between best-performing and low-performing campaigns, using feed rules and applying custom labels. Then, create campaigns based on these labels.
This can be done by utilizing the script and plugin below, which generates data in a spreadsheet which can be used as a supplement feed.
This script was made possible by looking at the code Jermaya Leijen created, where the original inspiration came from Frederick Vallaeys. So, these two deserve enormous credit.
I also have a paid version of this script that allows you to pull and merge data from multiple campaigns. Allowing you to setup even more advanced campaigns. Feel free to reach out for more info.
Change the campaignName and add your empty sheetUrl using the script below. Then, plug the spreadsheet data as a supplemental feed into Google Merchant Center.
/****************************
* Original Inspiration By (smart shopping): Frederick Vallaeys : https://gist.github.com/siliconvallaeys/87be58bcb9ddd741fbf743359578dc60
* Inspired By (pmax): Jermaya Leijen : Script: https://adsscripts.com/scripts/google-ads-scripts/pmax-data
* Modified by: FeedArmy (https://feedarmy.com) V1.01
* The inspiration is based on when I first used a code, there may be many other developers with similar ideas
* The code I modified is pretty much 90% modified
****************************/
function main() {
try {
// Constants
const countDays = 30;
const sheetUrl = "https://docs.google.com/spreadsheets/d/1hB42Xd9ZqMvFm5YqMhc2EaTfHTpnHxqhzB_-pGAhwOM/copy";
const campaignName = "US - Performance Max";
const end = new Date(Date.now() - 86400000);
const start = new Date(Date.now() - countDays * 86400000);
const searchQuery = `SELECT segments.product_item_id, campaign.id, campaign.name, campaign.advertising_channel_type, metrics.conversions, metrics.conversions_value, metrics.clicks, metrics.cost_micros, metrics.impressions FROM shopping_performance_view WHERE campaign.advertising_channel_type = PERFORMANCE_MAX AND campaign.name = "${campaignName}" AND segments.date>='${dateFormat(start)}' AND segments.date <='${dateFormat(end)}' `;
// Data array initialization
let data = [["id", "impressions", "clicks", "conversions", "conversion_value", "cost", "roas"]];
// Google Sheets
const ss = SpreadsheetApp.openByUrl(sheetUrl);
let sh = ss.getSheetByName("Sheet1");
// Clear existing data if any
if (sh.getMaxRows() > 1) sh.getRange(1, 1, sh.getMaxRows(), data[0].length).clear();
// Fetch search results
let searchResults = AdsApp.search(searchQuery);
// Process search results
for (const row of searchResults) {
let cost = row.metrics.costMicros / 1000000;
let roas = (row.metrics.conversionsValue / cost).toFixed(2);
// Check if ROAS is NaN, set it to zero
if (isNaN(roas)) {
roas = 0;
}
let productId = row.segments.productItemId;
// Handle product ID
if (productId.includes("shopify")) {
let countryCode = productId.slice(8, 10);
let productIdVariantId = productId.substring(productId.indexOf(countryCode) + 2);
productId = "shopify_" + countryCode.toUpperCase() + productIdVariantId;
}
// Push data to array
data.push([productId, row.metrics.impressions, row.metrics.clicks, row.metrics.conversions, row.metrics.conversionsValue, cost.toFixed(2), roas]);
}
// Write data to Google Sheets
sh.getRange(1, 1, data.length, data[0].length).setValues(data);
} catch (error) {
Logger.log("An error occurred: " + error.toString());
}
}
function dateFormat(date) {
return Utilities.formatDate(date, AdsApp.currentAccount().getTimeZone(), 'yyyy-MM-dd');
}
Hi Emmanuel,
i’ve bought paid verstion and try to add script in to my adwords account. but it’s showing error when i run the script.
“Ga: Unrecognized function name “main””
Thank you for reporting the issue, this is now updated and the current version is 2.091 which you can download in your account.
Thanks for update
But I was bought via guest checkout not create account
You can contact me with proof of purchase at [email protected] and I will help you.
Hi Emmanuel. What might be causing that only the roas column has data from row 30 and beyond? I’m running 2 pmax campaigns (best performers and low performers). I’ve installed the script for each campaign, but many id fields were blank, so I’ve also tested running the script only for the best performers, but still many ID fields are blank. Also, a feed rule for custom label 2 sets the value to ‘under kpi’ for any product under 5x ROAS from both supplemental feeds (1 per pmax) as you show above. Any help is much appreciated, thanks in advance.
When you seperate products into different campaigns, the product data will only show for these specific products, meaning if you split into multiple campaigns, this script does not merge the data. However I do have a paid version of the script here: https://feedarmy.io/product/google-ads-performance-max-data-integration-script-for-google-merchant-center/ That allows you to merge data from both campaigns. If you use multiple supplement feeds, the feed rules will not work correctly. So I have to completely rebuild the script, to merge data into 1 spreadsheet. You can see how this is done in this video: https://youtu.be/1216ggvLXOM
Just a follow up, if you are not seeing some products, then this is because there is no data. Only products with data will be added. For example if you have a product with 1 impression, it will show, but if it has zero impressions, it will not show.
When uploading the supplemental feed, I receive the following issue Global feed issues>File Not Found> Failed to locate file. Please make sure the file exists.
Thanks for the resource and help Emmanuel.
If you link the supplement feed using an URL, then you need to set the spreadsheet permissions to anyone with the URL. Not a good option.
But if you link it using an existing sheet (not copy pasting the link as a file), it should automatically add Google as a user to access the file.
Also try to make sure that all users use the same email address, not sure if this causes a bug.