Esta página aborda várias práticas recomendadas de desenvolvimento com os scripts do Google Ads.
Seletores
Filtre com seletores
Quando possível, use filtros para solicitar somente as entidades de que você precisa. A aplicação de filtros adequados proporciona estas vantagens:
- O código é mais simples e mais fácil de entender.
- O script é executado muito mais rápido.
Compare os snippets de código a seguir:
Abordagem de codificação | Snippet de código |
---|---|
Filtrar usando seletores (recomendado) |
var keywords = AdsApp.keywords() .withCondition('Clicks > 10') .forDateRange('LAST_MONTH') .get(); while (keywords.hasNext()) { var keyword = keywords.next(); // Do work here. } |
Filtrar código (não recomendado) |
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. } } |
A segunda abordagem não é recomendada porque tenta recuperar a lista de todas as palavras-chave da sua conta apenas para aplicar um filtro a ela.
Evite atravessar a hierarquia de campanhas
Quando você quiser recuperar entidades em um nível específico, use uma coleção nesse nível, em vez de atravessar toda a hierarquia da campanha. Em além de ser mais simples, ele também terá um desempenho muito melhor: o sistema não precisará ler desnecessariamente todas as campanhas e grupos de anúncios.
Compare os seguintes snippets de código que extraem todos os anúncios da sua conta:
Abordagem de codificação | Snippet de código |
---|---|
Usar o método de coleta adequado (recomendado) |
var ads = AdsApp.ads(); |
Percorrer a hierarquia (não recomendado) |
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. } } |
A segunda abordagem não é recomendada, porque tenta buscar hierarquias inteiras de objetos (campanhas, grupos de anúncios), enquanto apenas anúncios são necessários.
Use métodos do assistente de acesso pai específicos
Às vezes você precisa obter a entidade mãe de um objeto recuperado. Nesse caso, você deve usar um método de acessador fornecido em vez de buscar hierarquias inteiras.
Compare os snippets de código a seguir que recuperam os grupos de anúncios que ter anúncios de texto com mais de 50 cliques no mês passado:
Abordagem de codificação | Snippet de código |
---|---|
Usar o método de acesso pai apropriado (recomendado) |
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. } |
Percorrer a hierarquia (não recomendado) |
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. } } } |
A segunda abordagem não é recomendada, porque busca toda a campanha e hierarquias de grupos de anúncios na sua conta, enquanto você precisa de apenas um subconjunto campanhas e grupos de anúncios associados ao seu conjunto de anúncios. A primeira abordagem se limita a buscar apenas a coleção de anúncios relevante e usa um método adequado para acessar os objetos pai.
Use filtros pai específicos
Para acessar entidades em uma campanha ou um grupo de anúncios específico, use um filtro específico no seletor em vez de buscar e percorrer uma hierarquia.
Compare os seguintes snippets de código que recuperam a lista de anúncios de texto em uma campanha e um grupo de anúncios especificados com mais de 50 cliques no mês passado.
Abordagem de codificação | Snippet de código |
---|---|
Usar filtros adequados no nível pai (recomendado) |
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. } |
Percorrer a hierarquia (não recomendado) |
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. } } } |
A segunda abordagem não é recomendada, porque itera na hierarquia de campanhas e grupos de anúncios na sua conta, enquanto você precisa apenas de um conjunto selecionado de anúncios e as campanhas e grupos de anúncios principais. A primeira abordagem limita a iteração à lista de anúncios aplicando um filtro específico para entidades mães no seletor.
Use IDs para filtrar quando possível
Ao filtrar entidades, é preferível filtrar por entidades por em vez de outros campos.
Considere os snippets de código a seguir que selecionam uma campanha.
Abordagem de codificação | Snippet de código |
---|---|
Filtrar por ID (recomendado) |
var campaign = AdsApp.campaigns() .withIds([12345]) .get() .next(); |
Filtrar por nome (menos ideal) |
var campaign = AdsApp.campaigns() .withCondition('Name="foo"') .get() .next(); |
A segunda abordagem é menos ideal, pois estamos filtrando por um campo que não é o ID.
Filtre por IDs parentais quando possível
Ao selecionar uma entidade, filtre por IDs pai sempre que possível. Isso vai tornar suas consultas mais rápidas, limitando a lista de entidades que estão sendo recuperadas pelos servidores ao filtrar os resultados.
Considere o snippet de código a seguir, que recupera um grupo de anúncios pelo ID. Suponha que o ID da campanha principal seja conhecido.
Abordagem de codificação | Snippet de código |
---|---|
Filtrar por IDs de campanhas e grupos de anúncios (recomendado) |
var adGroup = AdsApp.adGroups() .withIds([12345]) .withCondition('CampaignId="54678"') .get() .next(); |
Filtrar apenas pelo ID do grupo de anúncios (menos ideal) |
var adGroup = AdsApp.adGroups() .withIds([12345]) .get() .next(); |
Embora os dois snippets de código apresentem resultados idênticos, a filtragem
adicional no snippet de código 1 usando um ID pai (CampaignId="54678")
torna o
código mais eficiente, restringindo a lista de entidades que o servidor
precisa iterar ao filtrar os resultados.
Use rótulos quando existirem muitas condições de filtragem
Quando você tem muitas condições de filtragem, é uma boa ideia criar uma para as entidades processadas e use esse rótulo para filtrar suas entidades.
Considere o snippet de código a seguir que recupera uma lista de campanhas pelo nome.
Abordagem de codificação | Snippet de código |
---|---|
Usar um rótulo (recomendado) |
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 } |
Criar seletores complexos (não recomendado) |
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. } |
Ambos os snippets de código oferecem um nível de desempenho semelhante, tende a gerar códigos mais complexos, pois o número de condições em seu seletor aumenta. Também é mais fácil aplicar o rótulo a uma nova entidade editar o script para incluir uma nova entidade.
Limite o número de condições na sua cláusula IN
Ao executar scripts, um caso de uso comum é gerar um relatório para uma lista de entidades. Os desenvolvedores geralmente conseguem isso construindo um Consulta AWQL que filtra os IDs de entidade usando uma cláusula IN. Essa abordagem funciona bem quando o número de entidades é limitado. No entanto, à medida que o comprimento da consulta aumenta, a performance do script se deteriora por dois motivos:
- A análise de uma consulta mais longa demora mais.
- Cada ID adicionado a uma cláusula IN é uma condição extra a ser avaliada e, portanto, leva mais tempo.
Nessas condições, é preferível aplicar um rótulo às entidades, e
e filtre por LabelId
.
Abordagem de codificação | Snippet de código |
---|---|
Aplicar um rótulo e filtrar por labelID (recomendado) |
// 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() + '"'); |
Criar uma consulta longa usando a cláusula IN (não recomendada) |
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…)'); |
Atualizações da conta
Alterações em lote
Quando você faz mudanças em uma entidade do Google Ads, os scripts do Google Ads não executam a mudança imediatamente. Em vez disso, ele tenta combinar várias mudanças lotes, para que seja possível emitir uma única solicitação que faça várias alterações. Essa abordagem torna seus scripts mais rápidos e reduz a carga no Google Ads servidores. No entanto, alguns padrões de código forçam os scripts do Google Ads a transferir o lote de operações com frequência, fazendo com que o script seja executado lentamente.
Considere o script a seguir que atualiza os lances de uma lista de palavras-chave.
Abordagem de codificação | Snippet de código |
---|---|
Acompanhar os elementos atualizados (recomendado) |
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()); } |
Recuperar elementos atualizados em um loop curto (não recomendado) |
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()); } |
A segunda abordagem não é recomendada, porque a chamada para
keyword.bidding().getCpc()
força os scripts do Google Ads a limpar o setCpc()
e executar apenas uma operação por vez. A primeira abordagem, embora
semelhante à segunda, tem o benefício adicional de oferecer suporte a lotes,
já que a chamada getCpc()
é feita em um loop separado do que é chamado
setCpc()
.
Use criadores quando possível
Os scripts do Google Ads são compatíveis com duas maneiras de criar novos objetos: criadores e criação métodos. Os builders são mais flexíveis do que os métodos de criação, já que oferecem acesso ao objeto criado pela chamada de API.
Considere estes snippets de código:
Abordagem de codificação | Snippet de código |
---|---|
Usar builders (recomendado) |
var operation = adGroup.newKeywordBuilder() .withText('shoes') .build(); var keyword = operation.getResult(); |
Usar métodos de criação (não recomendado) |
adGroup.createKeyword('shoes'); var keyword = adGroup.keywords() .withCondition('KeywordText="shoes"') .get() .next(); |
A segunda abordagem não é a preferida devido à operação de seleção extra envolvida na recuperação da palavra-chave. Além disso, os métodos de criação também foram descontinuados.
No entanto, lembre-se de que os builders, quando usados incorretamente, podem impedir que os scripts do Google Ads façam a agrupamento de operações.
Considere os snippets de código a seguir que criam uma lista de palavras-chave, e imprime o ID das palavras-chave recém-criadas:
Abordagem de codificação | Snippet de código |
---|---|
Acompanhar os elementos atualizados (recomendado) |
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()); } |
Recuperar elementos atualizados em um loop apertado (não recomendado) |
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()); } |
A segunda abordagem não é a preferida porque chama operation.getResult()
no mesmo loop que cria a operação, forçando os scripts do Google Ads
a executar uma operação por vez. A primeira abordagem, embora semelhante, permite
agrupamento, já que chamamos operation.getResult() em um loop diferente de onde
ele foi criado.
Considere usar uploads em massa para atualizações grandes
Uma tarefa comum que os desenvolvedores realizam é gerar relatórios e atualizar propriedades de entidade, como lances de palavras-chave, com base nos valores de performance atuais. Quando
você precisa atualizar um grande número de entidades, os uploads em massa tendem a oferecer
a performance. Por exemplo, considere os scripts a seguir que aumentam
o CPC máximo das palavras-chave com TopImpressionPercentage > 0.4
no último mês:
Abordagem de codificação | Snippet de código |
---|---|
Usar upload em massa (recomendado) |
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(); |
Selecionar e atualizar palavras-chave por ID (menos ideal) |
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); } } |
Embora a segunda abordagem ofereça uma performance muito boa, a primeira é a preferida neste caso, porque
Os scripts do Google Ads têm um limite no número de objetos que podem ser recuperados ou atualizados em uma única execução, e as operações de seleção e atualização na segunda abordagem contam para esse limite.
Os uploads em massa têm limites maiores em termos de número de entidades que podem atualização e o tempo total de execução.
Agrupe seus uploads em massa por campanhas
Ao criar seus uploads em massa, tente agrupar suas operações pelo pai campanha. Isso aumenta a eficiência e diminui a chance de erros de mudanças ou simultaneidade conflitantes.
Considere duas tarefas de upload em massa executadas em paralelo. Um deles pausa anúncios em um anúncio group; o outro ajusta os lances de palavras-chave. Mesmo que as operações não estejam relacionadas, elas podem ser aplicadas a entidades do mesmo grupo de anúncios (ou dois grupos de anúncios diferentes na mesma campanha). Quando isso acontece, o sistema bloqueia a entidade pai (o grupo de anúncios ou a campanha compartilhada), fazendo com que as tarefas de upload em massa se bloqueiem.
Os scripts do Google Ads podem otimizar a execução em uma única tarefa de upload em massa. Portanto, o mais simples é executar apenas uma tarefa de upload em massa por conta por vez. Se você decidir fazer mais de um upload em massa por conta, verifique se os uploads em massa operam em uma lista de campanhas mutuamente exclusivas (e as entidades filhas) para uma performance ideal.
Relatórios
Use relatórios para buscar estatísticas
Quando você quer recuperar grandes quantidades de entidades e as estatísticas delas, é melhor usar relatórios em vez de métodos padrão do AdsApp. O uso de relatórios é preferido pelos seguintes motivos:
- Os relatórios têm melhor desempenho em consultas grandes.
- Os relatórios não atingem cotas de busca normais.
Compare os snippets de código a seguir que buscam métricas de cliques, impressões e Custo e texto de todas as palavras-chave que receberam mais de 50 cliques no mês passado:
Abordagem de codificação | Snippet de código |
---|---|
Usar relatórios (recomendado) |
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); } |
Usar iteradores do AdsApp (não recomendado) |
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()); } |
A segunda abordagem não é a preferida porque itera as palavras-chave
e recupera as estatísticas uma entidade por vez. Os relatórios apresentam desempenho mais rápido nesse
já que ele busca todos os dados em uma única chamada e os transmite como
obrigatórios. Além disso, as palavras-chave recuperadas na segunda abordagem são
contabilizadas na cota do script para o número de entidades recuperadas usando
uma chamada get()
.
Usar a pesquisa em vez do relatório
O método de relatório foi criado para a infraestrutura antiga e vai gerar resultados em um formato simples, mesmo que você esteja usando o GAQL. Isso significa que ele precisa transformar os resultados da consulta para corresponder ao estilo antigo, que não é tem suporte em todos os campos e adiciona sobrecarga a cada chamada.
Sugerimos que você use a pesquisa para aproveitar todos os recursos da os novos relatórios da API Google Ads.
Prefira GAQL a AWQL
Embora a AWQL ainda seja compatível com consultas de relatórios e chamadas withCondition
,
ele é executado em uma camada de conversão que não tem compatibilidade total
com uma AWQL verdadeira. Para ter controle total sobre suas consultas, use o GAQL.
Se você tiver consultas AWQL que gostaria de traduzir, temos uma ferramenta de migração de consultas para ajudar.
Não selecione mais linhas do que o necessário
A velocidade de execução de relatórios (e seletores) baseia-se no número total de linhas que seriam retornadas pelo relatório, independentemente de você iterar elas. Isso significa que você sempre deve usar filtros específicos para minimizar ao máximo o conjunto de resultados de acordo com seu caso de uso.
Por exemplo, suponha que você queira encontrar grupos de anúncios com lances fora de em um intervalo específico. Seria mais rápido fazer duas consultas separadas, uma para lances abaixo do limite mínimo e outra para lances acima do limite máximo, do que buscar todos os grupos de anúncios e ignorar aqueles em que você não tem interesse.
Abordagem de codificação | Snippet de código |
---|---|
Usar duas consultas (recomendado) |
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); } |
Filtrar uma consulta genérica (não recomendado) |
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); } } |
Scripts do Gerenciador de anúncios (MCC)
Prefira executar em paralelo em vez de em série
Ao criar scripts para contas de administrador, use executeInParallel()
de execução em série quando possível. O executeInParallel()
deixa o script mais
tempo de processamento (até uma hora) e até 30 minutos por conta processada
em vez de 30 minutos combinados para a execução em série. Veja nossos limites
para mais detalhes.
Planilhas
Use operações em lote ao atualizar planilhas
Ao atualizar planilhas, tente usar os métodos de operação em massa
(por exemplo, getRange()
) em métodos que atualizam uma célula por vez.
Considere o snippet de código abaixo, que gera um padrão fractal em uma planilha.
Abordagem de codificação | Snippet de código |
---|---|
Atualizar um intervalo de células em uma única chamada (recomendado) |
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); |
Atualizar uma célula por vez (não recomendado) |
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(); } |
Enquanto as planilhas do Google tentam otimizar o segundo snippet de código armazenando em cache valores, ainda assim você terá um desempenho ruim em comparação com o primeiro snippet, devido com o número de chamadas de API feitas.