งบประมาณที่ยืดหยุ่น - บัญชีเดียว

ไอคอนเครื่องมือ

Google Ads ให้คุณกำหนดจำนวนงบประมาณรายวันสำหรับแต่ละแคมเปญ อย่างไรก็ตาม โครงการด้านการตลาดจะมีค่าใช้จ่ายคงที่ ตัวอย่างเช่น "ฉันอยากจ่าย $5,000 ก่อนถึงงานลดราคาฤดูใบไม้ร่วง" กลยุทธ์การเสนอราคามี คุณสามารถควบคุมการใช้งบประมาณรายวันได้ แต่ไม่สามารถควบคุมวิธีที่ งบประมาณที่ใช้ในระหว่างแคมเปญ

เช่น ถ้าเราต้องการจ่ายเพียง 150, 000 บาทเพื่อโฆษณาสินค้าลดราคาในฤดูใบไม้ร่วงและ และต้องการลงโฆษณาเป็นเวลา 10 วัน เราสามารถตั้งงบประมาณรายวันไว้ที่ 15, 000 บาทเพื่อใช้ งบประมาณทั้งหมด แต่ทั้งนี้ ถือว่าเราจะใช้เงินเต็มจำนวน ในแต่ละวัน และเราต้องการใช้จ่ายอย่างเท่าเทียม คุณไม่สามารถบอก Google Ads ว่า คุณต้องการใช้งบประมาณจำนวนมากในช่วง 2-3 วันที่ผ่านมา

สคริปต์นี้จะปรับงบประมาณแคมเปญของคุณแบบไดนามิกทุกวันด้วย การกระจายงบประมาณ

วิธีการทำงาน

การทดสอบกลยุทธ์งบประมาณ

สคริปต์มีโค้ดทดสอบบางอย่างเพื่อจำลองผลของการเรียกใช้สำหรับ หลายวัน ซึ่งจะช่วยให้คุณเห็นภาพมากขึ้นว่าจะเกิดอะไรขึ้นเมื่อสคริปต์ ถูกกำหนดให้ทำงานทุกวันในช่วงระยะเวลาหนึ่ง

โดยค่าเริ่มต้น สคริปต์นี้จะจำลองการกระจายงบประมาณเท่าๆ กันของการใช้จ่าย 20, 000 บาท เกิน 10 วัน

function main() {
  testBudgetStrategy(calculateBudgetEvenly, 10, 500);
  // setNewBudget(calculateBudgetEvenly, CAMPAIGN_NAME, TOTAL_BUDGET, START_DATE, END_DATE);
}

ระบบแสดงความคิดเห็นการเรียกฟังก์ชัน setNewBudget ซึ่งระบุว่าจะทำงาน โค้ดทดสอบ เอาต์พุตจากตัวอย่างมีดังนี้

Day 1.0 of 10.0, new budget 50.0, cost so far 0.0
Day 2.0 of 10.0, new budget 50.0, cost so far 50.0
Day 3.0 of 10.0, new budget 50.0, cost so far 100.0
Day 4.0 of 10.0, new budget 50.0, cost so far 150.0
Day 5.0 of 10.0, new budget 50.0, cost so far 200.0
Day 6.0 of 10.0, new budget 50.0, cost so far 250.0
Day 7.0 of 10.0, new budget 50.0, cost so far 300.0
Day 8.0 of 10.0, new budget 50.0, cost so far 350.0
Day 9.0 of 10.0, new budget 50.0, cost so far 400.0
Day 10.0 of 10.0, new budget 50.0, cost so far 450.0
Day 11.0 of 10.0, new budget 0.0, cost so far 500.0

ในแต่ละวันสคริปต์จะคำนวณงบประมาณใหม่เพื่อให้มั่นใจว่าการใช้จ่ายงบประมาณ กระจายอย่างเท่าเทียมกัน เมื่อถึงขีดจำกัดงบประมาณที่จัดสรร ระบบจะตั้งงบประมาณ เป็น 0 การระงับการใช้จ่าย

คุณเปลี่ยนกลยุทธ์งบประมาณที่ใช้ได้โดยเปลี่ยนฟังก์ชันที่ใช้ หรือ แก้ไขฟังก์ชัน สคริปต์จะมีกลยุทธ์ที่สร้างไว้ล่วงหน้า 2 อย่าง ได้แก่ calculateBudgetEvenly และ calculateBudgetWeighted วิธีตั้งการทดสอบแบบถ่วงน้ำหนัก กลยุทธ์งบประมาณ เปลี่ยนแปลง testBudgetStrategy ดังนี้

testBudgetStrategy(calculateBudgetWeighted, 10, 500);

คลิกแสดงตัวอย่างและตรวจสอบเอาต์พุตของบันทึก สังเกตว่ากลยุทธ์งบประมาณนี้ จัดสรรงบประมาณน้อยลงในช่วงต้นของระยะเวลาและจัดสรรงบประมาณเพิ่มเติมในช่วง 2-3 วันที่ผ่านมา

คุณสามารถใช้วิธีทดสอบนี้เพื่อจำลองการเปลี่ยนแปลงการคำนวณงบประมาณได้ ใช้งานได้และลองใช้แนวทางของตัวเองในการกระจายงบประมาณ

การจัดสรรงบประมาณ

วิธีนำกลยุทธ์งบประมาณ calculateBudgetWeighted ไปใช้มีดังนี้ ฟังก์ชัน:

function calculateBudgetWeighted(costSoFar, totalBudget, daysSoFar, totalDays) {
  const daysRemaining = totalDays - daysSoFar;
  const budgetRemaining = totalBudget - costSoFar;
  if (daysRemaining <= 0) {
    return budgetRemaining;
  } else {
    return budgetRemaining / (2 * daysRemaining - 1) ;
  }
}

ฟังก์ชันนี้ใช้อาร์กิวเมนต์ต่อไปนี้

costSoFar
ค่าใช้จ่ายที่เกิดขึ้นของแคมเปญตั้งแต่วันที่ START_DATE จนถึงวันนี้
totalBudget
การใช้จ่ายที่จัดสรรจาก START_DATE เป็น END_DATE
daysSoFar
วันที่ผ่านไปตั้งแต่ START_DATE ถึงวันนี้
totalDays
จำนวนวันทั้งหมดระหว่าง START_DATE ถึง END_DATE

คุณจะเขียนฟังก์ชันของตัวเองได้ตราบใดที่ต้องใช้อาร์กิวเมนต์เหล่านี้ การใช้ มูลค่าเหล่านี้ คุณจะสามารถเปรียบเทียบจำนวนเงินที่คุณใช้จ่ายไป ใช้จ่ายโดยรวมมากขึ้นและพิจารณาว่าตอนนี้คุณอยู่จุดไหนในลำดับเวลา สำหรับงบประมาณทั้งหมด

โดยเฉพาะอย่างยิ่ง กลยุทธ์งบประมาณนี้คำนวณงบประมาณที่เหลืออยู่ (totalBudget - costSoFar) แล้วหารด้วยจำนวนวัน 2 เท่า เหลืออยู่ เพื่อให้น้ำหนักการกระจายงบประมาณในช่วงท้ายของ แคมเปญ การใช้ค่าใช้จ่ายตั้งแต่ START_DATE ยังคํานึงถึง "ช้าด้วย วัน" ซึ่งงบประมาณที่ตั้งไว้ไม่ได้ใช้จ่ายทั้งหมด

การจัดทำงบประมาณตามจริง

เมื่อพอใจกับกลยุทธ์งบประมาณแล้ว คุณต้องทำการเปลี่ยนแปลงบางอย่าง ก่อนที่จะตั้งเวลาให้สคริปต์นี้ทำงานทุกวัน

ขั้นแรก ให้อัปเดตค่าคงที่ที่ด้านบนของไฟล์ดังนี้

  • START_DATE: ตั้งค่าเป็นจุดเริ่มต้นของกลยุทธ์งบประมาณ ควรเป็น วันที่ปัจจุบันหรือวันที่ผ่านมาแล้ว
  • END_DATE: ตั้งค่าเป็นวันสุดท้ายที่คุณต้องการโฆษณาโดยใช้งบประมาณนี้
  • TOTAL_BUDGET: จำนวนเงินทั้งหมดที่คุณพยายามจะใช้จ่าย ค่านี้อยู่ใน สกุลเงินของบัญชี และอาจมีการใช้จ่ายเกิน ทั้งนี้ขึ้นอยู่กับเวลาที่สคริปต์ กำหนดเวลาไว้
  • CAMPAIGN_NAME: ชื่อแคมเปญที่จะใช้กลยุทธ์งบประมาณ

ถัดไป ให้ปิดใช้การทดสอบแล้วเปิดใช้ตรรกะเพื่อเปลี่ยนงบประมาณจริงๆ

function main() {
  // testBudgetStrategy(calculateBudgetEvenly, 10, 500);
  setNewBudget(calculateBudgetWeighted, CAMPAIGN_NAME, TOTAL_BUDGET, START_DATE, END_DATE);
}

Scheduling

ตั้งเวลาให้สคริปต์นี้ทํางานทุกวัน ในเวลาเที่ยงคืนหรือหลังจากนั้นเล็กน้อยในท้องถิ่น เพื่อจัดสรรงบประมาณของวันถัดไปให้ได้มากที่สุด หมายเหตุ แต่ข้อมูลที่ดึงรายงาน เช่น ค่าใช้จ่าย อาจล่าช้าประมาณ 3 ดังนั้นพารามิเตอร์ costSoFar จึงอาจอ้างอิงยอดรวมของเมื่อวานเป็นเวลา สคริปต์ที่กำหนดให้ทำงานหลังเที่ยงคืน

ตั้งค่า

  • คลิกปุ่มด้านล่างเพื่อสร้างสคริปต์ในบัญชี Google Ads

    ติดตั้งเทมเพลตสคริปต์

  • บันทึกสคริปต์และคลิกปุ่มแสดงตัวอย่าง สคริปต์นี้ (โดย ค่าเริ่มต้น) จำลองกลยุทธ์งบประมาณที่มี 15,000 บาทใน 10 วัน เอาต์พุตบันทึก แสดงวันที่จำลอง งบประมาณที่จัดสรรสำหรับวันนั้น และ จำนวนเงินทั้งหมดที่ใช้จ่ายจนถึงปัจจุบัน

ซอร์สโค้ด

// 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 Flexible Budgets
 *
 * @overview The Flexible budgets script dynamically adjusts campaign budget for
 *     an advertiser account with a custom budget distribution scheme on a daily
 *     basis. See
 *     https://developers.google.com/google-ads/scripts/docs/solutions/flexible-budgets
 *     for more details.
 *
 * @author Google Ads Scripts Team [adwords-scripts@googlegroups.com]
 *
 * @version 2.1
 *
 * @changelog
 * - version 2.1
 *   - Split into info, config, and code.
 * - version 2.0
 *   - Updated to use new Google Ads scripts features.
 * - version 1.0.3
 *   - Add support for video and shopping campaigns.
 * - version 1.0.2
 *   - Use setAmount on the budget instead of campaign.setBudget.
 * - version 1.0.1
 *   - Improvements to time zone handling.
 * - version 1.0
 *   - Released initial version.
 */

/**
 * Configuration to be used for the Flexible Budgets script.
 */

CONFIG = {
  'total_budget': 500,
  'campaign_name': 'Special Promotion',
  'start_date': 'November 1, 2021 0:00:00 -0500',
  'end_date': 'December 1, 2021 0:00:00 -0500'
};

const TOTAL_BUDGET = CONFIG.total_budget;
const CAMPAIGN_NAME = CONFIG.campaign_name;
const START_DATE = new Date(CONFIG.start_date);
const END_DATE = new Date(CONFIG.end_date);

function main() {
  testBudgetStrategy(calculateBudgetEvenly, 10, 500);
//  setNewBudget(calculateBudgetEvenly, CAMPAIGN_NAME, TOTAL_BUDGET,
//      START_DATE, END_DATE);
}

function setNewBudget(budgetFunction, campaignName, totalBudget, start, end) {
  const today = new Date();
  if (today < start) {
    console.log('Not ready to set budget yet');
    return;
  }
  const campaign = getCampaign(campaignName);
  const costSoFar = campaign.getStatsFor(
        getDateStringInTimeZone('yyyyMMdd', start),
        getDateStringInTimeZone('yyyyMMdd', end)).getCost();
  const daysSoFar = datediff(start, today);
  const totalDays = datediff(start, end);
  const newBudget = budgetFunction(costSoFar, totalBudget, daysSoFar,
                                   totalDays);
  campaign.getBudget().setAmount(newBudget);
}

function calculateBudgetEvenly(costSoFar, totalBudget, daysSoFar, totalDays) {
  const daysRemaining = totalDays - daysSoFar;
  const budgetRemaining = totalBudget - costSoFar;
  if (daysRemaining <= 0) {
    return budgetRemaining;
  } else {
    return budgetRemaining / daysRemaining;
  }
}

function calculateBudgetWeighted(costSoFar, totalBudget, daysSoFar,
    totalDays) {
  const daysRemaining = totalDays - daysSoFar;
  const budgetRemaining = totalBudget - costSoFar;
  if (daysRemaining <= 0) {
    return budgetRemaining;
  } else {
    return budgetRemaining / (2 * daysRemaining - 1);
  }
}

function testBudgetStrategy(budgetFunc, totalDays, totalBudget) {
  let daysSoFar = 0;
  let costSoFar = 0;
  while (daysSoFar <= totalDays + 2) {
    const newBudget = budgetFunc(costSoFar, totalBudget, daysSoFar, totalDays);
    console.log(`Day ${daysSoFar + 1} of ${totalDays}, new budget ` +
                `${newBudget}, cost so far ${costSoFar}`);
    costSoFar += newBudget;
    daysSoFar += 1;
  }
}

/**
 * Returns number of days between two dates, rounded up to nearest whole day.
 */
function datediff(from, to) {
  const millisPerDay = 1000 * 60 * 60 * 24;
  return Math.ceil((to - from) / millisPerDay);
}

function getDateStringInTimeZone(format, date, timeZone) {
  date = date || new Date();
  timeZone = timeZone || AdsApp.currentAccount().getTimeZone();
  return Utilities.formatDate(date, timeZone, format);
}

/**
 * Finds a campaign by name, whether it is a regular, video, or shopping
 * campaign, by trying all in sequence until it finds one.
 *
 * @param {string} campaignName The campaign name to find.
 * @return {Object} The campaign found, or null if none was found.
 */
function getCampaign(campaignName) {
  const selectors = [AdsApp.campaigns(), AdsApp.videoCampaigns(),
      AdsApp.shoppingCampaigns()];
  for (const selector of selectors) {
    const campaignIter = selector
        .withCondition(`CampaignName = "${campaignName}"`)
        .get();
    if (campaignIter.hasNext()) {
      return campaignIter.next();
    }
  }
  throw new Error(`Could not find specified campaign: ${campaignName}`);
}