- Media Launcher
- Posts
- RSA Booster v1.5 (Single Account)
RSA Booster v1.5 (Single Account)
Supercharge your Google Ads Search Campaigns performance by automatically monitoring RSA ads headlines and description.
SPONSOR - Custom Automations by MediaLauncher.io đ
Hey, before I leave you to your script I have an announcement to make: you can now get me (and soon my team) to create custom automations for you!
You can book us for a one-off project, or on a monthly basis. We offer:
Up to Unlimited requests
Unlimited revisions
Free technical project analysis
Tailored recommendations
High priority support
Full access to the source code
Whitelabeling
30 days money back guarantee
This is perfect for you if your business relies heavily on advertising for revenue, but lacks technical capabilities to automate tasks to increase productivity. Ideal for mid to large Ecommerce, startups that raised funding, agencies, or corporates with small marketing teams.
Platforms we automate: Google Ads, Meta Ads, Linkedin Ads, Native, & more.
The tools we use: Custom scripts, Zapier, Make, n8n, Supermetrics, Funnel, & more.
Weâre still working on the website, so if youâre interested in learning more submit a request here. Describe your needs, attach your company website, and letâs see if weâre a fit.
Looking forward to taking your ads game to the next level! đ
RSA Booster v1.5 - Why Use This Script
In our data-dominated world creatives often get put at second place. Optimizing responsive search ads (RSA) headlines and descriptions is crucial for Search campaigns performance.
To ensure that your RSA assets are performing optimally across all campaigns you can analyze the Assets > Table view: Assets report, but this shows headlines and descriptions performance aggregated across all Search campaigns.
What the Script Does
The RSA Booster v1.5 script allows you to get granular data, at the ad-level. After generating the report, and it sends an email if Low performing assets are found.
On top of it, the Google Sheet template provided allows you to automatically generate Low-performing headlines and description alternatives directly in the sheet - if you provide your own OpenAI API Key.
Hereâs whatâs provided:
A report of RSA assets with performance label
Detailed information for each asset, including:
- Campaign and Ad Group names
- Ad Label for unique identification
- Asset Type (Headline or Description)
- Clicks, Impressions, and CTR
- Asset text and performance label
- Date range for the performance dataAn alert system that emails designated recipients when low-performing assets are detected, including a summary of key details and a direct link to the report for immediate review.
A second script inside the Google Sheet to create low-performing assets alternatives directly inside the sheet.
How It Works
Connects to your Google Ads account to gather asset performance data across all campaigns and ad groups.
Retrieves performance data based on user-defined criteria, such as minimum clicks and a selected look-back window.
Analyzes asset performance and labels assets as âLOW,â âLEARNING,â âGOOD,â or âBEST.â
Generates ad labels (e.g., âAd 1,â âAd 2â) within ad groups to uniquely identify ads (as most of the time not all ads are labeled, making it had to identify where each headline belongs).
Exports results to a specified Google Sheets URL.
Sends email alerts when low-performing assets are identified, summarizing key information and including a direct link to the report. (If no low-performing assets are found, the report remains updated but no email is sent.)
Generates 3 alternative assets directly in your language in use, if you manually trigger a second script, placed inside the sheet, from the custom menu RSA Booster > Generate alternative assets
How to Use It
Create a copy of this Google Sheet template and copy its URL. If you want to generate assets aternatives directly in the sheet:
Click on Extensions > Apps Script
On the left, click on Project settings
Scroll down, and under Script Properties click Add script property
Under Property type âAPI_KEYâ
Under Value enter your OpenAI API key
Copy-Paste the script below into a new Google Ads Script in your account.
Set the following parameters in the script:
NUMBER_OF_CLICKS
: Define the minimum click threshold for evaluation (default: 100).LOOKBACK_WINDOW
: Specify the performance data timeframe (e.g., âLAST_30_DAYSâ or âLAST_7_DAYSâ).SPREADSHEET_URL
: Paste the URL of your Google Sheet template copy.EMAIL_ADDRESSES
: List the email recipients for alerts.
Run the script or schedule it to run automatically at your desired intervals. My recommendation would be to run it weekly.
Generate alternative assets directly in the sheet by clicking RSA Booster > Generate alternative assets in the custom menu at the top
Reviewing the Results
After running the script, navigate to your Google Sheets report and review the output.
Focus on assets marked as âLOWâ in the âPerformance Labelâ column.
Review campaign and ad group context to understand asset placement.
Analyze CTR and other metrics to identify potential issues.
Consider checking for trends or patterns across multiple reports over time to identify consistent performance issues or improvements.
Based on your findings, consider:
Updating low-performing headlines or descriptions with more engaging content.
Adjusting targeting or bidding strategies for ad groups with consistent low performance.
Testing new variations of RSAs to boost overall ad quality.
Better headlines or descriptions can significantly improve ad performance by enhancing relevance and engagement, leading to higher click-through rates and potentially lower CPCs.
But remember, while this script provides valuable insights, always use your expertise and knowledge of your business goals when making final decisions about your Google Ads strategy.
Credits
P.S. I wanted to give credit to Slava Wagner, who inpired me to create this script with one of his super interistng Make automations. Check out his Linkedin profile here.
Customize this script
Want to an MCC version? Maybe customize the prompt, or specific filters? We got you covered!
Submit a request here. Describe your needs, attach your company website, and letâs see if weâre a fit.
The code
/**
* RSA BOOSTER v1.5
* Created by Francesco Cifardi
* For issues or questions reach out on Linkedin (https://www.linkedin.com/in/francescocifardi/)
* Free to use and share, a mention would be appreciated :-)
*
* This script monitors and evaluates asset performance across Google Ads campaigns,
* identifying low-performing assets and generating comprehensive reports. It exports
* data to a Google Sheet and sends email alerts when low-performing assets are detected.
*
* Key Features:
* - Tracks performance metrics (clicks, impressions, CTR)
* - Identifies low-performing assets
* - Generates unique ad labels within ad groups
* - Creates detailed performance reports
* - Sends email alerts for low-performing assets
*
* Note: The provided Google Sheet template includes an additional Apps Script that can
* generate alternative suggestions for low-performing assets using OpenAI's API
* (requires API key configuration).
*
* For complete setup instructions and documentation, visit:
* https://medialauncher.beehiiv.com/p/rsa-booster
*/
// User-modifiable criteria:
var NUMBER_OF_CLICKS = 100; // Minimum number of clicks to qualify for evaluation
var LOOKBACK_WINDOW = 'LAST_30_DAYS'; // Look-back window for performance data
// Spreadsheet template: https://docs.google.com/spreadsheets/d/1ydQFFkGojmcxjvp3PkXaT-CpypawHpeil2xSD5qaB2c/copy
var SPREADSHEET_URL = 'YOUR_URL'; // Add the URL of your Google Sheets template copy h
var EMAIL_ADDRESSES = [
'[email protected]'
// Add more email addresses as needed, between signle quotes, and comma separated
];
function main() {
// Get date range for reporting
const dates = getLookbackDates(LOOKBACK_WINDOW);
// Initialize spreadsheet
const ss = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
const sheet = ss.getActiveSheet();
// Define headers first
const headers = [
'Campaign', 'Ad Group', 'Ad Label', 'Clicks', 'Impressions', 'CTR',
'Asset Type', 'Asset Text', 'Performance Label',
'Report Start Date', 'Report End Date'
];
// Clear existing data while preserving formatting
const lastRow = Math.max(sheet.getLastRow(), 1);
const lastCol = Math.max(sheet.getLastColumn(), headers.length);
if (lastRow > 1) { // Only clear if there's data (preserve headers)
sheet.getRange(2, 1, lastRow - 1, lastCol).clearContent();
}
// Set headers
sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
// Rest of query remains the same
const query = `
SELECT
ad_group_ad.ad.id,
ad_group_ad.ad.responsive_search_ad.headlines,
ad_group_ad.ad.responsive_search_ad.descriptions,
campaign.name,
ad_group.name,
metrics.clicks,
metrics.impressions
FROM ad_group_ad
WHERE
campaign.status = "ENABLED"
AND metrics.clicks > ${NUMBER_OF_CLICKS}
AND segments.date DURING ${LOOKBACK_WINDOW}
LIMIT 1000
`;
const response = AdsApp.search(query);
let rowData = [];
let lowPerformingAssets = [];
let adGroupCounter = {}; // Track ad counts per ad group
while (response.hasNext()) {
const row = response.next();
const jsonString = JSON.stringify(row);
const data = JSON.parse(jsonString);
// Generate ad label
const adGroupKey = `${row.campaign.name}_${row.adGroup.name}`;
adGroupCounter[adGroupKey] = (adGroupCounter[adGroupKey] || 0) + 1;
const adLabel = `Ad ${adGroupCounter[adGroupKey]}`;
// Process headlines and descriptions
const assets = processAssets(data);
// Create row for each asset
assets.forEach(asset => {
if (asset.performanceLabel === 'LOW') {
lowPerformingAssets.push({
campaign: row.campaign.name,
adGroup: row.adGroup.name,
adLabel: adLabel,
type: asset.type,
text: asset.text
});
}
rowData.push([
row.campaign.name,
row.adGroup.name,
adLabel, // Add ad label to the row
row.metrics.clicks,
row.metrics.impressions,
(row.metrics.clicks/row.metrics.impressions * 100).toFixed(2) + '%',
asset.type,
asset.text,
asset.performanceLabel,
dates.startDate,
dates.endDate
]);
});
}
// Write all data at once
if (rowData.length > 0) {
sheet.getRange(2, 1, rowData.length, headers.length).setValues(rowData);
}
// Send email if there are low performing assets
if (lowPerformingAssets.length > 0) {
sendLowPerformanceAlert(lowPerformingAssets, SPREADSHEET_URL);
}
}
// New function to process assets and return structured data
function processAssets(data) {
const assets = [];
function findAssets(obj, context) {
if (typeof obj === 'object') {
let currentAsset = {};
for (const key in obj) {
if (Array.isArray(obj[key])) {
for (const item of obj[key]) {
findAssets(item, key);
}
} else if (typeof obj[key] === 'object') {
findAssets(obj[key], key);
} else if (key === 'text') {
currentAsset.type = context === 'headlines' ? 'Headline' : 'Description';
currentAsset.text = obj[key];
} else if (key === 'assetPerformanceLabel') {
currentAsset.performanceLabel = obj[key];
assets.push({...currentAsset});
currentAsset = {};
}
}
}
}
findAssets(data, '');
return assets;
}
// New function to calculate date range based on lookback window
function getLookbackDates(lookbackWindow) {
const endDate = new Date();
let startDate = new Date();
switch(lookbackWindow) {
case 'LAST_30_DAYS':
startDate.setDate(endDate.getDate() - 30);
break;
case 'LAST_7_DAYS':
startDate.setDate(endDate.getDate() - 7);
break;
// Add more cases as needed
}
return {
startDate: startDate.toISOString().split('T')[0],
endDate: endDate.toISOString().split('T')[0]
};
}
// Updated email alert function
function sendLowPerformanceAlert(lowPerformingAssets, spreadsheetUrl) {
const subject = 'Google Ads Alert: Low Performing RSA Assets Detected';
let emailBody = 'The following RSA assets are showing low performance:\n\n';
lowPerformingAssets.forEach(asset => {
emailBody += `Campaign: ${asset.campaign}\n`;
emailBody += `Ad Group: ${asset.adGroup}\n`;
emailBody += `Ad Label: ${asset.adLabel}\n`;
emailBody += `Asset Type: ${asset.type}\n`;
emailBody += `Asset Text: ${asset.text}\n\n`;
});
emailBody += `\nView full report here: ${spreadsheetUrl}`;
MailApp.sendEmail({
to: EMAIL_ADDRESSES.join(','),
subject: subject,
body: emailBody
});
}
Have questions or feedback? Hit reply. Loved it? Share it! đ
And if this was forwarded to you, but youâre not subscribed yetâŚ