Microsoft Reklam Betikleri için en iyi yöntemler
Betiklerinizin ve platformun performansını geliştirmek için lütfen aşağıda açıklanan en iyi yöntemleri gözden geçirin ve izleyin.
Seçicilerle çalışma
Filtreleri kullanma
Varlıkları kendiniz filtrelemek yerine bir seçicinin filtrelerini kullanın. Seçiciler kimliklere ve koşullara göre filtrelemenizi sağlar. Örneğin, bir varlığın performansına (ortalama CPC değeri 10'dan büyük olan dönüş kampanyaları), durumuna (duraklatılan kampanyalara), varlığın üst nesnesinin adına ve daha fazlasına göre filtreleyebilirsiniz.
Filtreleri kullanmanın avantajları:
Seçicinin döndürdüğü varlık sayısını yalnızca ihtiyacınız olan varlıklarla sınırlar.
Betiğin daha hızlı yürütülmesini sağlar (döndürülmesi ve işlenmesi için daha az varlık)
Varlık okuma sınırlarıyla karşılaşma ihtimalinizi azaltır (bkz . Betik yürütme sınırları).
Doğru yol
var adGroups = AdsApp.adGroups()
.withCondition('Status = PAUSED')
.get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
// Do something with paused ad group.
}
Yanlış yol
var adGroups = AdsApp.adGroups().get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
if (adGroup.isPaused() == true) {
// Do something with paused ad group.
}
}
Varlık hiyerarşisinde dolaşma
Bir varlığın alt varlıklarını veya varlığın üst varlığını almak istiyorsanız, varlık hiyerarşisinde gezinmeyin.
Alt varlıkları almak için alt varlığın koleksiyonunu istediğiniz düzeyde kullanın.
Doğru yol
// Get all ads.
var ads = AdsApp.ads().get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with ad.
}
Veya belirli bir kampanyadan reklam almak istiyorsanız:
// Get all ads in the campaign, 'mycampaign'.
var ads = AdsApp.ads()
.withCondition("CampaignName = 'mycampaign'")
.get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with ad.
}
Alternatif olarak, kampanya nesnesine sahipseniz bir kampanyanın reklamlarını da elde edebilirsiniz:
// Get all ads in the campaign.
var ads = campaign.ads().get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with ad.
}
Yanlış yol
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
var adGroups = campaigns.next().adGroups().get();
while (adGroups.hasNext()) {
var ads = adGroups.next().ads().get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with ad.
}
}
}
Aynı durum, varlığın üst öğesini almak istediğinizde de geçerlidir. Üst öğeyi almak için hiyerarşide gezinmek yerine alt varlığın üst erişimci yöntemini kullanın.
Doğru yol
// Get all ads.
var ads = AdsApp.ads()
.withCondition('Clicks > 5')
.forDateRange('LAST_7_DAYS')
.get();
while (ads.hasNext()) {
var ad = ads.next();
// Do something with campaign and adGroup.
var adGroup = ad.adGroup();
var campaign = ad.campaign();
}
Yanlış yol
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
var campaign = campaigns.next();
var adGroups = campaign.adGroups().get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
var ads = adGroup.ads().get();
while (ads.hasNext()) {
var ad = ads.next();
if ('<some condition is met>') {
// Do something with campaign and adGroup.
}
}
}
}
Mümkün olduğunda varlık kimliklerini kullanma
Varlıkları filtrelemek için kimlikleri kullanmak en iyi performansı sağlar.
Bu
var adGroups = AdsApp.adGroups()
.withIds(["123456"])
.get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
// Do something with adGroup.
}
Bundan daha iyi performans sağlar
var adGroups = AdsApp.adGroups()
.withCondition("Name = 'myadgroup'")
.get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
// Do something with adGroup.
}
Seçiciler ve gereksiz sayıda alma ile sıkı döngülerden kaçının
Tek bir varlık alan alma istekleriyle döngülerden kaçının. Örneğin, bir anahtar sözcük performans raporu çalıştırdığınızı ve rapordaki anahtar sözcükleri güncelleştirmek istediğinizi varsayalım. Rapordan satır almak, anahtar sözcüğü almak ve sonra güncelleştirmek yerine, rapordaki her satırda döngü oluştururken anahtar sözcük kimliklerinin listesini oluşturmanız gerekir. Ardından, tek bir alma isteğindeki tüm anahtar sözcükleri almak için kimlik listesini seçiciye geçirin. Ardından anahtar sözcükler listesinde yineleyebilir ve bunları güncelleştirebilirsiniz.
Doğru yol
var report = AdsApp.report('<report query goes here>');
var rows = report.rows();
var idLists = []; // an array where each element contains an array of IDs.
var idList = []; // array of IDs that's limited to maxCount.
var maxCount = 10000;
while (rows.hasNext()) {
var row = rows.next();
if (idList.length < maxCount) {
idList.push(row['id']);
}
else {
idLists.push(idList);
idList = [];
}
}
for (idList of idLists) {
var keywords = AdsApp.keywords()
.withIds(idList)
.get();
while (keywords.hasNext()) {
var keyword = keywords.next();
// update the keyword
}
}
Yanlış yol
var report = AdsApp.report('<report query goes here>');
var rows = report.rows();
while (rows.hasNext()) {
var row = rows.next();
var keyword = AdsApp.keywords()
.withIds([row['id']])
.get()
.next();
// update the keyword
}
forDateRange yöntemini yalnızca varlığın getStats yöntemini çağırmayı planlıyorsanız ekleyin
Seçicinin forDateRange
yöntemini çağırmak, seçicinin varlığın performans verilerini almasına neden olur. Bir varlığın performans verilerini almak pahalıdır, bu nedenle yalnızca varlığın getStats
yöntemini çağırmayı ve verileri kullanmayı planlıyorsanız alın.
Bir varlık için belirttiğiniz tarih aralığı, bu varlıktan erişeceğiniz üst veya alt varlıklar için geçerli değildir. Örneğin, bir reklam grubu alır ve ardından ana kampanyasını alır ve kampanyanın performans ölçümlerine erişmeye çalışırsanız, arama başarısız olur.
campaignStats.getReturnOnAdSpend()
Tarih aralığı kampanyaya değil reklam grubuna uygulandığından aşağıdaki örnekteki arama başarısız olur.
var myAdGroups = AdsApp.adGroups().
.withCondition("CampaignName CONTAINS 'gen'")
.forDateRange("LAST_7_DAYS")
.get();
while (myAdGroups.hasNext()) {
var adGroup = myAdGroups.next();
var campaign = adGroup.getCampaign();
var campaignStats = campaign.getStats();
var campaignROAS = campaignStats.getReturnOnAdSpend();
}
Bunun işe yarayacağı için kampanya için bir seçici oluşturmanız gerekir.
var myAdGroups = AdsApp.adGroups().
.withCondition("CampaignName CONTAINS 'gen'")
.forDateRange("LAST_7_DAYS")
.get();
while (myAdGroups.hasNext()) {
var adGroup = myAdGroups.next();
var campaign = AdsApp.campaigns()
.withIds([adGroup.getCampaign().getId()])
.forDateRange("LAST_7_DAYS")
.get()
.next();
var campaignStats = campaign.getStats();
var campaignROAS = campaignStats.getReturnOnAdSpend();
}
Bir varlığın seçicide koşul olarak kullanılan özelliğini değiştirmeyin
Yineleyiciler, bir kerede tüm öğe kümesi yerine tek bir öğe yükleyerek bellek baskısını azaltır. Bu nedenle, seçicide koşul olarak kullandığınız bir özelliği değiştirmek beklenmeyen davranışlara neden olabilir.
Doğru yol
var adGroups = [];
var iterator = AdsApp.adGroups()
.withCondition('Status = ENABLED')
.get();
while (iterator.hasNext()) {
adGroups.push(iterator.next());
}
for (var adGroup of adGroups) {
adGroup.pause();
}
Yanlış yol
var adGroups = AdsApp.adGroups()
.withCondition('Status = ENABLED')
.get();
while (adGroups.hasNext()) {
var adGroup = adGroups.next();
adGroup.pause();
}
Güncelleştirmeleri toplu olarak oluşturma
Betikler, performansı geliştirmek için derleme isteklerini toplu olarak işler. Derleme isteğinin işlem yöntemini çağırırsanız, Betikleri kuyruğa alınan derleme isteklerini hemen işlemeye zorlar ve tüm performans kazançlarını olumsuzleştirir. Birden fazla varlık oluşturuyorsanız, varlığı oluşturmak için kullandığınız döngüde işlem yöntemlerini yürütmeyin. Aynı anda yalnızca bir varlık işlendiğinden bu düşük performansa yol açar. Bunun yerine, işlemlerin bir dizisini oluşturun ve derleme döngüsünden sonra işleyin.
Doğru yol
// An array to hold the operations, so you
// can process them after all the entities are queued.
var operations = [];
// Create all the new entities.
for (var i = 0; i < keywords.length; i++) {
var keywordOperation = AdsApp.adGroups().get().next()
.newKeywordBuilder()
.withText(keywords[i])
.build();
operations.push(keywordOperation);
}
// Now call the operation method so the build requests
// get processed in batches.
for (var i = 0; i < operations.length; i++) {
var newKeyword = operations[i].getResult();
}
Yanlış yol
for (var i = 0; i < keywords.length; i++) {
var keywordOperation = AdsApp.adGroups().get().next() // Get the first ad group
.newKeywordBuilder() // Add the keyword to the ad group
.withText(keywords[i])
.build();
// Don't get results in the same loop that creates
// the entity because Scripts then only processes one
// entity at a time.
var newKeyword = keywordOperation.getResult();
}
Bir varlığı güncelleştirir ve ardından güncelleştirdiğiniz özelliği alırsanız aynı durum geçerlidir. Bunu yapmayın:
var bidAmount = 1.2;
while (keywords.hasNext()) {
var keyword = keywords.next();
keyword.bidding().setCpc(bidAmount);
if (keyword.bidding().getCpc() != bidAmount) {
Logger.log(`Failed to update bid amount for keyword, ${keyword.getText()} (${keyword.getId()})`);
}
}
Büyük varlık kümeleri alırken yield anahtar sözcüğünü kullanma
Çok sayıda varlığı alıp döngüde işlediğiniz tek bir listeye yüklemenin birkaç dezavantajı vardır:
İsteğin boyutuna bağlı olarak, döngü başlamadan önce tüm varlıkları getirmek için n sayıda arka uç isteği gerekebilir. Hepsini işlemezseniz, işlenmemiş varlıkları almak için kullanılan zaman ve işlem gücü boşa gider. Örneğin, 10.000 anahtar sözcüğü alırsanız ve yalnızca 2K anahtar sözcükleri işledikten sonra döngü bozulursa, kalan 8K anahtar sözcükleri almak için kullanılan süre ve işlem gücü harcanır.
Listeyi oluşturmak, tüm varlıkları aynı anda tutmak için daha fazla bellek gerektirir.
Bu sorunları çözmek için, betiğinizin varlıkları isteğe bağlı olarak getirmesine olanak tanıyan yield anahtar sözcüğünü kullanın veya bir bakıma "lazily" bunları yalnızca gerektiğinde getirir. Bu, betiğinizin şu anda ihtiyaç duyduğundan daha fazla çağrı yapmadığı ve büyük nesne listelerini geçmediği anlamına gelir.
Bu örnek , yield anahtar sözcüğünü kullanırken denetim akışını göstermek için günlüğe kaydetmeyi içerir.
function main() {
const keywords = getKeywords();
//@ts-ignore <-- suppresses iterator error
for (const keyword of keywords) {
Logger.log("in for loop\n\n");
}
}
// Note that you must use the yield keyword in a generator function - see the
// '*' at the end of the function keyword.
function* getKeywords() {
const keywords = AdsApp.keywords()
.withCondition("Status = ENABLED")
.withCondition("CombinedApprovalStatus = APPROVED")
.withLimit(10)
.get();
Logger.log(`total keywords in account: ${keywords.totalNumEntities()} \n\n`);
while (keywords.hasNext()) {
Logger.log("before next()\n\n");
yield keywords.next();
Logger.log("after next\n\n");
}
}
Varlık sınırlarından kaçınmak için çağrı düzeni
Betiklerin bir hesap için döndürebileceği varlık sayısı sınırı vardır. İstek bu sınırdan daha fazlasını döndürseydi, Betikler çok fazla varlık var iletisiyle bir hata oluşturur. Aşağıdaki örnek, çok sayıda varlık alırken kullanmanız gereken çağrı düzenini gösterir. Örnek, önce hesap düzeyindeki tüm anahtar sözcükleri getirmeye çalışır. Bu başarısız olursa, kampanya düzeyinde genellikle daha az varlık olduğundan, kampanyaya göre anahtar sözcükleri getirmek için birden çok çağrı yapmaya çalışır. Gerekirse bu desene genellikle reklam grubu düzeyine kadar devam edebilirsiniz.
Yield anahtar sözcüğünü kullanma hakkında bilgi için bkz. Büyük varlık kümeleri alırken ödeme anahtar sözcüğünü kullanma.
function* getEntities() {
const applyConditions = _ => _
.withCondition('CampaignStatus = ENABLED')
.withCondition('AdGroupStatus = ENABLED')
.withCondition('Status = ENABLED')
.withCondition("CombinedApprovalStatus = DISAPPROVED");
try {
// Get the account's keywords.
const keywords = applyConditions(AdsApp.keywords()).get();
while (keywords.hasNext()) {
yield keywords.next();
}
} catch (e) {
if (!e.message.startsWith('There are too many entities')) {
throw e;
}
// If there are too many keywords at the account level,
// get keywords by campaigns under the account.
const campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
const campaign = campaigns.next();
const keywords = applyConditions(campaign.keywords()).get();
while (keywords.hasNext()) {
yield keywords.next();
}
}
}
}