Importer kontakter fra Google Sheets til Brevo med Apps Script

Et gjentakbart Google Apps Script som sjekker samtykke, kobler felter, bevarer avmeldinger og viser API-feil.

google apps script brevo

Hva er det korte svaret?

Legg til kolonnene email, firstName, lastName og consent i arket. Sett BREVO_API_KEY i skriptegenskapene og liste-ID i koden. Kjør så syncSheetToBrevo. Skriptet behandler bare rader med samtykke, kontrollerer avmeldinger i Brevo, fjerner duplikater og stopper ved API-feil. Dette er et Apps Script du vedlikeholder selv, ikke en innebygd kobling.

Les mer
På denne siden

Et ark med tolv påmeldinger til et arrangement er enkelt å eksportere én gang. Ved neste import står én adresse der to ganger, og en annen person har meldt seg av i Brevo. En gjentakbar import må fange opp begge deler.

Skriptet bruker Brevos endepunkter for å lese, opprette og oppdatere kontakter. Det er laget for små, planlagte importer, ikke masseinnlasting eller som en innebygd Google Sheets-kobling. Det sender ingen e-post. Du har ansvar for samtykkedokumentasjon og drift.

Klargjør arket og listen

Opprett en fane Contacts med nøyaktig disse kolonnenavnene. Bruk avmerkingsbokser for consent og sett TRUE bare når du har tillatelse til den tiltenkte markedsføringen.

emailfirstNamelastNameconsent
[email protected]JaneDoeTRUE
[email protected]AlexLeeFALSE

Opprett eller velg en Brevo-liste og angi den numeriske ID-en som LIST_ID i koden. Sjekk at kontaktattributtene FNAME og LNAME finnes i Brevo. Bare disse feltene kobles. Ta vare på når og hvordan samtykket ble gitt hvis arket ikke kan dokumentere det. En TRUE-celle er ikke bevis.

Under Utvidelser → Apps Script → Prosjektinnstillinger → Skriptegenskaper legger du til BREVO_API_KEY. Egenskapene deles av brukerne av skriptet. Begrens derfor hvem som kan redigere prosjektet. Ikke legg nøkkelen i en celle eller i kildekoden. Les Googles tilgangsregler.

Skriptet

Erstatt Code.gs med eksemplet og sett LIST_ID før første kjøring.

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

Lagre, velg syncSheetToBrevo og trykk Kjør. Google ber om tilgang til Sheets og eksterne forespørsler. Under Kjøringer ser du sluttrapporten {written, skipped}. En 404 ved lesing fører til oppretting; 200 fører til oppdatering. Andre lesefeil stopper kjøringen. En vellykket skriving bekrefter kontaktforespørselen, ikke en sendt kampanje.

Skriptet fjerner doble adresser i én kjøring og spør Brevo igjen i neste. Det setter aldri emailBlacklisted til false og endrer ikke e-postadressen. Hvis Brevo viser en generell sperre eller avmelding fra denne listen, hoppes raden over selv om arket viser TRUE. Bruk ikke skriptet til å angre avmelding. Brevo advarer om at adresseendring for en sperret kontakt kan oppheve sperren.

Kontroller én kjøring før planlegging

Bruk en testliste og kontakter du kontrollerer. Kjør med én TRUE-rad, én FALSE-rad og en dobbelt adresse: forvent én skriving og to hoppede rader. Meld testkontakten av i Brevo og kjør igjen: den skal ikke skrives. Test en feil ved midlertidig å sette LIST_ID til en ugyldig verdi. Kontroller HTTP-feilen under Kjøringer, gjenopprett ID-en og prøv på nytt. Ikke test med virkelige kundedata. Koden er også testet lokalt med simulerte Brevo-svar, uten direkte skriving.

For automatikk velger du Apps Script → Utløsere → Legg til utløser, syncSheetToBrevo og et tidsintervall. Installerbare utløsere kjører som kontoen som opprettet dem. Kontoen må beholde tilgang til arket. Start daglig for et lite ark, og følg med på feil. Google begrenser kjøretid og URL Fetch-kall; del store kilder i avgrensede jobber.

Ved 429 leser skriptet x-sib-ratelimit-reset og prøver maksimalt to ganger til. Hvis nødvendig ventetid er over 60 sekunder, returnerer det 429 for en senere kjøring. Andre feil stopper kjøringen; neste begynner fra toppen. En kontakt kan melde seg av mellom lesing og skriving. Bruk eksemplet bare hvis det korte tidsrommet er akseptabelt. Strengere garantier krever avstemming fra hendelser, en autoritativ samtykkekilde og en siste sjekk før utsending.

For større ark returnerer Brevos asynkrone importendepunkt en processId. Den bekrefter at jobben er tatt imot, ikke at den er fullført. Kontroller resultatet før du kaller importen vellykket. Med denne ruten per kontakt blir feilen synlig ved den aktuelle raden.

Ofte Stilte Spørsmål

Trenger jeg en innebygd Google Sheets-kobling?

Nei. Eksemplet kjører i et Google Apps Script-prosjekt som er knyttet til arket og kaller Brevos kontakt-API. Du vedlikeholder skriptet, API-nøkkelen og den planlagte utløseren.

Hvilke rader sendes til Brevo?

Bare rader med TRUE i consent og gyldig e-postadresse. Skriptet fjerner duplikater i hver kjøring og sjekker Brevo før det skriver.

Melder en ny kjøring på en avmeldt kontakt igjen?

Skriptet hopper over kontakter Brevo markerer som emailBlacklisted eller avmeldt fra mållisten. Det sender aldri emailBlacklisted: false og endrer ikke e-postadressen. Sjekk andre samtykkekilder før produksjon.

Hvordan prøver jeg en mislykket kjøring igjen?

Les feilen i Apps Script-kjøringer, rett årsaken og kjør samme funksjon på nytt. Skrivingene bruker samme adresse og liste-ID, så en tidligere vellykket rad lager ikke en ny kontakt.

Be om tidlig tilgang

Skriv inn fornavn og e-postadresse på jobb. Vi sender deg en lenke for å bekrefte forespørselen om tilgang til Tajo.

Skaff Brevo