Pular para o conteúdo

Receita: exportar para planilha

Objetivo: gravar a série diária de um período num arquivo CSV com valores já convertidos de micros, que abre direto em planilha em português.

  • O mesmo preparo das receitas anteriores: chave de API, OWIEW_API_URL e as ferramentas da sua linguagem.
  • Uma pasta onde gravar o arquivo serie-diaria.csv.
  1. Troca a chave por um token.
  2. Lê GET /v1/t/{tenantID}/insights/daily com since e until. A resposta traz points,, uma linha por dia.
  3. Converte micros em decimais com inteiros e grava o CSV com ; como separador e vírgula como separador decimal, que é o que o Excel em português espera. O arquivo leva a marca UTF-8 (BOM) para os acentos abrirem certos.

Cada linha do arquivo tem: data;moeda;gasto;impressoes;cliques;conversoes.

Não exporte CPA nem ROAS por dia para somar depois. Se precisar deles, calcule na planilha a partir das colunas de totais, depois de somar o período.

exportar.sh
set -euo pipefail
SINCE="${1:-2026-09-01}"
UNTIL="${2:-2026-09-30}"
TOKEN_JSON=$(curl -sS -X POST "$OWIEW_API_URL/v1/token" \
-H "Authorization: Bearer $OWIEW_API_KEY")
TOKEN=$(echo "$TOKEN_JSON" | jq -r .access_token)
TENANT=$(echo "$TOKEN_JSON" | jq -r .tenant_id)
printf '\xef\xbb\xbf' > serie-diaria.csv
echo "data;moeda;gasto;impressoes;cliques;conversoes" >> serie-diaria.csv
curl -sS "$OWIEW_API_URL/v1/t/$TENANT/insights/daily?since=$SINCE&until=$UNTIL" \
-H "Authorization: Bearer $TOKEN" \
| jq -r '
def dec: ((. + 5000) / 10000 | floor) as $c
| "\($c / 100 | floor),\($c % 100 | tostring | if length < 2 then "0" + . else . end)";
.points[]
| [.date, .currency, (.spend_micros | dec), .impressions, .clicks, (.conversions_micros | dec)]
| join(";")' >> serie-diaria.csv
wc -l serie-diaria.csv
exportar.mjs
import { writeFileSync } from "node:fs";
const BASE = process.env.OWIEW_API_URL ?? "https://dash.owiew.com";
const CHAVE = process.env.OWIEW_API_KEY;
if (!CHAVE) throw new Error("Defina OWIEW_API_KEY");
const [since = "2026-09-01", until = "2026-09-30", saida = "serie-diaria.csv"] = process.argv.slice(2);
async function pegarJson(url, opcoes) {
const resposta = await fetch(url, opcoes);
const corpo = await resposta.json().catch(() => null);
if (!resposta.ok) {
const e = corpo?.error ?? {};
throw new Error(`HTTP ${resposta.status} ${e.code ?? ""} (trace_id ${e.trace_id ?? "n/d"})`);
}
return corpo;
}
/** Micros em texto "1234,57" (2 casas, vírgula decimal), só com inteiros. */
function decimal(micros) {
const centavos = (BigInt(micros) + 5_000n) / 10_000n;
return `${centavos / 100n},${(centavos % 100n).toString().padStart(2, "0")}`;
}
const token = await pegarJson(`${BASE}/v1/token`, {
method: "POST",
headers: { Authorization: `Bearer ${CHAVE}` },
});
const url = `${BASE}/v1/t/${token.tenant_id}/insights/daily?since=${since}&until=${until}`;
const { points } = await pegarJson(url, {
headers: { Authorization: `Bearer ${token.access_token}` },
});
const linhas = ["data;moeda;gasto;impressoes;cliques;conversoes"];
for (const p of points) {
linhas.push([p.date, p.currency, decimal(p.spend_micros), p.impressions, p.clicks,
decimal(p.conversions_micros)].join(";"));
}
writeFileSync(saida, "" + linhas.join("\r\n") + "\r\n", "utf8");
console.log(`${points.length} linhas gravadas em ${saida}`);
exportar.py
import os
import sys
import requests
BASE = os.environ.get("OWIEW_API_URL", "https://dash.owiew.com")
CHAVE = os.environ["OWIEW_API_KEY"]
since = sys.argv[1] if len(sys.argv) > 1 else "2026-09-01"
until = sys.argv[2] if len(sys.argv) > 2 else "2026-09-30"
saida = sys.argv[3] if len(sys.argv) > 3 else "serie-diaria.csv"
def checar(r):
if r.ok:
return r.json()
try:
e = r.json().get("error", {})
except ValueError:
e = {}
raise SystemExit(f"HTTP {r.status_code} {e.get('code', '')} (trace_id {e.get('trace_id', 'n/d')})")
def decimal(micros):
"""Micros em texto '1234,57' (2 casas, vírgula decimal), só com inteiros."""
centavos = (micros + 5_000) // 10_000
return f"{centavos // 100},{centavos % 100:02d}"
token = checar(requests.post(f"{BASE}/v1/token", headers={"Authorization": f"Bearer {CHAVE}"}, timeout=30))
r = requests.get(
f"{BASE}/v1/t/{token['tenant_id']}/insights/daily",
params={"since": since, "until": until},
headers={"Authorization": f"Bearer {token['access_token']}"},
timeout=60,
)
pontos = checar(r)["points"]
with open(saida, "w", encoding="utf-8-sig", newline="") as f:
f.write("data;moeda;gasto;impressoes;cliques;conversoes\r\n")
for p in pontos:
f.write(";".join([
p["date"], p["currency"], decimal(p["spend_micros"]),
str(p["impressions"]), str(p["clicks"]), decimal(p["conversions_micros"]),
]) + "\r\n")
print(f"{len(pontos)} linhas gravadas em {saida}")

Um arquivo serie-diaria.csv com o cabeçalho e uma linha por dia (valores de exemplo):

data;moeda;gasto;impressoes;cliques;conversoes
2026-09-01;BRL;1001,23;1000;10;0,50
2026-09-02;BRL;1002,47;2000;20;1,00
2026-09-03;BRL;1003,70;3000;30;1,50

No Excel, use Dados, De Texto/CSV, ou apenas abra o arquivo. No Google Planilhas, use Arquivo, Importar, e escolha ; como separador.

  • Os acentos aparecem quebrados: o arquivo perdeu a marca UTF-8. Use os scripts acima, que a gravam, ou importe escolhendo a codificação UTF-8.
  • Tudo numa coluna só: a planilha espera outro separador. Na importação, escolha ;.
  • Se o cliente tem contas em moedas diferentes, confira a coluna moeda e filtre antes de somar.
  • Datas dos dias mais recentes mudam entre exportações: as plataformas revisam os números. Reexporte e substitua os últimos 28 dias. Veja Unidades e tipos.
  • Períodos com mais de 400 dias: exporte em partes. Veja Janelas de data e paginação.