---
title: "Importera kontakter från Google Sheets till Brevo med Apps Script"
description: "Ett körbart Google Apps Script som kontrollerar samtycke, mappar fält, respekterar avregistreringar och visar API-fel."
url: https://tajo.io/se/blog/import-google-sheet-contacts-to-brevo-apps-script/
markdown: https://tajo.io/se/blog/import-google-sheet-contacts-to-brevo-apps-script.md
lang: sv-SE
author: "Set Noa"
author_url: https://tajo.io/se/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, pt-BR: /pt/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, 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}
---

[Datasynkronisering](https://tajo.io/se/blog/?category=data-sync)

# Importera kontakter från Google Sheets till Brevo med Apps Script

Ett körbart Google Apps Script som kontrollerar samtycke, mappar fält, respekterar avregistreringar och visar API-fel.

google apps script brevo

Hur importerar du Sheets-kontakter till Brevo?

Lägg till kolumnerna email, firstName, lastName och consent i ett ark. Spara BREVO\_API\_KEY i skriptegenskaper och list-ID i koden, kör sedan syncSheetToBrevo. Skriptet tar bara med rader med samtycke, kontrollerar avregistreringar i Brevo, tar bort dubbletter och stannar vid API-fel. Det är ett Apps Script du själv underhåller, ingen inbyggd anslutning.

[Läs mer](https://tajo.io/se/blog/import-google-sheet-contacts-to-brevo-apps-script/#f%C3%B6rbered-arket-och-listan)

| Källfält | Målfält | Exempelvärde |
| --- | --- | --- |
| `email` | `email` | `alex@example.com` |
| `firstName` | `FNAME` | `Alex` |
| `lastName` | `LNAME` | `Example` |

Ett ark med tolv evenemangsanmälningar är lätt att exportera en gång. Vid nästa import finns en adress två gånger och en annan person har avregistrerat sig i Brevo. En upprepningsbar import måste känna igen båda.

Skriptet använder [Brevos API för att läsa, skapa och uppdatera kontakter](https://developers.brevo.com/reference/create-contact). Det är avsett för små, schemalagda importer, inte massinläsning eller som en inbyggd Google Sheets-anslutning. Det skickar ingen e-post. Du ansvarar för samtyckesbevis och drift.

## Förbered arket och listan

Skapa en flik `Contacts` med exakt dessa rubriker. Använd kryssrutor för `consent` och sätt `TRUE` endast när du har tillstånd för den avsedda marknadsföringen.

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

Skapa eller välj en Brevo-lista och ange dess numeriska ID som `LIST_ID` i koden. Kontrollera att kontaktattributen `FNAME` och `LNAME` finns i Brevo; inga andra fält mappas. Spara underlag för när och hur samtycket gavs om arket inte kan visa det. En `TRUE`-cell är inget bevis.

Öppna **Tillägg → Apps Script → Projektinställningar → Skriptegenskaper** och lägg till `BREVO_API_KEY`. Skriptegenskaper delas av skriptets användare. Begränsa vem som får redigera projektet. Lägg inte nyckeln i en cell eller källkod. Läs [Googles åtkomstregler](https://developers.google.com/apps-script/guides/properties).

## Skriptet

Ersätt `Code.gs` med exemplet och ange `LIST_ID` före första körningen.

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

Spara, välj `syncSheetToBrevo` och klicka på **Kör**. Google begär åtkomst till Sheets och externa anrop. Under **Körningar** ser du slutloggen `{written, skipped}`. Ett lässvar 404 leder till att kontakten skapas; 200 till att den uppdateras. Andra läsfel stoppar körningen. En lyckad skrivning bekräftar kontaktanropet, inte att någon kampanj skickats.

Skriptet tar bort dubbla adresser i samma körning och frågar Brevo på nytt vid nästa. Det sätter aldrig `emailBlacklisted` till `false` och ändrar inte e-postadressen. Om Brevo visar en allmän spärr eller avregistrering från listan hoppas raden över även med `TRUE` i arket. Använd inte skriptet för att ångra en avregistrering. [Brevo varnar](https://developers.brevo.com/reference/update-contact) för att en ändrad adress kan häva spärren på en blockerad kontakt.

## Kontrollera en körning före schemaläggning

Använd en testlista och kontakter du själv kontrollerar. Kör med en `TRUE`-rad, en `FALSE`-rad och en dubbel adress: vänta dig en skrivning och två överhoppade rader. Avregistrera testkontakten i Brevo och kör igen: kontakten ska inte skrivas. Testa ett fel genom att tillfälligt ange ett ogiltigt `LIST_ID`, kontrollera HTTP-felet under **Körningar**, återställ ID och kör igen. Använd inte riktiga kunddata. Koden har också testats lokalt med simulerade Brevo-svar, utan live-skrivning.

För schemaläggning väljer du **Apps Script → Utlösare → Lägg till utlösare**, `syncSheetToBrevo` och ett tidsintervall. [Installerade utlösare körs under skaparens konto](https://developers.google.com/apps-script/guides/triggers/installable). Kontot måste behålla åtkomst till arket. Börja med daglig körning och granska misslyckanden. Google [begränsar körtid och URL Fetch-anrop](https://developers.google.com/apps-script/guides/services/quotas); dela stora källor i begränsade jobb.

Vid 429 läser skriptet `x-sib-ratelimit-reset`, försöker högst två gånger till och returnerar 429 för en senare körning om väntan behöver bli längre än 60 sekunder. Andra fel stoppar körningen; nästa börjar överst. En kontakt kan avregistrera sig mellan läsning och skrivning. Använd exemplet bara om det korta tidsfönstret är godtagbart. För striktare garantier behövs avstämning via händelser, en auktoritativ samtyckeskälla och en sista kontroll före utskick.

För större ark returnerar Brevos [asynkrona import-API](https://developers.brevo.com/reference/import-contacts) ett `processId`. Det bekräftar att jobbet tagits emot, inte att det är klart. Kontrollera resultatet innan du kallar importen lyckad. Med vägen per kontakt syns felet på den berörda raden.

## Vanliga Frågor

**Behöver jag en inbyggd Google Sheets-anslutning?**

Nej. Exemplet körs i ett Google Apps Script-projekt som är kopplat till arket och anropar Brevos kontakt-API. Du underhåller själv skriptet, API-nyckeln och den schemalagda utlösaren.

**Vilka rader skickas till Brevo?**

Bara rader med TRUE i consent och en giltig e-postadress. Skriptet tar bort dubbletter vid varje körning och kontrollerar Brevo före skrivning.

**Registrerar en ny körning en avregistrerad person igen?**

Skriptet hoppar över kontakter som Brevo markerar som emailBlacklisted eller avregistrerade från mållistan. Det skickar aldrig emailBlacklisted: false och ändrar inte e-postadressen. Kontrollera andra samtyckeskällor före produktion.

**Hur upprepar jag en misslyckad körning?**

Läs felet i Apps Script-körningar, åtgärda orsaken och kör samma funktion igen. Skrivningarna använder samma adress och list-ID, så en tidigare lyckad rad skapar inte en andra kontakt.

## Relaterade artiklar

### [Så importerar du CSV- eller Excel-kontakter till Brevo med ett skript (Python, Node.js, cURL)](https://tajo.io/se/blog/import-csv-contacts-to-brevo-with-a-script/)

30 apr. 2026 · 5 min lästid

CSV → Brevo

### [Så skickar du Excel-kontakter till Brevo med ett VBA-makro (och alternativet med Office Scripts)](https://tajo.io/se/blog/import-excel-contacts-to-brevo-with-vba-macro/)

30 apr. 2026 · 6 min lästid

Microsoft Excel → Brevo

### [Brevo-integrationer: välj en anslutning som går att verifiera](https://tajo.io/se/blog/brevo-connector-guide/)

19 aug. 2026 · 3 min lästid

6 avsnitt
