Orçamentos flexíveis: conta única

Ícone de ferramentas

O Google Ads permite definir um valor de orçamento diário para cada campanha. No entanto, alguns iniciativas de marketing terão um custo fixo associado a elas; por exemplo, "Quero gastar US $5.000 com nossas vendas de outono." A estratégia de lances oferece a você algum controle sobre como o orçamento diário é gasto, mas nenhum controle sobre como o orçamento é consumido durante a campanha.

Por exemplo, se quisermos gastar apenas US $5.000 para anunciar nossa venda de outono e anunciar por 10 dias, poderíamos definir um orçamento diário de US $500 para usar todo o orçamento. No entanto, isso pressupõe que gastaremos todo o valor cada dia E quisermos gastá-lo por igual. Não é possível informar ao Google Ads que você quer gastar a maior parte do orçamento durante os últimos dias.

Este script ajustará dinamicamente o orçamento diário da sua campanha com um esquema personalizado de distribuição do orçamento.

Como funciona

Teste de estratégias de orçamento

O script inclui um código de teste para simular os efeitos da execução vários dias. Isso dá uma ideia melhor do que pode acontecer quando o script está programado para ser executado diariamente durante um período.

Por padrão, esse script simula uma distribuição uniforme de um orçamento de US $500 em 10 dias.

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

A chamada de função setNewBudget é comentada, indicando que ela será executada apenas o código de teste. Aqui está a saída do exemplo:

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

Todos os dias, o script calcula um novo orçamento para garantir que o gasto do orçamento seja distribuídos de maneira uniforme. Quando o limite do orçamento alocado é atingido, o orçamento é definido para zero, interrompendo os gastos.

Você pode alterar a estratégia de orçamento usada mudando a função usada ou a modificação da própria função. O script vem com duas estratégias pré-criadas: calculateBudgetEvenly e calculateBudgetWeighted. Para definir um teste ponderado estratégia de orçamento, mude testBudgetStrategy da seguinte maneira:

testBudgetStrategy(calculateBudgetWeighted, 10, 500);

Clique em Visualizar e verifique a saída do registro. Essa estratégia de orçamento aloca menos orçamento no início do período e mais durante os últimos dias.

Você pode usar esse método de teste para simular alterações feitas nas funções de cálculo do orçamento e testar sua própria abordagem na distribuição de um orçamento.

Alocação de um orçamento

A estratégia de orçamento calculateBudgetWeighted é implementada pelas seguintes função:

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) ;
  }
}

Essa função usa estes argumentos:

costSoFar
Custo acumulado da campanha de START_DATE até hoje.
totalBudget
Gasto alocado de START_DATE para END_DATE.
daysSoFar
Dias decorridos entre START_DATE e hoje.
totalDays
Número total de dias entre START_DATE e END_DATE.

Você pode escrever sua própria função, desde que ela use esses argumentos. Usando esses valores, você pode comparar quanto gastou em dinheiro até agora com quanto deve gastar no geral e determinar em que ponto está no momento dentro do cronograma de todo o orçamento.

Em particular, essa estratégia de orçamento identifica quanto orçamento resta (totalBudget - costSoFar) e divide esse valor pelo dobro do número de dias restantes. Ela pondera a distribuição do orçamento mais para o final do campanha. Usando o custo desde START_DATE, ela também considera a "lenta" dias" em que o orçamento definido não é totalmente gasto.

Criação de um orçamento de verdade

Quando estiver feliz com sua estratégia de orçamento, você precisará fazer algumas alterações antes de programar a execução diária dele.

Primeiro, atualize as constantes no início do arquivo:

  • START_DATE: defina como o início da sua estratégia de orçamento. Ela deve ser a data atual ou um dia no passado.
  • END_DATE: defina como o último dia em que você quer anunciar usando esse orçamento.
  • TOTAL_BUDGET: o valor total que você está tentando gastar. Esse valor está em moeda da conta e pode ser excedido dependendo de quando o script for programado para execução.
  • CAMPAIGN_NAME: o nome da campanha a que a estratégia de orçamento deve ser aplicada.

Em seguida, desative o teste e ative a lógica para alterar efetivamente o orçamento:

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

Agendamento

Agende este script para ser executado diariamente, à meia-noite ou pouco depois no fuso horário local, para que ele direcione o máximo possível o orçamento do dia seguinte. Observação: No entanto, os dados de relatórios recuperados, como custo, podem ter um atraso de cerca de três horas. Portanto, o parâmetro costSoFar pode estar fazendo referência ao total do dia anterior para um que está programado para ser executado após a meia-noite.

Configuração

  • Clique no botão abaixo para criar o script na sua conta do Google Ads.

    Instalar o modelo de script

  • Salve o script e clique no botão Visualizar. Este script (por padrão) simula uma estratégia de orçamento com US $500 em 10 dias. A saída do logger reflete o dia que está sendo simulado, o orçamento alocado para aquele dia e o valor total gasto até o momento.

Código-fonte

// 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}`);
}