מהם סקריפטים של גוגל אדס ולמה הם כל כך חשובים?
דמיינו שיש לכם עוזר אישי שעובד 24/7, לא עושה טעויות, ומבצע עבורכם את כל המשימות המונוטוניות בניהול חשבון הגוגל אדס. אלו בדיוק סקריפטים של גוגל אדס. הם מאפשרים לנו להרחיב את היכולות הבסיסיות של הפלטפורמה ולבצע פעולות מורכבות באופן אוטומטי. היתרונות המרכזיים ברורים: חיסכון אדיר בזמן, צמצום טעויות אנוש, יכולת לקבל התראות בזמן אמת על שינויים קריטיים, וביצוע אופטימיזציות מבוססות חוקים ברמת דיוק שקשה להגיע אליה ידנית. בעולם תחרותי של קידום ממומן בגוגל, אוטומציה היא לא פריבילגיה אלא הכרח כדי להישאר רלוונטיים ויעילים.
את ממשק הסקריפטים ניתן למצוא בחשבון הגוגל אדס תחת 'כלים והגדרות' (Tools & Settings) > 'פעולות בכמות גדולה' (Bulk Actions) > 'סקריפטים' (Scripts). משם, הדרך להפעלת האוטומציה הראשונה שלכם קצרה מתמיד.
לפני שמתחילים: איך מוסיפים סקריפט חדש לחשבון?
התהליך פשוט וידידותי גם למי שאינו מפתח. עקבו אחר הצעדים הבאים:
- ניווט לממשק הסקריפטים: היכנסו לחשבון הגוגל אדס, לחצו על 'כלים והגדרות' ובחרו ב'סקריפטים' תחת קטגוריית 'פעולות בכמות גדולה'.
- יצירת סקריפט חדש: לחצו על כפתור הפלוס הכחול (+) כדי לפתוח את עורך הסקריפטים.
- מתן שם והדבקת הקוד: העניקו לסקריפט שם ברור שיתאר את פעולתו (למשל, 'בודק קישורים שבורים יומי'). לאחר מכן, הדביקו את קוד ה-JavaScript שתמצאו בהמשך המדריך בשדה המיועד.
- הרשאה: בפעם הראשונה שתפעילו סקריפט, תצטרכו להעניק לו הרשאה לגשת לנתוני החשבון ולבצע בו שינויים. זהו תהליך חד פעמי לכל סקריפט.
- תצוגה מקדימה (Preview): לפני הפעלה מלאה, תמיד השתמשו באפשרות 'תצוגה מקדימה'. מצב זה מדמה את פעולת הסקריפט ומציג לכם את השינויים שהוא היה מבצע, מבלי ליישם אותם בפועל. זהו שלב קריטי לוודא שהסקריפט פועל כמצופה.
- הגדרה ותזמון: לאחר שווידאתם שהכל תקין, תוכלו להגדיר תדירות הרצה אוטומטית (שעתית, יומית, שבועית או חודשית) ולשמור את הסקריפט.
סקריפט 1: בדיקת קישורים שבורים (404) בחשבון
למה זה חשוב?
קישור שבור במודעה או ב-Sitelink הוא בזבוז כסף טהור. אתם משלמים על קליק שמוביל את המשתמש לדף שגיאה (404), מה שיוצר חווית משתמש שלילית, פוגע בתדמית המותג ומוריד את ציון האיכות שלכם. בדיקה ידנית של כל הקישורים בחשבון גדול היא משימה כמעט בלתי אפשרית.
איך זה עובד?
הסקריפט סורק את כל כתובות ה-URL הסופיות (Final URLs) של המודעות, מילות המפתח ותוספי ה-Sitelink הפעילים בחשבון. הוא שולח בקשה לכל כתובת ובודק את קוד התגובה של השרת (HTTP Status Code). אם הקוד הוא 404 (Not Found) או קוד שגיאה אחר, הסקריפט שולח התראה מפורטת במייל עם רשימת הקישורים התקולים.
קוד הסקריפט
function main() {
const RECIPIENT_EMAIL = '[email protected]';
const SPREADSHEET_URL = 'PASTE_YOUR_SPREADSHEET_URL_HERE';
const spreadsheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
const sheet = spreadsheet.getActiveSheet();
sheet.clear();
sheet.appendRow(['Campaign', 'Ad Group', 'Type', 'URL', 'Response Code']);
const entities = getEntitiesToCheck();
let brokenUrls = [];
for (const entity of entities) {
const url = entity.url;
if (!url) continue;
try {
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true });
const responseCode = response.getResponseCode();
if (responseCode >= 400) {
const brokenInfo = {
campaign: entity.campaign,
adGroup: entity.adGroup,
type: entity.type,
url: url,
code: responseCode
};
brokenUrls.push(brokenInfo);
sheet.appendRow([brokenInfo.campaign, brokenInfo.adGroup, brokenInfo.type, brokenInfo.url, brokenInfo.code]);
}
} catch (e) {
// Could be a malformed URL
const brokenInfo = {
campaign: entity.campaign,
adGroup: entity.adGroup,
type: entity.type,
url: url,
code: 'Error: ' + e.message
};
brokenUrls.push(brokenInfo);
sheet.appendRow([brokenInfo.campaign, brokenInfo.adGroup, brokenInfo.type, brokenInfo.url, brokenInfo.code]);
}
}
if (brokenUrls.length > 0) {
sendEmail(RECIPIENT_EMAIL, brokenUrls, SPREADSHEET_URL);
}
}
function getEntitiesToCheck() {
let entities = [];
// Add Ads
const adIterator = AdsApp.ads().withCondition('Status = ENABLED').get();
while (adIterator.hasNext()) {
const ad = adIterator.next();
entities.push({
campaign: ad.getCampaign().getName(),
adGroup: ad.getAdGroup().getName(),
type: 'Ad',
url: ad.urls().getFinalUrl()
});
}
// Add Keywords
const keywordIterator = AdsApp.keywords().withCondition('Status = ENABLED').get();
while (keywordIterator.hasNext()) {
const keyword = keywordIterator.next();
entities.push({
campaign: keyword.getCampaign().getName(),
adGroup: keyword.getAdGroup().getName(),
type: 'Keyword',
url: keyword.urls().getFinalUrl()
});
}
// Add Sitelinks
const sitelinkIterator = AdsApp.extensions().sitelinks().get();
while (sitelinkIterator.hasNext()) {
const sitelink = sitelinkIterator.next();
entities.push({
campaign: 'Account Level',
adGroup: 'Account Level',
type: 'Sitelink',
url: sitelink.urls().getFinalUrl()
});
}
return entities;
}
function sendEmail(recipient, brokenUrls, spreadsheetUrl) {
let subject = 'Alert: Broken URLs Found in Google Ads Account';
let body = 'The following broken URLs were found:\n\n';
for (const item of brokenUrls) {
body += `Campaign: ${item.campaign}, Ad Group: ${item.adGroup}, Type: ${item.type}, URL: ${item.url}, Code: ${item.code}\n`;
}
body += `\nFull report available at: ${spreadsheetUrl}`;
MailApp.sendEmail(recipient, subject, body);
}
התאמה אישית
לפני ההרצה, שנו את כתובת המייל בשורה `const RECIPIENT_EMAIL = '[email protected]';` לכתובת שלכם, וצרו Google Sheet חדש, הדביקו את הקישור שלו במקום `PASTE_YOUR_SPREADSHEET_URL_HERE`, והריצו בתדירות יומית.
סקריפט 2: השהיית מילות מפתח עם ציון איכות נמוך
למה זה חשוב?
ציון איכות (Quality Score) הוא הדירוג של גוגל לרלוונטיות של מילת המפתח, המודעה ודף הנחיתה. ציון נמוך מוביל לעלויות קליק גבוהות יותר ולמיקומי מודעה נמוכים יותר. זיהוי והשהיה אוטומטית של מילות מפתח עם ציון איכות נמוך באופן כרוני (שלא הצלחתם לשפר) יכול לחסוך כסף ולשפר את בריאות החשבון. הגורם המשפיע ביותר על ציון האיכות הוא יחס ההקלקה, ולכן חשוב להבין מה זה CTR וכיצד לשפר אותו.
איך זה עובד?
הסקריפט סורק את כל מילות המפתח הפעילות בחשבון. עבור כל מילה, הוא בודק את ציון האיכות שלה. אם הציון נמוך מהרף שהוגדר (למשל, 3 ומטה) וגם צברה כמות חשיפות מינימלית (כדי להבטיח מובהקות סטטיסטית), הסקריפט ישנה את הסטטוס שלה ל'מושהה' (Paused) ויוסיף לה תווית (Label) לצורך מעקב קל.
קוד הסקריפט
function main() {
const QUALITY_SCORE_THRESHOLD = 3; // Pause keywords with QS <= this value
const MIN_IMPRESSIONS = 100; // Only consider keywords with at least this many impressions
const LABEL_NAME = 'Paused_Low_QS';
ensureLabelExists(LABEL_NAME);
const keywordIterator = AdsApp.keywords()
.withCondition('Status = ENABLED')
.withCondition(`QualityScore <= ${QUALITY_SCORE_THRESHOLD}`)
.withCondition(`Impressions > ${MIN_IMPRESSIONS}`)
.forDateRange('ALL_TIME')
.get();
let pausedKeywords = [];
while (keywordIterator.hasNext()) {
const keyword = keywordIterator.next();
keyword.pause();
keyword.applyLabel(LABEL_NAME);
pausedKeywords.push(keyword.getText());
Logger.log(`Paused keyword: ${keyword.getText()} in Ad Group: ${keyword.getAdGroup().getName()}`);
}
if (pausedKeywords.length > 0) {
// Optional: Send an email notification
MailApp.sendEmail('[email protected]',
'Low Quality Score Keywords Paused',
`The script has paused ${pausedKeywords.length} keywords due to low quality score. Keywords paused: \n${pausedKeywords.join('\n')}`);
}
}
function ensureLabelExists(labelName) {
const labelIterator = AdsApp.labels().withCondition(`Name = '${labelName}'`).get();
if (!labelIterator.hasNext()) {
AdsApp.createLabel(labelName, 'Keywords paused automatically due to low Quality Score.');
}
}
התאמה אישית
ניתן לשנות את סף ציון האיכות בפרמטר `QUALITY_SCORE_THRESHOLD` ואת רף החשיפות המינימלי ב-`MIN_IMPRESSIONS`. אל תשכחו לעדכן את כתובת המייל להתראות.
סקריפט 3: התראה על שינויים דרסטיים בביצועים
למה זה חשוב?
חשבונות פרסום הם דינמיים. תקלה במעקב המרות, שינוי פתאומי במגמת חיפוש או בעיה בדף הנחיתה יכולים לגרום לצניחה חדה בביצועים. סקריפט זה משמש כמערכת התראה מוקדמת שמודיעה לכם על חריגות משמעותיות, ומאפשרת לכם להגיב במהירות לפני שנגרם נזק גדול.
איך זה עובד?
הסקריפט משווה את נתוני הביצועים של אתמול (קליקים, עלות, המרות) לנתונים של אותו יום בשבוע שעבר. אם הפער באחוזים עבור מדד כלשהו (למשל, ירידה של 30% בהמרות) גדול מהסף שהגדרתם, תישלח אליכם התראה מיידית במייל.
קוד הסקריפט
function main() {
const RECIPIENT_EMAIL = '[email protected]';
const THRESHOLD = 0.2; // 20% change
const yesterday = new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
const sameDayLastWeek = new Date(new Date().getTime() - 8 * 24 * 60 * 60 * 1000);
const yesterdayStats = getStatsForDate(yesterday);
const lastWeekStats = getStatsForDate(sameDayLastWeek);
let alerts = [];
checkMetric('Clicks', yesterdayStats.clicks, lastWeekStats.clicks, THRESHOLD, alerts);
checkMetric('Cost', yesterdayStats.cost, lastWeekStats.cost, THRESHOLD, alerts);
checkMetric('Conversions', yesterdayStats.conversions, lastWeekStats.conversions, THRESHOLD, alerts);
if (alerts.length > 0) {
let subject = 'Alert: Significant Performance Change Detected';
let body = 'The following significant performance changes were detected when comparing yesterday to the same day last week:\n\n' + alerts.join('\n');
MailApp.sendEmail(RECIPIENT_EMAIL, subject, body);
}
}
function getStatsForDate(date) {
const dateString = Utilities.formatDate(date, AdsApp.currentAccount().getTimeZone(), 'yyyyMMdd');
const report = AdsApp.report(
'SELECT Clicks, Cost, Conversions ' +
'FROM ACCOUNT_PERFORMANCE_REPORT ' +
`DURING ${dateString},${dateString}`
);
const row = report.rows().next();
return {
clicks: row['Clicks'],
cost: parseFloat(row['Cost'].replace(/,/g, '')),
conversions: row['Conversions']
};
}
function checkMetric(metricName, todayValue, lastWeekValue, threshold, alerts) {
if (lastWeekValue == 0) return;
const change = (todayValue - lastWeekValue) / lastWeekValue;
if (Math.abs(change) > threshold) {
const changePercent = (change * 100).toFixed(2);
alerts.push(`${metricName} changed by ${changePercent}%. Yesterday: ${todayValue}, Same day last week: ${lastWeekValue}`);
}
}
התאמה אישית
התאימו את כתובת המייל ואת סף הרגישות בפרמטר `THRESHOLD` (למשל, 0.3 עבור שינוי של 30%). מומלץ להריץ את הסקריפט כל בוקר.
סקריפט 4: דוח N-Gram לניתוח שאילתות חיפוש
למה זה חשוב?
דוח שאילתות החיפוש (Search Query Report) הוא מכרה זהב של תובנות. ניתוח ידני שלו יכול להיות מייגע, ובדרך כלל מסתכם בהוספת מילות מפתח שליליות בודדות. ניתוח N-Gram לוקח את זה צעד קדימה. הוא מפרק את כל שאילתות החיפוש לרצפים של מילה אחת (1-gram), שתי מילים (2-gram) ושלוש מילים (3-gram), ומסכם את הביצועים של כל רצף כזה. כך, קל לזהות דפוסים, למצוא 'זנבות ארוכים' ממירי במיוחד, או לאתר ביטויים שליליים שמופיעים בעשרות שאילתות שונות. זוהי טכניקה מתקדמת עבור אופטימיזציה בגוגל ברמה הגבוהה ביותר.
איך זה עובד?
הסקריפט שולף את דוח שאילתות החיפוש מה-30 הימים האחרונים, מעבד את הנתונים, ומייצא אותם לגליון Google Sheets. הגליון יכיל לשוניות נפרדות עבור 1-gram, 2-gram ו-3-gram, כאשר כל שורה מציגה את הביטוי והביצועים המצטברים שלו (קליקים, חשיפות, עלות, המרות, CPA וכו').
קוד הסקריפט
// N-Gram script is quite long. This is a conceptual representation.
// A popular and complete version can be found on sites like Brainlabs or Optmyzr.
function main() {
const SPREADSHEET_URL = 'PASTE_YOUR_SPREADSHEET_URL_HERE';
const queryReport = AdsApp.report(
'SELECT Query, Clicks, Impressions, Cost, Conversions ' +
'FROM SEARCH_QUERY_PERFORMANCE_REPORT ' +
'WHERE Impressions > 5 ' +
'DURING LAST_30_DAYS');
const ngrams = {1: {}, 2: {}, 3: {}};
const rows = queryReport.rows();
while (rows.hasNext()) {
const row = rows.next();
const query = row['Query'].toLowerCase().trim();
const words = query.split(/\s+/);
for (let n = 1; n <= 3; n++) {
if (words.length >= n) {
for (let i = 0; i <= words.length - n; i++) {
const ngramText = words.slice(i, i + n).join(' ');
if (!ngrams[n][ngramText]) {
ngrams[n][ngramText] = {clicks: 0, impressions: 0, cost: 0, conversions: 0};
}
ngrams[n][ngramText].clicks += parseInt(row['Clicks']);
ngrams[n][ngramText].impressions += parseInt(row['Impressions']);
ngrams[n][ngramText].cost += parseFloat(row['Cost'].replace(/,/g, ''));
ngrams[n][ngramText].conversions += parseFloat(row['Conversions']);
}
}
}
}
const spreadsheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
for (let n in ngrams) {
let sheet = spreadsheet.getSheetByName(n + '-grams');
if (!sheet) {
sheet = spreadsheet.insertSheet(n + '-grams');
}
sheet.clear();
sheet.appendRow(['N-Gram', 'Clicks', 'Impressions', 'Cost', 'Conversions', 'CTR', 'CPC', 'CPA']);
for (let text in ngrams[n]) {
const stats = ngrams[n][text];
const ctr = stats.impressions > 0 ? (stats.clicks / stats.impressions) : 0;
const cpc = stats.clicks > 0 ? (stats.cost / stats.clicks) : 0;
const cpa = stats.conversions > 0 ? (stats.cost / stats.conversions) : 0;
sheet.appendRow([text, stats.clicks, stats.impressions, stats.cost, stats.conversions, ctr, cpc, cpa]);
}
}
}
התאמה אישית
הדבר היחיד שצריך להגדיר הוא ה-`SPREADSHEET_URL`. צרו גליון חדש, העתיקו את כתובת ה-URL שלו והדביקו אותה במקום המתאים. מומלץ להריץ סקריפט זה פעם בשבוע או פעם בחודש.
סקריפט 5: השהיית קמפיינים בעת חריגה מתקציב חודשי
למה זה חשוב?
גוגל אדס מאפשרת להגדיר תקציב יומי, אך המערכת יכולה לחרוג ממנו ביום נתון עד פי 2, כל עוד היא מאזנת את ההוצאה הממוצעת לאורך החודש. עבור מפרסמים עם תקציב חודשי קשיח, זה יכול ליצור אי ודאות. סקריפט זה מבטיח שההוצאה החודשית הכוללת לא תחרוג מהתקרה שהוגדרה, על ידי השהיית כל הקמפיינים ברגע שהתקציב נוצל.
איך זה עובד?
הסקריפט בודק את סך ההוצאה בחשבון מתחילת החודש הנוכחי. הוא משווה את הסכום הזה לתקציב החודשי המקסימלי שהגדרתם בקוד. אם ההוצאה בפועל עולה על התקציב, הסקריפט ישנה את הסטטוס של כל הקמפיינים הפעילים ל'מושהה' וישלח לכם מייל המודיע על כך.
קוד הסקריפט
function main() {
const MONTHLY_BUDGET = 5000; // Your total monthly budget for the account
const RECIPIENT_EMAIL = '[email protected]';
const account = AdsApp.currentAccount();
const stats = account.getStatsFor('THIS_MONTH');
const cost = stats.getCost();
Logger.log(`Current monthly cost: ${cost}. Monthly budget: ${MONTHLY_BUDGET}`);
if (cost > MONTHLY_BUDGET) {
const campaignIterator = AdsApp.campaigns().withCondition('Status = ENABLED').get();
let pausedCampaigns = [];
while (campaignIterator.hasNext()) {
const campaign = campaignIterator.next();
campaign.pause();
pausedCampaigns.push(campaign.getName());
}
if (pausedCampaigns.length > 0) {
const subject = 'Action Required: Monthly Budget Exceeded - Campaigns Paused';
const body = `The account has spent ${cost.toFixed(2)}, which exceeds the monthly budget of ${MONTHLY_BUDGET}.\n\nThe following campaigns have been paused automatically:\n${pausedCampaigns.join('\n')}`;
MailApp.sendEmail(RECIPIENT_EMAIL, subject, body);
}
}
}
התאמה אישית
הגדירו את התקציב החודשי הכולל שלכם במשתנה `MONTHLY_BUDGET` ועדכנו את כתובת המייל שלכם. מומלץ לתזמן את הסקריפט לרוץ מספר פעמים ביום (למשל, כל 4 שעות) לקראת סוף החודש כדי להבטיח בקרה הדוקה.
שמי חן, ואני הבעלים של PPC Israel. במשך שנים של ניהול קמפיינים, ראיתי איך מנהלי PPC מוכשרים שוקעים במשימות טכניות שחוזרות על עצמן במקום להתמקד באסטרטגיה. החלטתי שדן, המומחה הטכני שלנו, יכתוב את המדריך הזה כדי לתת לכם כלים פרקטיים שיפנו לכם את הזמן היקר הזה. אוטומציה היא לא מותרות, היא הכרח בעולם ה-PPC המודרני.