---
title: "Importar contatos do Google Sheets para a Brevo com Apps Script"
description: "Exemplo repetível de Google Apps Script que verifica consentimento, mapeia campos, preserva descadastros e mostra erros da API da Brevo."
url: https://tajo.io/pt/blog/import-google-sheet-contacts-to-brevo-apps-script/
markdown: https://tajo.io/pt/blog/import-google-sheet-contacts-to-brevo-apps-script.md
lang: pt-BR
author: "Set Noa"
author_url: https://tajo.io/pt/set-noa/
published: 2026-04-30
updated: 2026-10-09
alternates: {en-US: /blog/import-google-sheet-contacts-to-brevo-apps-script.md, bg-BG: /bg/blog/import-google-sheet-contacts-to-brevo-apps-script.md, cs-CZ: /cz/blog/import-google-sheet-contacts-to-brevo-apps-script.md, de-DE: /de/blog/import-google-sheet-contacts-to-brevo-apps-script.md, da-DK: /dk/blog/import-google-sheet-contacts-to-brevo-apps-script.md, es-ES: /es/blog/import-google-sheet-contacts-to-brevo-apps-script.md, fr-FR: /fr/blog/import-google-sheet-contacts-to-brevo-apps-script.md, el-GR: /gr/blog/import-google-sheet-contacts-to-brevo-apps-script.md, hi-IN: /hi/blog/import-google-sheet-contacts-to-brevo-apps-script.md, id-ID: /in/blog/import-google-sheet-contacts-to-brevo-apps-script.md, hr-HR: /hr/blog/import-google-sheet-contacts-to-brevo-apps-script.md, hu-HU: /hu/blog/import-google-sheet-contacts-to-brevo-apps-script.md, it-IT: /it/blog/import-google-sheet-contacts-to-brevo-apps-script.md, ja-JP: /jp/blog/import-google-sheet-contacts-to-brevo-apps-script.md, ko-KR: /kr/blog/import-google-sheet-contacts-to-brevo-apps-script.md, ar-SA: /ar/blog/import-google-sheet-contacts-to-brevo-apps-script.md, nl-NL: /nl/blog/import-google-sheet-contacts-to-brevo-apps-script.md, no-NO: /no/blog/import-google-sheet-contacts-to-brevo-apps-script.md, pl-PL: /pl/blog/import-google-sheet-contacts-to-brevo-apps-script.md, ro-RO: /ro/blog/import-google-sheet-contacts-to-brevo-apps-script.md, ru-RU: /ru/blog/import-google-sheet-contacts-to-brevo-apps-script.md, sv-SE: /se/blog/import-google-sheet-contacts-to-brevo-apps-script.md, zh-CN: /zh-cn/blog/import-google-sheet-contacts-to-brevo-apps-script.md, sl-SI: /sl/blog/import-google-sheet-contacts-to-brevo-apps-script.md, sr-Latn-RS: /sr/blog/import-google-sheet-contacts-to-brevo-apps-script.md, th-TH: /th/blog/import-google-sheet-contacts-to-brevo-apps-script.md, tr-TR: /tr/blog/import-google-sheet-contacts-to-brevo-apps-script.md, ur-PK: /ur/blog/import-google-sheet-contacts-to-brevo-apps-script.md, vi-VN: /vi/blog/import-google-sheet-contacts-to-brevo-apps-script.md, sk-SK: /sk/blog/import-google-sheet-contacts-to-brevo-apps-script.md}
---

[Sincronização de dados](https://tajo.io/pt/blog/?category=data-sync)

# Importar contatos do Google Sheets para a Brevo com Apps Script

Exemplo repetível de Google Apps Script que verifica consentimento, mapeia campos, preserva descadastros e mostra erros da API da Brevo.

google apps script brevo

Como importar contatos do Sheets para o Brevo?

Adicione as colunas email, firstName, lastName e consent à planilha. Defina BREVO\_API\_KEY nas propriedades do script e o ID da lista no código; depois execute syncSheetToBrevo. O script considera apenas linhas com consentimento, verifica descadastros na Brevo, remove duplicatas e para em erros da API. É um Apps Script mantido por você, não um conector nativo.

[Saiba mais](https://tajo.io/pt/blog/import-google-sheet-contacts-to-brevo-apps-script/#prepare-a-planilha-e-a-lista)

| Campo de origem | Campo de destino | Valor de exemplo |
| --- | --- | --- |
| `email` | `email` | `alex@example.com` |
| `firstName` | `FNAME` | `Alex` |
| `lastName` | `LNAME` | `Example` |

Uma planilha com doze inscrições para um evento é fácil de exportar uma vez. Na segunda importação, um endereço aparece duas vezes e outra pessoa já se descadastrou na Brevo. Uma importação repetível precisa detectar ambos os casos.

Este script usa [os endpoints da Brevo para ler, criar e atualizar contatos](https://developers.brevo.com/reference/create-contact). Ele serve para pequenas importações agendadas, não para cargas em massa nem como conector nativo do Google Sheets. Não envia e-mail. A prova de consentimento e a operação do script são suas responsabilidades.

## Prepare a planilha e a lista

Crie uma aba `Contacts` com estes cabeçalhos exatos. Use caixas de seleção para `consent` e marque `TRUE` apenas quando houver permissão para o uso de marketing previsto.

| email | firstName | lastName | consent |
| --- | --- | --- | --- |
| [jane@example.com](mailto:jane@example.com) | Jane | Doe | TRUE |
| [alex@example.com](mailto:alex@example.com) | Alex | Lee | FALSE |

Crie ou escolha uma lista na Brevo e copie o ID numérico para `LIST_ID` no código. Confirme que os atributos `FNAME` e `LNAME` existem na Brevo. São os únicos campos mapeados. Guarde o registro de quando e como o consentimento foi obtido se a planilha não puder comprová-lo. Uma célula `TRUE` não é prova suficiente.

Em **Extensões → Apps Script → Configurações do projeto → Propriedades do script**, adicione `BREVO_API_KEY`. Essas propriedades são compartilhadas entre usuários do script; limite quem pode editá-lo. Não guarde a chave em uma célula nem no código-fonte. Veja as [regras de acesso do Google](https://developers.google.com/apps-script/guides/properties).

## O script

Substitua `Code.gs` por este exemplo e ajuste `LIST_ID` antes da primeira execução.

```javascript
const LIST_ID = 42; // Replace with your existing Brevo list ID.
const TAB = 'Contacts';
const BASE = 'https://api.brevo.com/v3';

function syncSheetToBrevo() {
  const key = PropertiesService.getScriptProperties().getProperty('BREVO_API_KEY');
  if (!key) throw new Error('Set BREVO_API_KEY in Script Properties first');
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(TAB);
  if (!sheet) throw new Error('Contacts tab missing');
  const values = sheet.getDataRange().getValues();
  const headers = values.shift().map(h => String(h).trim());
  const columns = ['email', 'firstName', 'lastName', 'consent']
    .map(name => headers.indexOf(name));
  if (columns.includes(-1)) throw new Error('Required header missing');
  const [emailCol, firstCol, lastCol, consentCol] = columns;
  const seen = new Set();
  const result = { written: 0, skipped: 0 };

  for (const row of values) {
    const email = String(row[emailCol] || '').trim().toLowerCase();
    if (row[consentCol] !== true || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) || seen.has(email)) {
      result.skipped++;
      continue;
    }
    seen.add(email);
    const path = '/contacts/' + encodeURIComponent(email);
    const current = brevo_(key, path, 'get');
    if (current.code !== 200 && current.code !== 404) {
      throw new Error(`Contact read failed (${current.code}) for row ${result.written + result.skipped + 2}`);
    }
    if (current.code === 200) {
      const contact = JSON.parse(current.text);
      if (contact.emailBlacklisted || (contact.listUnsubscribed || []).includes(LIST_ID)) {
        result.skipped++;
        continue;
      }
    }
    const attributes = {};
    if (row[firstCol] !== '') attributes.FNAME = String(row[firstCol]);
    if (row[lastCol] !== '') attributes.LNAME = String(row[lastCol]);
    const body = { attributes, listIds: [LIST_ID] };
    const saved = current.code === 404
      ? brevo_(key, '/contacts', 'post', { email, ...body })
      : brevo_(key, path, 'put', body);
    if (![201, 204].includes(saved.code)) {
      throw new Error(`Contact write failed (${saved.code}) for ${email}: ${saved.text.slice(0, 200)}`);
    }
    result.written++;
  }
  Logger.log(JSON.stringify(result));
  return result;
}

function brevo_(key, path, method, body) {
  for (let attempt = 0; attempt < 3; attempt++) {
    const response = UrlFetchApp.fetch(BASE + path, {
      method,
      contentType: 'application/json',
      headers: { 'api-key': key },
      payload: body ? JSON.stringify(body) : undefined,
      muteHttpExceptions: true,
    });
    const code = response.getResponseCode();
    if (code !== 429) return { code, text: response.getContentText() };
    if (attempt === 2) return { code, text: response.getContentText() };
    const reset = Object.entries(response.getHeaders()).find(
      ([name]) => name.toLowerCase() === 'x-sib-ratelimit-reset'
    );
    const raw = Number(reset && reset[1]);
    const seconds = Number.isFinite(raw) && raw > 0 ? raw : 2 ** attempt;
    const waitSeconds = seconds + 2 ** attempt;
    if (waitSeconds > 60) return { code, text: response.getContentText() };
    Utilities.sleep(waitSeconds * 1000);
  }
}
```

Salve, selecione `syncSheetToBrevo` e clique em **Executar**. O Google pedirá acesso ao Sheets e a solicitações externas. Em **Execuções**, veja o registro final `{written, skipped}`. Uma leitura 404 leva à criação; uma 200 leva à atualização. Outros erros interrompem a execução. Uma gravação bem-sucedida confirma a requisição de contato, não o envio de campanha.

O script elimina e-mails repetidos na mesma execução e consulta a Brevo novamente na próxima. Nunca define `emailBlacklisted` como `false` nem altera o e-mail. Se a Brevo indicar bloqueio global ou descadastro dessa lista, a linha será ignorada mesmo que a planilha mostre `TRUE`. Não use o script para reverter um descadastro. [A Brevo alerta](https://developers.brevo.com/reference/update-contact) que alterar o endereço de um contato bloqueado pode remover o bloqueio.

## Confira uma execução antes de agendar

Use uma lista de teste e contatos que você controla. Rode com uma linha `TRUE`, uma `FALSE` e um e-mail duplicado: espere uma gravação e duas linhas ignoradas. Descadastre o contato de teste na Brevo e rode outra vez: ele não deve receber gravação. Para testar uma falha, ajuste `LIST_ID` temporariamente para um valor inválido, confira o erro HTTP em **Execuções**, restaure o ID e repita. Não teste com clientes reais. O código também foi validado localmente com respostas simuladas da Brevo, sem gravação ao vivo.

Para agendar, abra **Apps Script → Acionadores → Adicionar acionador**, escolha `syncSheetToBrevo` e um intervalo baseado em tempo. [Acionadores instaláveis rodam na conta de quem os criou](https://developers.google.com/apps-script/guides/triggers/installable), que precisa manter acesso à planilha. Comece diariamente para uma planilha pequena e confira falhas. O Google [limita duração e chamadas URL Fetch](https://developers.google.com/apps-script/guides/services/quotas); divida fontes grandes em trabalhos limitados.

Ao receber 429, o script lê `x-sib-ratelimit-reset`, faz no máximo duas novas tentativas e retorna 429 para uma execução posterior se a espera necessária superar 60 segundos. Outros erros param a execução; a próxima rodada começa do início. Um contato pode se descadastrar entre a leitura e a gravação. Use este exemplo somente se essa pequena janela for aceitável. Para garantias mais fortes, combine reconciliação por eventos, uma fonte confiável de consentimento e uma última checagem antes do envio.

Para planilhas grandes, o [endpoint de importação assíncrona da Brevo](https://developers.brevo.com/reference/import-contacts) devolve `processId`. Ele confirma que um trabalho foi aceito, não que terminou. Confira o resultado antes de declarar a importação bem-sucedida. O caminho por contato deste artigo mostra a falha na linha que a causou.

## Perguntas frequentes

**É necessário um conector nativo do Google Sheets?**

Não. O exemplo roda em um projeto Google Apps Script vinculado à planilha e chama a API de contatos da Brevo. Você mantém o script, a chave de API e o acionador agendado.

**Quais linhas são enviadas à Brevo?**

Somente linhas com TRUE em consent e e-mail válido. O script remove duplicatas em cada execução e consulta a Brevo antes de escrever.

**Uma nova execução reinscreve quem se descadastrou?**

O script ignora contatos que a Brevo marca como emailBlacklisted ou descadastrados da lista de destino. Ele nunca envia emailBlacklisted: false nem muda o endereço de e-mail. Verifique outras fontes de consentimento antes de usar em produção.

**Como repetir uma execução com falha?**

Leia o erro nas execuções do Apps Script, corrija a causa e execute a mesma função de novo. As gravações usam o mesmo e-mail e ID de lista; uma linha já concluída não cria um segundo contato.

## Artigos relacionados

### [Como importar contatos CSV ou Excel para a Brevo com um script (Python, Node.js, cURL)](https://tajo.io/pt/blog/import-csv-contacts-to-brevo-with-a-script/)

30 de abr. de 2026 · 6 min de leitura

CSV → Brevo

### [Como empurrar contatos do Excel para a Brevo com uma macro VBA (e a alternativa Office Scripts)](https://tajo.io/pt/blog/import-excel-contacts-to-brevo-with-vba-macro/)

30 de abr. de 2026 · 7 min de leitura

Microsoft Excel → Brevo

### [Integrações Brevo: escolha uma conexão verificável](https://tajo.io/pt/blog/brevo-connector-guide/)

19 de ago. de 2026 · 5 min de leitura

6 seções
