אופטימיזציה של שאילתות חיפוש – חשבון יחיד

סמל הדוחות

הסקריפט משווה בין הביצועים של מונחי החיפוש בדוח תצוגת מונחי החיפוש לבין ערכי הסף שאתם מספקים כדי ליצור רשימות של מילות מפתח חיוביות ושליליות (בהתאמה מדויקת).

איך זה עובד

כדי להכיר איך פועל הדיווח בסקריפטים של Google Ads, אפשר לעיין במדריך הייעודי לדיווח ובדף הדוגמאות לדיווח.

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

הסקריפט גם מחפש מילות מפתח עם שיעור קליקים גבוה ועם עלות נמוכה להמרה, ומוסיף אותן כמילות מפתח חיוביות.

הגדרה

  • יש ליצור סקריפט חדש עם קוד המקור שלמטה.
  • כשפותחים תצוגה מקדימה, סביר להניח שהסקריפט יושלם תוך 30 שניות. אם לא, נסו לשנות את התנאי DURING LAST_7_DAYS ל-DURING YESTERDAY.
  • בסיום הסקריפט בתצוגה המקדימה, מוצגת רשימה של מילות מפתח שיתווספו כמילות מפתח שליליות (ובמקרים מסוימים, כחיוביות).

קוד מקור

// Copyright 2015, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @name Search Query Report
 *
 * @overview The Search Query Report script uses the Search Query Performance
 *     Report to find undesired search terms and add them as negative (or
 *     positive) exact keywords. See
 *     https://developers.google.com/google-ads/scripts/docs/solutions/search-query
 *     for more details.
 *
 * @author Google Ads Scripts Team [adwords-scripts@googlegroups.com]
 *
 * @version 2.0
 *
 * @changelog
 * - version 2.0
 *   - Updated to use new Google Ads scripts features.
 * - version 1.0.1
 *   - Upgrade to API version v201609.
 * - version 1.0
 *   - Released initial version.
 */

// Minimum number of impressions to consider "enough data"
const IMPRESSIONS_THRESHOLD = 100;
// Cost-per-click (in account currency) we consider an expensive keyword.
const AVERAGE_CPC_THRESHOLD = 1; // $1
// Threshold we use to decide if a keyword is a good performer or bad.
const CTR_THRESHOLD = 0.5; // 0.5%
// If ctr is above threshold AND our conversion cost isn’t too high,
// it’ll become a positive keyword.
const COST_PER_CONVERSION_THRESHOLD = 10; // $10

/**
 * Configuration to be used for running reports.
 */
const REPORTING_OPTIONS = {
  // Comment out the following line to default to the latest reporting version.
  apiVersion: 'v11'
};

function main() {
  const report = AdsApp.report(
      `SELECT search_term_view.search_term, ` +
      `metrics.clicks, ` +
      `metrics.cost_micros, ` +
      `metrics.ctr, ` +
      `metrics.conversions_from_interactions_rate, ` +
      `metrics.cost_per_conversion, ` +
      `metrics.conversions, ` +
      `campaign.id, ` +
      `ad_group.id ` +
      `FROM search_term_view ` +
      `WHERE metrics.conversions > -1 ` +
      `AND metrics.impressions > ${IMPRESSIONS_THRESHOLD} ` +
      `AND metrics.average_cpc > ${AVERAGE_CPC_THRESHOLD} ` +
      `AND segments.date DURING LAST_7_DAYS`, REPORTING_OPTIONS);

  const rows = report.rows();
  const negativeKeywords = {};
  const positiveKeywords = {};
  const allAdGroupIds = {};
  // Iterate through search query and decide whether to
  // add them as positive or negative keywords (or ignore).
  for (const row of rows) {
    if (parseFloat(row['metrics.ctr*100%']) < CTR_THRESHOLD) {
      addToMultiMap(negativeKeywords, row['ad_group.id'],
                    row['search_term_view.search_term']);
      allAdGroupIds[row['ad_group.id']] = true;
    } else if (parseFloat(row['metrics.cost_per_conversion']) <
        COST_PER_CONVERSION_THRESHOLD ||
        !(parseFloat(row['metrics.cost_per_conversion']))) {
        addToMultiMap(positiveKeywords, row['ad_group.id'],
                    row['search_term_view.search_term']);
        allAdGroupIds[row['ad_group.id']] = true;
    }
  }

  // Copy all the adGroupIds from the object into an array.
  const adGroupIdList = [];
  for (const adGroupId in allAdGroupIds) {
    adGroupIdList.push(adGroupId);
  }

  // Add the keywords as negative or positive to the applicable ad groups.
  const adGroups = AdsApp.adGroups().withIds(adGroupIdList).get();
  for (const adGroup of adGroups) {
    if (negativeKeywords[adGroup.getId()]) {
      for (const negativeKeyword of negativeKeywords[adGroup.getId()]) {
        adGroup.createNegativeKeyword(`[${negativeKeyword}]`);
      }
    }
    else if (positiveKeywords[adGroup.getId()]) {
      for (const positiveKeyword of positiveKeywords[adGroup.getId()]) {
        adGroup.newKeywordBuilder()
            .withText(`[${positiveKeyword}]`)
            .build();
      }
    }
  }
}

function addToMultiMap(map, key, value) {
  if (!map[key]) {
    map[key] = [];
  }
  map[key].push(value);
}