بهترین شیوه ها

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

انتخابگرها

فیلتر با انتخابگر

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

  • کد ساده تر و قابل درک تر است.
  • اسکریپت خیلی سریعتر اجرا می شود.

قطعات کد زیر را با هم مقایسه کنید:

رویکرد کدگذاری قطعه کد
فیلتر کردن با استفاده از انتخابگرها (توصیه می شود)
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.
  }
}

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

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

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

قطعات کد زیر را مقایسه کنید که گروه های تبلیغاتی را که در ماه گذشته تبلیغات متنی با بیش از 50 کلیک داشتند، بازیابی می کند:

رویکرد کدگذاری قطعه کد
استفاده از روش دسترسی والد مناسب (توصیه می شود)
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.
    }
  }
}

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

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

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

قطعات کد زیر را مقایسه کنید که لیستی از تبلیغات متنی را در یک کمپین مشخص و گروه تبلیغاتی با بیش از 50 کلیک در ماه گذشته بازیابی می کند.

رویکرد کدگذاری قطعه کد
استفاده از فیلترهای سطح والدین مناسب (توصیه می شود)
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();

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

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

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

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

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

اگرچه هر دو قطعه کد نتایج یکسانی ارائه می دهند، فیلتر اضافی در قطعه کد 1 با استفاده از شناسه والد (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 خود را محدود کنید

هنگام اجرای اسکریپت ها، یک مورد رایج استفاده از آن، اجرای یک گزارش برای لیستی از موجودیت ها است. توسعه دهندگان معمولاً این کار را با ساختن یک کوئری AWQL بسیار طولانی انجام می دهند که شناسه های موجودیت را با استفاده از یک عبارت 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 را در حلقه ای متفاوت از محل ایجاد آن فراخوانی می کنیم.

استفاده از آپلودهای انبوه را برای به روز رسانی های بزرگ در نظر بگیرید

یک کار رایج که توسعه دهندگان انجام می دهند اجرای گزارش ها و به روز رسانی ویژگی های موجودیت (به عنوان مثال، پیشنهادات کلمه کلیدی) بر اساس مقادیر عملکرد فعلی است. هنگامی که مجبور هستید تعداد زیادی نهاد را به‌روزرسانی کنید، آپلودهای انبوه عملکرد بهتری به شما ارائه می‌دهند. به عنوان مثال، اسکریپت های زیر را در نظر بگیرید که MaxCpc کلمات کلیدی را که 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 استفاده کنید. استفاده از گزارش ها به دلایل زیر ترجیح داده می شود:

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

تکه‌های کد زیر را که کلیک‌ها، نمایش‌ها، هزینه و متن همه کلیدواژه‌هایی را که در ماه گذشته بیش از 50 کلیک دریافت کرده‌اند، مقایسه کنید:

رویکرد کدگذاری قطعه کد
استفاده از گزارش ها (توصیه می شود)
  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 پشتیبانی می شود، اما از طریق یک لایه ترجمه اجرا می شود که سازگاری کامل با AWQL واقعی ندارد. برای داشتن کنترل کامل بر جستارهای خود، مطمئن شوید که از GAQL استفاده می کنید.

اگر جستارهای AWQL موجودی دارید که می‌خواهید ترجمه کنید، ما یک ابزار Query Migration برای کمک داریم.

سطرهای بیشتری از آنچه نیاز دارید انتخاب نکنید

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

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

رویکرد کدگذاری قطعه کد
استفاده از دو پرس و جو (توصیه می شود)
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() به اسکریپت شما زمان پردازش بیشتری (حداکثر یک ساعت) و حداکثر 30 دقیقه برای هر حساب پردازش شده (به جای 30 دقیقه ترکیبی برای اجرای سریال) می دهد. برای جزئیات بیشتر به صفحه محدودیت های ما مراجعه کنید.

صفحات گسترده

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

هنگام به‌روزرسانی صفحه‌گسترده، سعی کنید از روش‌های عملیات انبوه (مثلا 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 انجام شده، همچنان عملکرد ضعیفی نسبت به قطعه اول به شما ارائه می دهد.