Skip to content

Instantly share code, notes, and snippets.

@OlenaTimchenko
Last active February 14, 2025 11:58
Show Gist options
  • Select an option

  • Save OlenaTimchenko/70acae9cf8aa05253f8312a1246f41d1 to your computer and use it in GitHub Desktop.

Select an option

Save OlenaTimchenko/70acae9cf8aa05253f8312a1246f41d1 to your computer and use it in GitHub Desktop.
Google Ads ROAS alert script

Here’s a step-by-step guide to setting up and using the ROAS analysis script:

  1. Get Your Telegram Bot Token and Chat ID:
    To create a Telegram bot, open Telegram and search for “BotFather.” Start a chat with BotFather and use the command /newbot. Follow the prompts to set a name and username for your bot. After the bot is created, BotFather will provide a bot token; copy and save it. Next, find your Telegram chat ID by adding the bot to a chat, sending any message, and visiting the URL https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates (replace YOUR_BOT_TOKEN with your token). Look for the chat.id field in the response, which will be your chat ID.

  2. Access Google Ads Scripts:
    Log in to your Google Ads account and navigate to Tools & Settings > Bulk Actions > Scripts. Click the “+” button to create a new script.

  3. Add the Script:
    Copy the provided script and paste it into the Google Ads script editor. Replace "YOUR_TELEGRAM_BOT_TOKEN" with your bot token and "YOUR_TELEGRAM_CHAT_ID" with your chat ID.

  4. Authorize the Script:
    After pasting the script, click the “Authorize” button and grant the necessary permissions to allow the script to access your Google Ads account.

  5. Adjust Script Parameters:
    Set the number of days to analyze (default is 7) and the deviation threshold percentage (default is 5%) to match your requirements.

  6. Run and Schedule the Script:
    To test the script, click “Preview” in the editor. If the preview runs without issues, click “Run” to execute the script manually. To automate the script, click “Actions > Create Schedule” and select a frequency, such as daily or weekly.

  7. Monitor Results:
    Once the script is running, it will analyze ROAS deviations across campaigns in your Google Ads account. If a significant deviation is detected, a notification will be sent to your Telegram chat with details about the specific account. You can also check the logs in Google Ads Scripts for additional details.

This script automates ROAS monitoring and provides instant notifications, saving you time and helping you respond quickly to potential inefficiencies in your campaigns. Interested in the topic? Join my Telegram channel. "Тут про рекламу" – all information is shared in Ukrainian. I write about AI solutions, their applications in advertising, and develop solutions designed to save time and streamline processes.

I have also developed a GPT-powered assistant for creating Google Ads texts while adhering to Google Ads policies. It's free to use, and you can access it here: Google Ads Text Writer. Use it to automate routine tasks efficiently and intelligently.

/**
* @author Olena Timchenko - Telegram @Timchenko_elena
* === SETTINGS ===
* This script analyzes the ROAS (Return on Ad Spend) performance of Google Ads campaigns
* over a specified number of days and calculates the average deviation (positive or negative).
* If the deviation exceeds a predefined threshold, it sends a notification to a specified
* Telegram chat, enabling timely attention to potential campaign inefficiencies.
* Enter the required information in the fields below before running the script.
* @version 1.1
*/
// Telegram Settings
const TELEGRAM_BOT_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN"; // Enter your Telegram bot token
const TELEGRAM_CHAT_ID = "YOUR_TELEGRAM_CHAT_ID"; // Enter the chat ID where messages will be sent
// ROAS Analysis Settings
const DAYS_TO_ANALYZE = 7; // Number of days to analyze
const DEVIATION_THRESHOLD = 5; // Deviation threshold in percentage for notifications
function main() {
const accountName = AdsApp.currentAccount().getName();
Logger.log("Account Name: " + accountName);
const roasData = fetchROASData(DAYS_TO_ANALYZE);
Logger.log("ROAS Data: " + JSON.stringify(roasData));
const avgROAS = calculateAverageROAS(roasData);
Logger.log("Average ROAS: " + avgROAS);
const deviationPercentage = calculateROASDeviation(roasData, avgROAS);
Logger.log("ROAS Deviation Percent: " + deviationPercentage.toFixed(2) + "%");
if (Math.abs(deviationPercentage) > DEVIATION_THRESHOLD) {
const deviationType = deviationPercentage > 0 ? "increase" : "decrease";
const message = `📊 *ROAS Alert in Account: "${accountName}"* 📊\n
ROAS has a *${deviationType}* of *${Math.abs(deviationPercentage).toFixed(2)}%* over the last ${DAYS_TO_ANALYZE} days.\n
Please review the campaign performance.`;
sendTelegramMessage(TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID, message);
Logger.log("Alert sent to Telegram.");
} else {
Logger.log("No significant deviations in ROAS detected.");
}
}
function fetchROASData(days) {
const query = `
SELECT
campaign.id,
campaign.name,
metrics.conversions_value,
metrics.cost_micros
FROM
campaign
WHERE
segments.date DURING LAST_${days}_DAYS
AND campaign.status = 'ENABLED'
`;
const report = AdsApp.report(query);
const rows = report.rows();
const campaigns = [];
while (rows.hasNext()) {
const row = rows.next();
const cost = row['metrics.cost_micros'] / 1000000;
const conversionsValue = row['metrics.conversions_value'];
const roas = cost > 0 ? conversionsValue / cost : 0;
campaigns.push({
id: row['campaign.id'],
name: row['campaign.name'],
roas: roas
});
}
return campaigns;
}
function calculateAverageROAS(campaigns) {
if (campaigns.length === 0) return 0;
const totalROAS = campaigns.reduce((sum, campaign) => sum + campaign.roas, 0);
return totalROAS / campaigns.length;
}
function calculateROASDeviation(campaigns, avgROAS) {
if (avgROAS === 0) return 0;
const totalDeviation = campaigns.reduce((sum, campaign) => sum + ((campaign.roas - avgROAS) / avgROAS) * 100, 0);
return totalDeviation / campaigns.length;
}
function sendTelegramMessage(botToken, chatId, message) {
const url = 'https://api.telegram.org/bot${botToken}/sendMessage';
const payload = {
chat_id: chatId,
text: message,
parse_mode: "Markdown"
};
const options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload)
};
try {
const response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() !== 200) {
Logger.log("Error sending message: " + response.getContentText());
}
} catch (error) {
Logger.log("Telegram API Error: " + error.toString());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment