logo

077-9978050

שיפור קמפיינים בגוגל באמצעות כללים, ניסויים וסקריפטים

כללים ניסויים וסקריפטים - איך אפשר לשפר את הקמפיינים שלכם בגוגל באופן אוטומי באמצעות סקריפטים?

בכנס Update Upgrade 2019 אבישי פרוינד נתן הרצאה על איך נוכל לשפר את הקמפיינים שלנו בגוגל באופן אוטומטי. באמצעות כללים, ניסויים וסקריפטים נוכל למקסם את התוצאות שלנו. כל הפרטים בהמשך.

כללים אוטומטיים

נקרא גם חוקים / פעולות גורפות, מטרתם לבצע פעולות מסוימות באופן אוטומטי, בתקופת זמן שהגדרנו, נניח פעם ביום / בשבוע / יום בחודש.

דוגמאות:

כאשר עלות הקמפיין הגיעה החודש ל-6000 ₪, עצור פרסום

לשלוח מייל כל בוקר עם ביטוי חיפוש שיש לו ציון איכות נמוך מ-3.

אז איך נבצע זאת?

– להכנס לרמת קמפיינים / קבוצות / מילות מפתח

– לסמן את הרצוי (קמפיין, קבוצת מודעות, ביטויי מפתח – ניתן לבחור אחד או יותר)

– ללחוץ על "עוד" (שלושת הנקודות):

כללים אוטומטיים

– ללחוץ על יצירת כלל אוטומטי:

יצירת כלל אוטומטי

דוגמא ראשונה

– כל יום בשש בבוקר יופעל הכלל – אם קמפיין X הוציא 6,000 ש"ח עד היום -> נעצור את הקמפיין.

יצירת כלל חדש לקמפיינים

מה בחרנו?

– בחרנו השהיית קמפיין

– ניתן לבחור איזה קמפיין שנרצה

– נקבע את התנאי

– נקבע את תדירות הפעולה ואת תקופת הייחוס

החל על קמפיינים

דוגמא שניה

– לשלוח מייל כל בוקר עם כל ביטויי המפתח שיש להם ציון איכות נמוך מ-3.

– נכנס למילות המפתח.

– נבחר בשליחת מייל.

על אילו מילות מפתח ליישם את הכלל
מילות מפתח


ניסויים

– כיום גוגל משחרר לנו שלל הצעות לניהול החשבון.

– כדי לעבור מאסטרטגיה לאסטרטגיה יש להיכנס בתפריט:

"קמפיין", משם ל"הגדרות", משם ל"הצעת המחיר שלך":

מקסימום המרות

 

איך מפעילים ניסוי?

קודם כל יוצרים טיוטה, לאחר מכן מגדירים את הניסוי, ואז את ההחלטה:

שלב א':

– בתחתית התפריט יש לבחור בטיוטות וניסויים

– במסך שהתקבל יש להוסיף טיוטה חדשה

איך מפעילים ניסוי?

– לתת שם לטיוטה ולשמור:

טיוטה חדשה

– בתפריט למטה תופיע הטיוטה.

– יש לבחור (לעמוד עליה), ולבחור שוב טיוטות וניסויים.

– לבחור ניסוי חדש.

ניסוי חדש

 

שלב ב' – יצירת הניסוי:

– כעת נמלא את הפרטים.

– במקור אסטרטגיית הקמפיין הייתה עלות ידנית לקליק, אני רוצה לבחון מעבר לאסטרטגיה יעד להמרה.

– הניסוי יתבצע על חצי מהתנועה.

– הניסוי יערך כשבועיים (5/2 עד ל22/3).

– יש לשמור.

יצירת הניסוי

– יש לחבר הקמפיין

חיבור הקמפיין

– הניסוי החל:

Picture3
יצירת הניסוי

הערות:

– ניתן לעצור את הניסוי בכל עת.

– אם הניסוי הצליח ולא רוצים לחכות ניתן להחיל את הנסוי.

ניסוי


סקריפטים

מה זה סקריפט בעצם?

– סקריפט הינו קטע קוד שמבצע פעולה אוטומטית, יש הרבה סקריפטים שניתן להוריד מהאינטרנט.

– הסקריפט נמצא על גבי שרתי גוגל.

– הסקריפט יכול לפעול על חשבון, או על כל ה-MCC שלכם

התקנת סקריפט ברמת חשבון

כל הקמפיינים

 

הסקריפט הראשון:

– הסקריפט מנטר מודעות פעילות ובודק את הססטוס שלהם, במידה והלינק שבור – שולח דו"ח + אפשרות לעצירה מיידית.

– שם הסקריפט: (R) Ads Final URL Monitor (Pause + Report).

– שני פרמטרים: 

1. מייל אליו יישלח הדו"ח

2. האם לעצור מודעות או לא (רק דו"ח)

– סקריפט ברמת חשבון.

הערה: בשלב מסוים תתבקשו לאשר הרשאות.

 

ניתן להעתיק את הסקריפט מפה:


var EMAIL = '[email protected]';
var PAUSE = false;

function main(){  
  var htmlService = HTMLBuilderService();
  
  var ads = AdWordsApp.ads()
  .withCondition('CampaignStatus = ENABLED')
  .withCondition('AdGroupStatus = ENABLED')
  .withCondition('Status = ENABLED')
  .withCondition('Type NOT_IN [CALL_ONLY_AD]') // IMAGE_AD, MOBILE_AD, MOBILE_IMAGE_AD, PRODUCT_AD, RICH_MEDIA_AD, TEMPLATE_AD, TEXT_AD, CALL_ONLY_AD
  .withLimit(4)
  .get();
  
  Logger.log('%s ads found.', ads.totalNumEntities());
  
  var matches = 0;  
  while(ads.hasNext()){
    var ad = ads.next();      
    var adURL = ad.urls().getFinalUrl();
    var adHeader = ad.getHeadline();
    var adType = ad.getType();
    
    Logger.log('ad: %s (%s)', adHeader, adType);
    
    var statusCode = -1;
    try{
      var response = UrlFetchApp.fetch(adURL, { muteHttpExceptions: true });
      statusCode = response.getResponseCode();      
      Logger.log('[status %s] %s', statusCode, adURL);      
    }
    catch(e){
      Logger.log('[exception %s] %s', e.message, adURL);      
    }
    
    // OK
    if(statusCode == 200 || statusCode == -1) 
      continue;    
    
    var adgroup = ad.getAdGroup();
    var adgroupName = adgroup.getName();
    
    Logger.log('adgroup: %s', adgroupName);
    Logger.log('%s [%s]', adURL, statusCode);    
    
    matches++;
    
    htmlService.add(
      '

statusCode: ' + statusCode +'

' + '
adGroup: ' + adgroupName +'
' + '

adURL: ' + adURL + '

' ); if(PAUSE) { Logger.log('ad paused'); ad.pause(); } } if(matches > 0){ MailApp.sendEmail(EMAIL, 'Ad Monitor', '', { htmlBody: htmlService.get() }); } } var HTMLBuilderService = function(){ var _html = ''; return { add: function(content){ _html += content; }, get: function(){ return _html; } }; }

תנו שם לסקריפט, תנו הרשאות, והדביקו את הסקריפט:

שם הסקריפט

תרשמו את המייל שלכם והאם לעצור או לא לעצור:

תרשמו את המייל שלכם והאם לעצור או לא לעצור

תלחצו על הסקריפטים, תבחרו את התדירות של ההפעלת הסקריפט

סקריפטים

אתם יכולים לראות בהיסטורית הסקריפטים, מתי הסקריפט פעל ואיזה פעולה הוא עשה:

היסטוריית סקריפטים

סקריפט שני – דיווח חודשי:

– שם הסקריפט: (R) Account Daily Stats + Charts – Current Month)

– מטרת הסקריפט: ליצור אקסל יפה ובו גרפים.

– הסקריפט מייצר קובץ גוגל שיט בתוך הדרייב.

– בראש הסקריפט שם הקובץ שאתם מעוניינים.

– אם לא קיים קובץ, הסקריפט מייצר באופן אוטומטי, אם קיים קובץ, הסקריפט מעדכן.

– הסקריפט ברמת חשבון.

 

ניתן להעתיק את הסקריפט מפה:


var SPREADSHEET = 'AccountDailyStats';

function main() {  
  var sheetService = SpreadsheetLoader.loadSheetService(SPREADSHEET);
  if(!sheetService) // create the sheet 
    sheetService = SpreadsheetLoader.createSheetService(SPREADSHEET);
  
  sheetService.clear();
  
  Logger.log('Loading "%s" Account Statistics ...', AdWordsApp.currentAccount().getName());
  var report = AdWordsApp.report(
     'SELECT Date, Impressions, Clicks, ConversionRate, Cost ' +
     'FROM   ACCOUNT_PERFORMANCE_REPORT ' +
     'DURING THIS_MONTH');
  
  report.exportToSheet(sheetService.sheet);
  sheetService.sort(1);
  
  SetTotals(sheetService);    
  
  if(!sheetService.hasCharts)
    DrawChart(sheetService);  
  
  Logger.log('Done!');
}

function SetTotals(sheetService){
  
  // TOTALS (using formulas)
  Logger.log('Setting formulas ...');
  
  var lastRowIndex = sheetService.getLastRowIndex();  
  var totalRowIndex = (parseInt(lastRowIndex) + 1).toString();
  
  sheetService.setCellSumFormula('B2:B'.concat(lastRowIndex), 'B'.concat(totalRowIndex));
  sheetService.setCellSumFormula('C2:C'.concat(lastRowIndex), 'C'.concat(totalRowIndex));
  sheetService.setCellAvgFormula('D2:D'.concat(lastRowIndex), 'D'.concat(totalRowIndex));
  sheetService.setCellSumFormula('E2:E'.concat(lastRowIndex), 'E'.concat(totalRowIndex));
  sheetService.setDataUI('A'.concat(totalRowIndex, ':E', totalRowIndex), '#F5F6F9', '#000000', 20, 'center');   
}

function DrawChart(sheetService){
  Logger.log('Drawing Chart ... ');
     
  var lastRowIndex = sheetService.getLastRowIndex();
  
  // arrRanges, vAxisDataLeft, vAxisDataRight, width, height, rowPosition, columnPosition, chartTitle 
  // vAxisData: { title, ticks, color, legend }
  sheetService.addLineChartDualY(
    ['A2:A'.concat(lastRowIndex), 'B2:B'.concat(lastRowIndex), 'C2:C'.concat(lastRowIndex)],
    { 
      title: 'impressions',
      color:'#4572A7', 
      legend:'impressions'
    },
    { 
      title: 'clicks',       
      color:'#AA4643', 
      legend:'clicks'
    },   
    700, 160, 3, 7, // chart location - row 3, column 7
    'impressions vs clicks'
  ); 
  
  sheetService.addLineChartDualY(
    ['A2:A'.concat(lastRowIndex), 'D2:D'.concat(lastRowIndex), 'C2:C'.concat(lastRowIndex)],
    { 
      title: 'conv.Rate',
      color:'#4572A7', 
      legend:'conv.Rate'
    },
    { 
      title: 'clicks',       
      color:'#AA4643', 
      legend:'clicks'
    },  
    700, 160, 11, 7, // chart location - row 10, column 7
    'conv.Rate vs clicks'
  ); 
  
  sheetService.addLineChartDualY(
    ['A2:A'.concat(lastRowIndex), 'E2:E'.concat(lastRowIndex), 'C2:C'.concat(lastRowIndex)],
    { 
      title: 'cost',
      color:'#4572A7', 
      legend:'cost'
    },
    { 
      title: 'clicks',       
      color:'#AA4643', 
      legend:'clicks'
    },
    700, 160, 19, 7, // chart location - row 17, column 7
    'cost vs clicks'
  ); 
}

/* SPREADSHEET SERVICE */
var SpreadSheetService = function(spreadSheet) {
  var _spreadSheet = spreadSheet;
  var _sheets = [];

  (function(){
    var sheetServices = [];
    var temp_sheets = spreadSheet.getSheets();
    for(var i= 0; i  0,
     findColumnValuesByFilter: function(columnPosition, filterValue, filterColumnPosition){
       /* 
          get column values filtered by other column
          
          e.g: findColumnValuesByFilter(2, '100', 1)          
          all B column values that the value in A column equals to '100'
       */

       var result = [];       
       var rows = _sheet.getDataRange().getValues();
 
       for(row in rows)
         if(rows[row][filterColumnPosition - 1] == filterValue)
           result.push(rows[row][columnPosition]);
       return result;  
     }, 
     clear: function(charts, format, contents){
       charts = charts || false;
       format = format || false;
       contents = contents || true;
       
       if(!charts) return; 
       
       // clear all charts
       _sheet.clear({ formatOnly: format, contentsOnly: contents });        
       var charts = _sheet.getCharts();
       for (var i in charts)
         _sheet.removeChart(charts[i]);
     },          
     setValue: function(rowPosition, columnPosition, value){ 
       _sheet.getRange(rowPosition, columnPosition).setValue(value);
     },     
     setRangeValue: function(strRange, value){ 
       // e.g: setCurrencyFormat('A1'); // set cell
       _sheet.getRange(strRange).setValue(value);
     },
     setDataUI: function(strRange, backgroundColor, foreColor, fontSize, align){
       var range = _sheet.getRange(strRange);
       if(backgroundColor)
           range.setBackground(backgroundColor);
       if(foreColor)
           range.setFontColor(foreColor);
       if(fontSize)
           range.setFontSize(fontSize);
       if(align)
         range.setHorizontalAlignment(align);
     }, 
     setNumberFormat: function(strRange){
       setFormat(strRange, '0');       
     },
     setDecimalFormat: function(strRange){
       setFormat(strRange, '0.00');
     },
     setCurrencyFormat: function(strRange){
       // e.g: setCurrencyFormat('A1'); // set cell
       // e.g: setCurrencyFormat('A1:A10'); // set range
       
       setFormat(strRange, '$0.00');
     },
     setCellSumFormula: function(strRange, strCell){
       // e.g: setCellSumFormula('A1:A10', 'B1'); 
       // set SUM value of cells A1 to A10 to cell B1
       
       var cell = _sheet.getRange(strCell);
       cell.setFormula('=SUM(' + strRange + ')');
     },
     setCellAvgFormula: function(strRange, strCell){
       // e.g: setCellSumFormula('A1:A10', 'B1'); 
       // set AVG value of cells A1 to A10 to cell B1
       
       var cell = _sheet.getRange(strCell);
       cell.setFormula('=AVERAGE(' + strRange + ')');
     }       
   }; 
}

/* SPREADSHEET LOADER */
var SpreadsheetLoader = {
  createSpreadSheet: function(spreadSheetName, folderName){
    Logger.log('CREATING %s ... ', spreadSheetName);
    var spreadsheet = SpreadsheetApp.create(spreadSheetName); // create new file         
    
    if(!folderName || folderName == '') 
      return spreadsheet; // folder not specified  - return spreadsheet
     
    // save in specific folder 
    
    for(var i=0;i

 

סקריפט שלישי – טיפול במודעות לא ממירות:

– שם הסקריפט: R) Pause Non Converting or High Cost Ads)

– מטרת הסקריפט: לעצור מודעות שלא ממירות או בעלות המרה גבוהה.

– סקריפט ברמת חשבון.

 

ניתן להעתיק את הסקריפט מפה:


    var PERIOD = 'ALL_TIME'; // ALL_TIME, LAST_30_DAYS

function main() {
  HandleNonConvertingAds();
  HandleConvertingAds();
}

function HandleNonConvertingAds(){ 
  Logger.log('## Non Converting Ads ##')
  var ads = AdWordsApp.ads()
     .withCondition('ConvertedClicks = 0')
     .withCondition('Status = ENABLED')
     .withCondition('Cost > 0')  
     .forDateRange(PERIOD)
     .orderBy('Cost ASC')
     .get();
  
  while (ads.hasNext()) {
    var ad = ads.next();
    var adGroup = ad.getAdGroup();
    var adGroupCPA = GetAdGroupCPA(adGroup);
    var adCost = ad.getStatsFor(PERIOD).getCost();
    
    Logger.log('ad: %s -> cost %s', ad.getHeadline(), adCost);
    Logger.log('adGroup %s -> CPA %s', adGroup.getName(), adGroupCPA);
        
    if(adGroupCPA == null || adCost  0')
     .withCondition('Status = ENABLED')
     .withCondition('Cost > 0')  
     .forDateRange(PERIOD)
     .orderBy('ConvertedClicks DESC')
     .get();
  
  while (ads.hasNext()) {
    var ad = ads.next();
    var adGroup = ad.getAdGroup();
    var adGroupCPA = GetAdGroupCPA(adGroup);
    var stats = ad.getStatsFor(PERIOD);
    var adCPA = stats.getCost() / stats.getConvertedClicks(); // calculate the ad "CPA" - cost per converted
    
    Logger.log('ad: %s -> Conversions %s, CPA %s', ad.getHeadline(), stats.getConvertedClicks(), adCPA)
    Logger.log('adGroup %s -> CPA %s', adGroup.getName(), adGroupCPA);
        
    if(adGroupCPA == null || adCPA 

סקריפט רביעי – מילות מפתח חבויות:

– שם הסקריפט: (R) queries 2 keywords – mcc (set)

– מטרת הסקריפט: לקחת מילות מפתח שיבצעו המרה בפועל אך לא מופיעות בפועל.

– הסבר: ביטוח המפתח המקורי היה ביטוי בפרייז או BMM.

– סקריפט ברמת MCC.

 

ניתן להעתיק את הסקריפט מפה:


function main() {
  var accounts = MccApp.accounts().get();

  while (accounts.hasNext()) {
    var account = accounts.next();
    var accountName = account.getName() ? account.getName() : '--';
    Logger.log('account #%s %s', account.getCustomerId(), accountName);

    MccApp.select(account); 
    execute();    
  }
}

function execute() {
  var report = AdWordsApp.report(
   'SELECT Query,Clicks,ConvertedClicks,AverageCpc ' +
   'FROM SEARCH_QUERY_PERFORMANCE_REPORT ' +
   'WHERE ConvertedClicks > 0 ' + 
   'DURING 20000101,' + dateFormat(new Date()));
 
  var rows = report.rows();  
  while(rows.hasNext()) {
    var row = rows.next();
    
    var clicks = row['Clicks'];
    var conversions = row['ConvertedClicks'];

    var query = row['Query'];
    //Logger.log(query + ' ' + clicks);
    var found_in_my_keywords = AdWordsApp.keywords().withCondition('Text CONTAINS "' + query + '"').get().hasNext();
    if(found_in_my_keywords)
    {
      Logger.log('"' + query + '" found in my keywords');
      continue;
    }
    
    var adGroup = AdWordsApp.adGroups().get().next();
    var maxcpc = row['AverageCpc'];
    
    if(!AdWordsApp.getExecutionInfo().isPreview())
      adGroup.createKeyword(query, maxcpc);
    Logger.log('"' + query + '" added as keyword with maxcpc ' + maxcpc)
  }
}

function dateFormat(date){
  var year = date.getFullYear().toString();
  var month = date.getMonth().toString();
  var day = date.getDate().toString();
  
  if(month.length == 1) month = '0' + month; // return yyyyMMdd
  if(day.length == 1) day = '0' + day;
  
  return year + month + day;
}
    

דוגמאות נוספות

– אתר מסחר אלקטרוני, ניטור המודעות הפעילות ועצירת המודעה כאשר המכירה הסתיימה – קריאת נתונים מתוך הHTML

– ניהול קמפיין מלא על בסיס פיד (אקסל או XML או גייסון) החל מיצירת המודעה חדשה כאשר מוצר חדש לדוגמא: "רק היום המוצר X בהנחה", הפסקת המודעה כאשר אין במלאי, עדכון מחיר בתוך המודעה

– ניהול תקציב כדי שתגיע בדיוק לתקציב שהוגדר, לא פחות ולא יותר.

– הזרקה של נתונים לתוך מודעות

– מערכת התרעות לבעיות בקמפיינים

סיכום

מטרת הכללים הניסויים והסקריפטים הם לעזור לנו לנהל את החשבון בצורה אוטומטית ולייצר תהליכי עבודה שישפרו לנו את הביצועים, אני ממליץ לכל אחד להשתמש בכללים בשביל פעולות אוטומטיות, בניסויים בשביל לנסות דברים חדשים בלי לפגוע בביצועים, ובסקריפטים בשביל מקרים שאין כללים מתאימים
 

אבישי פרוינד

  • מנהל ובעלים של לוגוס שיווק באינטרנט
  • מומחה לשיווק, פרסום וקידום ברשת
  • מייעץ ומלווה גופים מוסדיים וגורמים פרטיים בכל הקשור למדיום האינטרנטי
  • מקצוען מוסמך ע"י גוגל Google Advertising Professional
  • מרצה בכיר באוניברסיטאות ומכללות העוסק בהוראת השיווק באינטרנט וטכנולוגיות WEB
  • משמש כמומחה מטעם בית המשפט לתחום הפרסום והשיווק.
  • מוסמך במנהל עסקים MBA ביה"ס לניהול של הפקולטה להנדסה, אוניברסיטת בן גוריון, באר שבע
אבישי פרוינד

פוסטים נוספים:

spin-to-win
galgla