روال‌های مطلوب

این صفحه روال‌های مطلوب مختلفی را برای توسعه با جاوااسکریپت Google Ads پوشش می‌دهد.

گزینشگرها

فیلتر کردن با انتخابگرها

درصورت امکان، از فیلترها برای درخواست فقط نهادهای موردنیازتان استفاده کنید. اعمال فیلترهای مناسب مزایای زیر را دارد:

  • کد ساده‌تر و درک آن آسان‌تر است.
  • دستورات بسیار سریع‌تر اجرا خواهد شد.

تکه‌کدهای زیر را مقایسه کنید:

رویکرد کدنویسی تکه‌کد
فیلتر کردن بااستفاده از انتخابگرها (توصیه‌شده)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 10')
    .forDateRange('LAST_MONTH')
    .get();
while (keywords.hasNext()) {
  var keyword = keywords.next();
  // Do work here.
}
فیلتر کردن در کد (توصیه نمی‌شود)
var keywords = AdsApp.keywords().get();

while (keywords.hasNext()) {
  var keyword = keywords.next();
  var stats = keyword.getStatsFor(
      'LAST_MONTH');
  if (stats.getClicks() > 10) {
    // Do work here.
  }
}

رویکرد دوم توصیه نمی‌شود زیرا تلاش می‌کند فهرست همه کلیدواژه‌های موجود در حسابتان را بازیابی کند تا فیلتری را روی فهرست اعمال کند.

از پیمایش سلسله‌مراتب پویش اجتناب کنید

وقتی می‌خواهید نهادها را در سطح خاصی بازیابی کنید، به‌جای پیمایش کل سلسله‌مراتب پویش، از روش مجموعه در آن سطح استفاده کنید. علاوه‌بر ساده‌تر بودن، این کار عملکرد بسیار بهتری نیز خواهد داشت: سیستم مجبور نخواهد بود همه پویش‌ها و گروه‌های آگهی را به‌طور غیرضروری بخواند.

تکه‌کدهای زیر را که همه آگهی‌های حسابتان را بازیابی می‌کنند مقایسه کنید:

رویکرد کدنویسی تکه‌کد
استفاده از روش جمع‌آوری مناسب (توصیه‌شده)

var ads = AdsApp.ads();

پیمایش سلسله‌مراتب (توصیه نمی‌شود)
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
  var adGroups = campaigns.next().
      adGroups().get();
  while (adGroups.hasNext()) {
    var ads = adGroups.next().ads().get();
    // Do your work here.
  }
}

رویکرد دوم توصیه نمی‌شود زیرا تلاش می‌کند کل سلسله مراتب اشیا (پویش‌ها، گروه‌های آگهی) را واکشی کند درحالی‌که فقط آگهی‌ها موردنیاز است.

استفاده از روش‌های دسترسی ولی خاص

گاهی اوقات لازم است نهاد اصلی شیء بازیابی‌شده را دریافت کنید. در این مورد، باید به‌جای واکشی کل سلسله‌مراتب، از روش دستیاب ارائه‌شده استفاده کنید.

تکه‌کدهای زیر را که گروه‌های آگهی را بازیابی می‌کنند مقایسه کنید که آگهی‌های نوشتاری با بیش‌از ۵۰ کلیک در ماه گذشته دارند:

رویکرد کدنویسی تکه‌کد
از روش دستیاب والد مناسب استفاده کنید (توصیه‌شده)
var ads = AdsApp.ads()
    .withCondition('Clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();

while (ads.hasNext()) {
  var ad = ads.next();
  var adGroup = ad.getAdGroup();
  var campaign = ad.getCampaign();
  // Store (campaign, adGroup) to an array.
}
پیمایش سلسله‌مراتب (توصیه نمی‌شود)
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
  var adGroups = campaigns.next()
      .adGroups()
      .get();
  while (adGroups.hasNext()) {
    var ads = adGroups.ads()
       .withCondition('Clicks > 50')
       .forDateRange('LAST_MONTH')
       .get();
    if (ads.totalNumEntities() > 0) {
      // Store (campaign, adGroup) to an array.
    }
  }
}

رویکرد دوم توصیه نمی‌شود زیرا کل سلسله‌مراتب پویش و گروه آگهی را در حسابتان واکشی می‌کند، درحالی‌که شما فقط به زیرمجموعه‌ای از پویش‌ها و گروه‌های آگهی نیاز دارید که با مجموعه آگهی‌هایتان مرتبط است. رویکرد اول خود را به واکشی کردن فقط مجموعه آگهی‌های مربوط محدود می‌کند و از روشی مناسب برای دسترسی به اشیای والد آن استفاده می‌کند.

استفاده از فیلترهای خاص والدین

برای دسترسی به نهادها در یک پویش یا گروه آگهی خاص، به‌جای واکشی و سپس پیمایش ازطریق سلسله‌مراتب، از فیلتر خاصی در انتخابگر استفاده کنید.

تکه‌کدهای زیر را که فهرست آگهی‌های نوشتاری را در پویش و گروه آگهی مشخصی که ماه گذشته بیش‌از ۵۰ کلیک داشته‌اند بازیابی می‌کنند مقایسه کنید.

رویکرد کدنویسی تکه‌کد
استفاده از فیلترهای مناسب سطح والدین (توصیه‌شده)
var ads = AdsApp.ads()
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .withCondition('Clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();

while (ads.hasNext()) {
  var ad = ads.next();
  var adGroup = ad.getAdGroup();
  var campaign = ad.getCampaign();
  // Store (campaign, adGroup, ad) to
  // an array.
}
پیمایش سلسله‌مراتب (توصیه نمی‌شود)
var campaigns = AdsApp.campaigns()
    .withCondition('Name = "Campaign 1"')
    .get();

while (campaigns.hasNext()) {
  var adGroups = campaigns.next()
      .adGroups()
      .withCondition('Name = "AdGroup 1"')
      .get();
  while (adGroups.hasNext()) {
    var ads = adGroups.ads()
       .withCondition('Clicks > 50')
       .forDateRange('LAST_MONTH')
       .get();
    while (ads.hasNext()) {
      var ad = ads.next();
      // Store (campaign, adGroup, ad) to
      // an array.
    }
  }
}

رویکرد دوم توصیه نمی‌شود زیرا سلسله‌مراتب پویش و گروه آگهی را در حسابتان تکرار می‌کند، درحالی‌که فقط به مجموعه انتخابی از آگهی‌ها و پویش‌ها و گروه‌های آگهی والد آن‌ها نیاز دارید. رویکرد اول تکرار را به فهرست آگهی‌ها محدود می‌کند، با اعمال فیلتر خاصی برای نهادهای والد در انتخابگر.

درصورت امکان، از شناسه‌ها برای فیلتر کردن استفاده کنید

هنگام فیلتر کردن برای نهادها، بهتر است نهادها را براساس شناسه‌هایشان فیلتر کنید نه براساس فیلدهای دیگر.

تکه‌کدهای زیر را که پویشی را انتخاب می‌کنند درنظر بگیرید.

رویکرد کدنویسی تکه‌کد
فیلتر کردن براساس شناسه (توصیه‌شده)
var campaign = AdsApp.campaigns()
    .withIds([12345])
    .get()
    .next();
فیلتر براساس نام (کمتر بهینه)
var campaign = AdsApp.campaigns()
    .withCondition('Name="foo"')
    .get()
    .next();

رویکرد دوم کمتر بهینه است زیرا براساس فیلد غیرشناسه فیلتر می‌کنیم.

هرزمان ممکن بود، براساس شناسه‌های والدین فیلتر کنید

هنگام انتخاب نهاد، هر زمان ممکن بود براساس شناسه‌های اصلی فیلتر کنید. این کار با محدود کردن فهرست نهادهایی که سرورها هنگام فیلتر کردن نتایج واکشی می‌کنند، پرسش‌های شما را سریع‌تر می‌کند.

تکه‌کد زیر را درنظر بگیرید که AdGroup را با شناسه آن بازیابی می‌کند. فرض کنید شناسه پویش اصلی مشخص است.

رویکرد کدنویسی تکه‌کد
فیلتر کردن براساس شناسه‌های پویش و گروه آگهی (توصیه‌شده)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .withCondition('CampaignId="54678"')
    .get()
    .next();
فیلتر کردن فقط براساس شناسه گروه آگهی (کمتر بهینه)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .get()
    .next();

اگرچه هر دو تکه‌کد نتایج یکسانی ارائه می‌دهند، اما فیلتر کردن اضافی در تکه‌کد ۱ بااستفاده از شناسه والد (CampaignId="54678") باعث می‌شود کد کارآمدتر شود زیرا فهرست نهادهایی را که سرور باید هنگام فیلتر کردن نتایج تکرار کند محدود می‌کند.

وقتی شرایط فیلتر کردن زیاد است، از برچسب‌ها استفاده کنید

وقتی شرایط فیلتر کردن زیادی دارید، ایده خوبی است که برای نهادهایی که پردازش می‌کنید برچسبی ایجاد کنید و از آن برچسب برای فیلتر کردن نهادهایتان استفاده کنید.

قطعه کد زیر را درنظر بگیرید که فهرستی از پویش‌ها را براساس نامشان بازیابی می‌کند.

رویکرد کدنویسی تکه‌کد
استفاده از برچسب (توصیه می‌شود)
var label = AdsApp.labels()
    .withCondition('Name = "My Label"')
    .get()
    .next();
var campaigns = label.campaigns.get();
while (campaigns.hasNext()) {
  var campaign = campaigns.next();
  // Do more work
}
ساختن انتخابگرهای پیچیده (توصیه نمی‌شود)
var campaignNames = ['foo', 'bar', 'baz'];

for (var i = 0; i < campaignNames.length; i++) {
  campaignNames[i] = '"' + campaignNames[i] + '"';
}

var campaigns = AdsApp.campaigns
    .withCondition('CampaignName in [' + campaignNames.join(',') + ']')
    .get();

while (campaigns.hasNext()) {
  var campaign = campaigns.next();
  // Do more work.
}

اگرچه هر دو تکه‌کد سطح عملکرد مشابهی به شما می‌دهند، اما رویکرد دوم با افزایش تعداد شرایط در گزینشگر شما، کد پیچیده‌تری تولید می‌کند. همچنین اعمال برچسب به نهاد جدید آسان‌تر از ویرایش کردن اسکریپت برای گنجاندن نهاد جدید است.

تعداد شرایط را در بند IN محدود کنید

هنگام اجرای اسکریپت‌ها، یک مورد استفاده رایج، اجرای گزارش برای فهرستی از نهادها است. توسعه‌دهندگان معمولاً این کار را با ساختن یک پُرسمان GAQL بسیار طولانی انجام می‌دهند که بااستفاده از عبارت IN، شناسه‌های نهاد را فیلتر می‌کند. این رویکرد زمانی خوب کار می‌کند که تعداد نهادها محدود باشد. بااین‌حال، با افزایش طول پُرسمان، عملکرد اسکریپت شما به دو دلیل کاهش می‌یابد:

  • تجزیه پُرسمان طولانی‌تر زمان بیشتری می‌برد.
  • هر شناسه‌ای که به بند IN اضافه می‌کنید شرط دیگری برای ارزیابی است و بنابراین زمان بیشتری می‌برد.

در چنین شرایطی، بهتر است برچسبی به نهادها اعمال کنید و سپس براساس LabelId فیلتر کنید.

رویکرد کدنویسی تکه‌کد
اعمال برچسب و فیلتر کردن براساس شناسه برچسب (توصیه‌شده)
// The label applied to the entity is "Report Entities"
var label = AdsApp.labels()
    .withCondition('LabelName contains "Report Entities"')
    .get()
    .next();

var report = AdsApp.report('SELECT AdGroupId, Id, Clicks, ' +
    'Impressions, Cost FROM KEYWORDS_PERFORMANCE_REPORT ' +
    'WHERE LabelId = "' + label.getId() + '"');
ساختن پُرسمان طولانی بااستفاده از عبارت IN (توصیه نمی‌شود)
var report = AdsApp.report('SELECT AdGroupId, Id, Clicks, ' +
    'Impressions, Cost FROM KEYWORDS_PERFORMANCE_REPORT WHERE ' +
    'AdGroupId IN (123, 456) and Id in (123,345, 456…)');

به‌روزرسانی‌های حساب

تغییرات گروهی

وقتی در نهاد Google Ads تغییراتی ایجاد می‌کنید، جاوااسکریپت Google Ads تغییر را فوراً اجرا نمی‌کند. درعوض، سعی می‌کند چندین تغییر را در دسته‌هایی ترکیب کند تا بتواند یک درخواست واحد صادر کند که چندین تغییر را انجام دهد. این رویکرد سرعت اسکریپت‌هایتان را افزایش می‌دهد و بار روی سرورهای Google Ads را کاهش می‌دهد. بااین‌حال، الگوهای کدی وجود دارد که اسکریپت‌های Google Ads را مجبور می‌کند دسته‌ای از عملیات را به‌طور مکرر پاک کند، و درنتیجه باعث می‌شود اسکریپت شما به‌کندی اجرا شود.

نوشتار زیر را که قیمت‌های پیشنهادی فهرست کلیدواژه‌ها را به‌روز می‌کند درنظر بگیرید.

رویکرد کدنویسی تکه‌کد
پیگیری عناصر به‌روزشده (توصیه‌شده)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 50')
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .forDateRange('LAST_MONTH')
    .get();

var list = [];
while (keywords.hasNext()) {
  var keyword = keywords.next();
  keyword.bidding().setCpc(1.5);
  list.push(keyword);
}

for (var i = 0; i < list.length; i++) {
  var keyword = list[i];
  Logger.log('%s, %s', keyword.getText(),
      keyword.bidding().getCpc());
}
بازیابی عناصر به‌روزشده در حلقه تنگ (توصیه نمی‌شود)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 50')
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .forDateRange('LAST_MONTH')
    .get();

while (keywords.hasNext()) {
  var keyword = keywords.next();
  keyword.bidding().setCpc(1.5);
  Logger.log('%s, %s', keyword.getText(),
      keyword.bidding().getCpc());
}

رویکرد دوم توصیه نمی‌شود زیرا فراخوانی keyword.bidding().getCpc() باعث می‌شود اسکریپت‌های Google Ads setCpc() عملکرد را پاکسازی کنند و فقط یک عملکرد را در هر زمان اجرا کنند. رویکرد اول، درحالی‌که شبیه رویکرد دوم است، مزیت اضافه‌ای دارد که از دسته‌ای کردن پشتیبانی می‌کند زیرا فراخوانی getCpc() در حلقه‌ای جدا از حلقه‌ای که setCpc() در آن فراخوانی می‌شود انجام می‌شود.

درصورت امکان از سازنده‌ها استفاده کنید

دستورگان Google Ads از دو روش برای ایجاد کردن عناصر جدید پشتیبانی می‌کند—سازندگان و روش‌های ایجاد. سازنده‌ها انعطاف‌پذیرتر از روش‌های ایجاد هستند، زیرا به شیء ایجادشده از فراخوانی API دسترسی می‌دهند.

تکه‌کدهای زیر را درنظر بگیرید:

رویکرد کدنویسی تکه‌کد
استفاده از سازنده‌ها (توصیه می‌شود)
var operation = adGroup.newKeywordBuilder()
    .withText('shoes')
    .build();
var keyword = operation.getResult();
استفاده از روش‌های ایجاد (توصیه نمی‌شود)
adGroup.createKeyword('shoes');
var keyword = adGroup.keywords()
    .withCondition('KeywordText="shoes"')
    .get()
    .next();

رویکرد دوم به‌دلیل عملیات انتخاب اضافی که در بازیابی کلیدواژه وجود دارد، ترجیح داده نمی‌شود. علاوه‌براین، روش‌های ایجاد نیز منسوخ شده‌اند.

بااین‌حال، به‌خاطر داشته باشید که سازندگان، درصورت استفاده نادرست، می‌توانند از دسته‌ای کردن عملیات توسط دستورگان Google Ads جلوگیری کنند.

تکه‌کدهای زیر را که فهرستی از کلیدواژه‌ها ایجاد می‌کند و شناسه کلیدواژه‌های تازه ایجادشده را چاپ می‌کند درنظر بگیرید:

رویکرد کدنویسی تکه‌کد
پیگیری عناصر به‌روزشده (توصیه‌شده)
var keywords = ['foo', 'bar', 'baz'];

var list = [];
for (var i = 0; i < keywords.length; i++) {
  var operation = adGroup.newKeywordBuilder()
      .withText(keywords[i])
      .build();
  list.push(operation);
}

for (var i = 0; i < list.length; i++) {
  var operation = list[i];
  var result = operation.getResult();
  Logger.log('%s %s', result.getId(),
      result.getText());
}
بازیابی عناصر به‌روزشده در حلقه تنگ (توصیه نمی‌شود)
var keywords = ['foo', 'bar', 'baz'];

for (var i = 0; i < keywords.length; i++) {
  var operation = adGroup.newKeywordBuilder()
      .withText(keywords[i])
      .build();
  var result = operation.getResult();
  Logger.log('%s %s', result.getId(),
      result.getText());
}

رویکرد دوم ترجیح داده نمی‌شود زیرا operation.getResult() را در همان حلقه‌ای که عملیات را ایجاد می‌کند فراخوانی می‌کند، بنابراین جاوااسکریپت Google Ads را مجبور می‌کند تا هر بار یک عملیات را اجرا کند. رویکرد اول، بااینکه مشابه است، امکان دسته‌بندی را فراهم می‌کند زیرا operation.getResult()‎ را در حلقه‌ای متفاوت از جایی که ایجاد شده است فراخوانی می‌کنیم.

برای به‌روزرسانی‌های بزرگ، از بارگذاری انبوه استفاده کنید

وظیفه رایجی که توسعه‌دهندگان انجام می‌دهند اجرای گزارش‌ها و به‌روزرسانی دارایی‌های نهاد (برای مثال، پیشنهاد قیمت کلیدواژه) براساس مقادیر عملکرد کنونی است. وقتی باید تعداد زیادی از نهادها را به‌روز کنید، بارگذاری انبوه معمولاً عملکرد بهتری به شما می‌دهد. برای مثال، دستورگان زیر را درنظر بگیرید که «قیمت پیشنهادی بیشینه برای هر کلیک» کلیدواژه‌هایی را که TopImpressionPercentage > 0.4 آن‌ها برای ماه گذشته است افزایش می‌دهد:

رویکرد کدنویسی تکه‌کد
استفاده از بارگذاری انبوه (توصیه می‌شود)

var report = AdsApp.report(
  'SELECT AdGroupId, Id, CpcBid FROM KEYWORDS_PERFORMANCE_REPORT ' +
  'WHERE TopImpressionPercentage > 0.4 DURING LAST_MONTH');

var upload = AdsApp.bulkUploads().newCsvUpload([
  report.getColumnHeader('AdGroupId').getBulkUploadColumnName(),
  report.getColumnHeader('Id').getBulkUploadColumnName(),
  report.getColumnHeader('CpcBid').getBulkUploadColumnName()]);
upload.forCampaignManagement();

var reportRows = report.rows();
while (reportRows.hasNext()) {
  var row = reportRows.next();
  row['CpcBid'] = row['CpcBid'] + 0.02;
  upload.append(row.formatForUpload());
}

upload.apply();
انتخاب و به‌روزرسانی کلیدواژه‌ها براساس شناسه (کمتر بهینه)
var reportRows = AdsApp.report('SELECT AdGroupId, Id, CpcBid FROM ' +
    'KEYWORDS_PERFORMANCE_REPORT WHERE TopImpressionPercentage > 0.4 ' +
    ' DURING LAST_MONTH')
    .rows();

var map = {
};

while (reportRows.hasNext()) {
  var row = reportRows.next();
  var adGroupId = row['AdGroupId'];
  var id = row['Id'];

  if (map[adGroupId] == null) {
    map[adGroupId] = [];
  }
  map[adGroupId].push([adGroupId, id]);
}

for (var key in map) {
  var keywords = AdsApp.keywords()
      .withCondition('AdGroupId="' + key + '"')
      .withIds(map[key])
      .get();

  while (keywords.hasNext()) {
    var keyword = keywords.next();
    keyword.bidding().setCpc(keyword.bidding().getCpc() + 0.02);
  }
}

درحالی‌که رویکرد دوم عملکرد بسیار خوبی به شما می‌دهد، رویکرد اول در این مورد ترجیح داده می‌شود زیرا

  • دستورگان Google Ads برای تعداد اشیایی که می‌توانند در یک اجرای واحد بازیابی یا به‌روزرسانی شوند محدودیت دارد، و عملیات‌های انتخاب و به‌روزرسانی در رویکرد دوم در این محدودیت محاسبه می‌شود.

  • بارگذاری‌های انبوه هم ازنظر تعداد نهادهایی که می‌تواند به‌روز کند و هم ازنظر زمان اجرای کلی، محدودیت‌های بالاتری دارند.

بارگذاری‌های انبوه خود را براساس پویش‌ها گروه‌بندی کنید

وقتی بارگذاری‌های انبوه را ایجاد می‌کنید، سعی کنید عملیاتتان را براساس کمپین اصلی گروه‌بندی کنید. این کار کارایی را افزایش می‌دهد و احتمال تغییرات متناقض / خطاهای هم‌زمانی را کاهش می‌دهد.

دو تکلیف بارگذاری انبوه را درنظر بگیرید که به‌طور هم‌زمان اجرا می‌شوند. یکی آگهی‌ها را در گروه آگهی موقتاً متوقف می‌کند؛ دیگری پیشنهادهای قیمت کلیدواژه را تعدیل می‌کند. هرچند عملیات‌ها نامرتبط هستند، ممکن است عملیات‌ها برای نهادهای تحت یک گروه آگهی (یا دو گروه آگهی متفاوت تحت یک پویش) اعمال شوند. وقتی این اتفاق می‌افتد، سیستم نهاد اصلی (گروه آگهی یا پویش هم‌رسانی‌شده) را قفل می‌کند و درنتیجه باعث می‌شود کارهای بارگذاری انبوه یکدیگر را مسدود کنند.

جاوااسکریپت Google Ads می‌تواند اجرا را در یک تکلیف بارگذاری انبوه بهینه‌سازی کند، بنابراین ساده‌ترین کار این است که در هر زمان فقط یک تکلیف بارگذاری انبوه را برای هر حساب اجرا کنید. اگر تصمیم دارید بیش‌از یک بارگذاری انبوه برای هر حساب اجرا کنید، مطمئن شوید که بارگذاری‌های انبوه روی فهرست کمپین‌های متقابلاً انحصاری (و نهادهای فرزند آن‌ها) برای عملکرد بهینه اجرا می‌شوند.

گزارش

استفاده از گزارش‌ها برای واکشی آمار

وقتی می‌خواهید حجم زیادی از نهادها و آمار آن‌ها را بازیابی کنید، اغلب بهتر است از گزارش‌ها استفاده کنید تا روش‌های استاندارد AdsApp. استفاده از گزارش‌ها به‌دلایل زیر ترجیح داده می‌شود:

  • گزارش‌ها عملکرد بهتری برای پرسمان‌های بزرگ به شما ارائه می‌دهند.
  • گزارش‌ها به سهمیه‌های واکشی عادی نمی‌رسند.

تکه‌کدهای زیر را که «کلیک‌ها»، «ظهورها»، «هزینه»، و «نوشتار» همه کلیدواژه‌هایی را که در ماه گذشته بیش‌از ۵۰ کلیک دریافت کرده‌اند واکشی می‌کنند مقایسه کنید:

رویکرد کدنویسی تکه‌کد
استفاده از گزارش‌ها (توصیه‌شده)
  report = AdsApp.search(
      'SELECT ' +
      '   ad_group_criterion.keyword.text, ' +
      '   metrics.clicks, ' +
      '   metrics.cost_micros, ' +
      '   metrics.impressions ' +
      'FROM ' +
      '   keyword_view ' +
      'WHERE ' +
      '   segments.date DURING LAST_MONTH ' +
      '   AND metrics.clicks > 50');
  while (report.hasNext()) {
    var row = report.next();
    Logger.log('Keyword: %s Impressions: %s ' +
        'Clicks: %s Cost: %s',
        row.adGroupCriterion.keyword.text,
        row.metrics.impressions,
        row.metrics.clicks,
        row.metrics.cost);
  }
استفاده از تکرارکننده‌های AdsApp (توصیه نمی‌شود)
var keywords = AdsApp.keywords()
    .withCondition('metrics.clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();
while (keywords.hasNext()) {
  var keyword = keywords.next();
  var stats = keyword.getStatsFor('LAST_MONTH');
  Logger.log('Keyword: %s Impressions: %s ' +
      'Clicks: %s Cost: %s',
      keyword.getText(),
      stats.getImpressions(),
      stats.getClicks(),
      stats.getCost());
}

رویکرد دوم ترجیح داده نمی‌شود زیرا روی کلیدواژه‌ها تکرار می‌کند و آمارها را یک نهاد در هر زمان بازیابی می‌کند. در این حالت، گزارش‌ها سریع‌تر اجرا می‌شوند زیرا همه داده‌ها را در یک فراخوانی واکشی می‌کند و آن را به‌صورت جریانی درصورت نیاز ارسال می‌کند. علاوه‌براین، کلیدواژه‌های بازیابی‌شده در رویکرد دوم به‌عنوان سهمیه اسکریپت شما برای تعداد نهادهای بازیابی‌شده بااستفاده از فراخوانی get() محاسبه می‌شود.

به‌جای گزارش کردن، از جستجو استفاده کنید

روش گزارش برای زیرساخت قدیمی ساخته شده است و حتی اگر از GAQL استفاده کنید، نتایج را در قالب تخت ارائه می‌دهد. این یعنی باید نتایج پُرسمان را تبدیل کند تا با سبک قدیمی مطابقت داشته باشد، که برای همه فیلدها پشتیبانی نمی‌شود و به هر تماس سربار اضافه می‌کند.

پیشنهاد می‌کنیم به‌جای آن از جستجو استفاده کنید تا از همه ویژگی‌های گزارش‌دهی Google Ads API جدید بهره‌مند شوید.

ترجیح GAQL به AWQL

هرچند AWQL ازنظر فنی هنوز برای پُرسمان‌های گزارش و withCondition تماس‌ها کار می‌کند، اما توصیه نمی‌شود. برای کنترل کامل پُرسمان‌هایتان، مطمئن شوید که به‌جای آن از GAQL استفاده می‌کنید.

بیشتر از تعداد ردیف‌های موردنیازتان انتخاب نکنید

سرعت اجرای گزارش‌ها (و گزینشگرها) براساس تعداد کل ردیف‌هایی است که گزارش برمی‌گرداند، صرف‌نظر از اینکه آن‌ها را تکرار کنید یا نه. این یعنی همیشه باید از فیلترهای خاصی استفاده کنید تا مجموعه نتایج را تا حد امکان برای مطابقت با مورد استفاده‌تان به‌حداقل برسانید.

برای مثال، فرض کنید می‌خواهید گروه‌های آگهی را با قیمت‌های پیشنهادی خارج از یک محدوده خاص پیدا کنید. ساختن دو پُرسمان جداگانه، یکی برای قیمت‌های پیشنهادی زیر آستانه پایین و دیگری برای قیمت‌های پیشنهادی بالای آستانه بالا، سریع‌تر از واکشی کردن همه گروه‌های آگهی و نادیده گرفتن گروه‌هایی است که به آن‌ها علاقه‌ای ندارید.

رویکرد کدنویسی تکه‌کد
استفاده از دو پُرسمان (توصیه‌شده)
var adGroups = []
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group WHERE ad_group.cpc_bid_micros < 1000000');

while (report.hasNext()) {
  var row = report.next();
  adGroups.push(row.adGroup);
}
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group WHERE ad_group.cpc_bid_micros > 2000000');

while (report.hasNext()) {
  var row = report.next();
  adGroups.push(row.adGroup);
}
فیلتر کردن از پُرسمان عمومی (توصیه نمی‌شود)
var adGroups = []
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group');

while (report.hasNext()) {
  var row = report.next();
  var cpcBidMicros = row.adGroup.cpcBidMicros;
  if (cpcBidMicros < 1000000 || cpcBidMicros > 2000000) {
    adGroups.push(row.adGroup);
  }
}

دستورگان «مدیر آگهی‌ها» (MCC)

executeInParallel را به اجرای سریال ترجیح دهید

هنگام نوشتن دستورگان برای حساب‌های مدیر، درصورت امکان به‌جای اجرای سریال از executeInParallel() استفاده کنید. executeInParallel() به دستورات شما زمان پردازش بیشتری می‌دهد (تا یک ساعت) و تا ۳۰ دقیقه برای هر حساب پردازش‌شده (به‌جای ۳۰ دقیقه ترکیبی برای اجرای سریالی). برای جزئیات بیشتر، صفحه محدودیت‌های ما را ببینید.

صفحه‌گسترده‌ها

هنگام به‌روزرسانی صفحه‌گسترده‌ها از عملیات دسته‌ای استفاده کنید

هنگام به‌روزرسانی صفحه‌گسترده‌ها، سعی کنید از روش‌های عملیات انبوه (برای مثال، getRange()) به‌جای روش‌هایی که یک سلول را در هر زمان به‌روزرسانی می‌کنند استفاده کنید.

تکه‌کد زیر را که الگوی فراکتال را در صفحه‌گسترده تولید می‌کند درنظر بگیرید.

رویکرد کدنویسی تکه‌کد
به‌روزرسانی کردن محدوده سلول‌ها در یک تماس (توصیه‌شده)
var colors = new Array(100);
for (var y = 0; y < 100; y++) {
  xcoord = xmin;
  colors[y] = new Array(100);
  for (var x = 0; x < 100; x++) {
    colors[y][x] = getColor_(xcoord, ycoord);
    xcoord += xincrement;
  }
  ycoord -= yincrement;
}
sheet.getRange(1, 1, 100, 100).setBackgroundColors(colors);
به‌روزرسانی سلول‌ها به‌صورت تکی (توصیه نمی‌شود)
var cell = sheet.getRange('a1');
for (var y = 0; y < 100; y++) {
  xcoord = xmin;
  for (var x = 0; x < 100; x++) {
    var c = getColor_(xcoord, ycoord);
    cell.offset(y, x).setBackgroundColor(c);
    xcoord += xincrement;
  }
  ycoord -= yincrement;
  SpreadsheetApp.flush();
}

درحالی‌که Google Spreadsheets تلاش می‌کند تکه‌کد دوم را با ذخیره کردن مقادیر در حافظه نهان بهینه‌سازی کند، به‌دلیل تعداد فراخوانی‌های API که انجام می‌شود، همچنان عملکرد ضعیفی نسبت‌به تکه‌کد اول دارد.