Pessoal, esse script não está devolvendo o valor de custo, no entanto na campanha tem custo a ser mostrado no entanto não está mostrando na planilha
const START_DATE = "20250101"; // Data de início para a busca de dados
const END_DATE = "20291231"; // Data de término para a busca de dados
/**
* Formata um valor em micros (inteiros) para o formato de moeda decimal (ex: 1.234.567 -> 1,23).
* Retorna "0,00" se o valor for inválido ou nulo.
* @param {number} value O valor em micros.
* @returns {string} O valor formatado como string de moeda.
*/
function formatMicros(value) {
if (value === undefined || value === null || isNaN(value)) {
// Logger.log("formatMicros: Valor de entrada inválido ou nulo. Recebido: " + value); // Desativado para logs mais limpos, ative para debug
return "0,00";
}
const micros = parseFloat(value / 1000000).toFixed(2).replace(".", ",");
// Logger.log("formatMicros: Entrada original: " + value + ", Saída formatada: " + micros); // Desativado para logs mais limpos, ative para debug
return micros;
}
/**
* Função principal para buscar dados do Google Ads e inseri-los/atualizá-los na planilha.
*/
function main() {
// URL da sua planilha e nome da aba
var spreadsheetUrl = '
https://docs.google.com/spreadsheets/d/1dFZgomOvAtqMcrVg_cFnZ03S-1xAfJ-du7FmiVtperI/';
var spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
var ss = spreadsheet.getSheetByName('base-google_ads');
// Define o cabeçalho da planilha (apenas se a primeira linha estiver vazia ou incorreta)
var currentHeader = ss.getRange(1, 1, 1, ss.getLastColumn()).getValues()[0];
var expectedHeader = ["Data", "Fonte", "Campanha", "Tipo de Campanha", "Impressões", "Cliques", "Custo", "Conversões"];
if (currentHeader.join(',') !== expectedHeader.join(',')) {
ss.getRange(1, 1, 1, expectedHeader.length).setValues([expectedHeader]);
Logger.log("Cabeçalho da planilha atualizado.");
} else {
Logger.log("Cabeçalho da planilha já está correto.");
}
// --- Leitura dos dados existentes na planilha ---
// Mapeia os dados existentes para facilitar a atualização
// Chave: "YYYYMMDD|Nome da Campanha" (Ex: "20250101|Campanha de Vendas")
// Valor: Número da linha na planilha
var existingDataMap = {};
var dataToUpdate = []; // Array para armazenar as linhas que precisam ser atualizadas
var newRows = []; // Array para armazenar as novas linhas a serem adicionadas
// Pega todos os valores da planilha, exceto o cabeçalho
var range = ss.getDataRange();
var values = range.getValues();
Logger.log("Lendo " + (values.length - 1) + " linhas existentes na planilha...");
for (var i = 1; i < values.length; i++) { // Começa da linha 1 (índice 1) para pular o cabeçalho
var row = values[i];
var rowDate = Utilities.formatDate(new Date(row[0]), AdsApp.currentAccount().getTimeZone(), 'yyyyMMdd');
var rowSource = row[1]; // Coluna 'Fonte'
var rowCampaign = row[2]; // Coluna 'Campanha'
// Apenas mapeia dados do Google dentro do período de interesse
if (rowSource === 'Google' && rowDate >= START_DATE && rowDate <= END_DATE) {
var key = rowDate + '|' + rowCampaign;
existingDataMap[key] = i + 1; // Guarda o número da linha (índice + 1)
}
}
Logger.log("Mapeamento de " + Object.keys(existingDataMap).length + " linhas existentes do Google Ads concluído.");
// --- Busca de novos dados no Google Ads ---
var query = `
SELECT
campaign.name,
campaign.advertising_channel_type,
segments.date,
metrics.impressions,
metrics.clicks,
metrics.cost_micros,
metrics.conversions
FROM campaign
WHERE segments.date BETWEEN '${START_DATE}' AND '${END_DATE}'`;
Logger.log("Executando query GAQL: " + query);
var result = AdsApp.search(query);
Logger.log("Busca de dados do Google Ads iniciada.");
// --- Processa os resultados da busca ---
while (result.hasNext()) {
var row = result.next();
var segmentDate = row.segments.date || "";
var campaignName =
row.campaign.name || "";
var campaignType = row.campaign.advertising_channel_type || "";
var impressions = row.metrics.impressions || 0;
var clicks = row.metrics.clicks || 0;
var conversions = row.metrics.conversions || 0;
// Pega o custo bruto e o formata
var costMicrosRaw = row.metrics.cost_micros;
var cost = (costMicrosRaw !== undefined && costMicrosRaw !== null) ? costMicrosRaw : 0; // Se for undefined/null, assume 0
var formattedCost = formatMicros(cost);
var currentKey = segmentDate + '|' + campaignName;
// Se a linha já existe na planilha
if (existingDataMap.hasOwnProperty(currentKey)) {
var rowIndex = existingDataMap[currentKey]; // Obtém o número da linha (base 1)
var currentRow = values[rowIndex - 1]; // Pega a linha completa da planilha (base 0)
// Compara os valores para ver se precisam de atualização
// Apenas atualiza se houver alguma diferença nas métricas
if (currentRow[4] !== impressions ||
currentRow[5] !== clicks ||
currentRow[6] !== formattedCost || // Comparar o custo formatado
currentRow[7] !== conversions) {
// Prepara a linha para atualização. Colunas 4-7 são as métricas.
dataToUpdate.push({
range: ss.getRange(rowIndex, 5, 1, 4), // Colunas E (Impressões) até H (Conversões)
values: [[impressions, clicks, formattedCost, conversions]]
});
Logger.log("Linha existente para " + currentKey + " marcada para atualização.");
}
// Remove a chave do mapa para saber o que sobrou (se precisar remover depois)
delete existingDataMap[currentKey];
} else {
// Se a linha não existe, é uma nova linha a ser adicionada
newRows.push([
segmentDate,
'Google',
campaignName,
campaignType,
impressions,
clicks,
formattedCost,
conversions
]);
Logger.log("Nova linha para " + currentKey + " marcada para adição.");
}
}
Logger.log("Processamento de dados do Google Ads concluído.");
// --- Aplica as atualizações e adições na planilha ---
// 1. Atualiza as linhas existentes
if (dataToUpdate.length > 0) {
Logger.log("Iniciando atualização de " + dataToUpdate.length + " linhas existentes...");
// Para otimizar, o ideal seria agrupar as atualizações por ranges contíguos
// Mas para um número moderado de atualizações, fazer um a um é aceitável.
dataToUpdate.forEach(function(update) {
update.range.setValues(update.values);
});
Logger.log("Atualização de linhas existentes concluída.");
} else {
Logger.log("Nenhuma linha existente precisou de atualização.");
}
// 2. Adiciona as novas linhas
if (newRows.length > 0) {
var startRow = ss.getLastRow() + 1;
var numColumns = newRows[0].length;
ss.getRange(startRow, 1, newRows.length, numColumns).setValues(newRows);
Logger.log("Total de " + newRows.length + " novas linhas adicionadas à planilha a partir da linha " + startRow + ".");
} else {
Logger.log("Nenhuma nova linha para adicionar.");
}
// --- Opcional: Remover linhas que não foram atualizadas (dados antigos) ---
// As chaves que restaram em 'existingDataMap' representam linhas na planilha
// que estavam lá antes, mas não foram encontradas na busca mais recente do Google Ads.
// Isso pode ser útil para limpar dados de campanhas deletadas ou dados fora do período da busca,
// mas requer cuidado para não apagar informações que você deseja manter (de outras fontes, por exemplo).
// Descomente e ajuste com cautela se precisar dessa funcionalidade.
/*
var rowsToDelete = [];
for (var key in existingDataMap) {
var rowIndex = existingDataMap[key];
// Certifique-se que o dado é do Google e está dentro do período que você está gerenciando
// Para evitar apagar dados de outras fontes ou períodos
var rowInSheet = values[rowIndex - 1]; // Pega a linha original
var rowDateInSheet = Utilities.formatDate(new Date(rowInSheet[0]), AdsApp.currentAccount().getTimeZone(), 'yyyyMMdd');
var rowSourceInSheet = rowInSheet[1];
if (rowSourceInSheet === 'Google' && rowDateInSheet >= START_DATE && rowDateInSheet <= END_DATE) {
rowsToDelete.push(rowIndex);
}
}
// Deleta as linhas de baixo para cima para não invalidar os índices
rowsToDelete.sort(function(a, b){return b-a});
if (rowsToDelete.length > 0) {
Logger.log("Iniciando exclusão de " + rowsToDelete.length + " linhas obsoletas...");
rowsToDelete.forEach(function(rowIndex) {
ss.deleteRow(rowIndex);
Logger.log("Linha " + rowIndex + " (obsoleta) deletada.");
});
Logger.log("Exclusão de linhas obsoletas concluída.");
} else {
Logger.log("Nenhuma linha obsoleta para deletar.");
}
*/
Logger.log("Script 'main' concluído.");
}