Kontaktsynchronisierung

Synchronisieren Sie Kontakte aus Ihrer Datenbank nach Owlat — mit Upsert-Mustern und Massenoperationen.

Synchronisieren Sie Kontakte aus Ihrer Datenbank nach Owlat — mit Upsert-Mustern und Massenoperationen.

Einen einzelnen Kontakt upserten

Die API hat keinen eigenen Upsert-Endpunkt, doch Sie können einen aus create + update zusammensetzen:

import {
  Owlat,
  ConflictError,
} from '@owlat/sdk-js'

const owlat = new Owlat('lm_live_...')

async function upsertContact(email: string, data: { firstName?: string; lastName?: string }) {
  try {
    // Try creating first
    return await owlat.contacts.create({ email, ...data })
  } catch (error) {
    if (error instanceof ConflictError) {
      // Contact already exists — update instead
      return await owlat.contacts.update(email, data)
    }
    throw error
  }
}

await upsertContact('mira@acme.io', {
  firstName: 'Mira',
  lastName: 'Chen',
})

Massensynchronisierung

Verwenden Sie Promise.allSettled, um viele Kontakte zu synchronisieren, ohne dass ein einzelner Fehler den Batch stoppt. Ergänzen Sie eine Begrenzung der Nebenläufigkeit, um innerhalb der Rate Limits zu bleiben:

import { Owlat, RateLimitError } from '@owlat/sdk-js'

const owlat = new Owlat('lm_live_...')

interface UserRecord {
  email: string
  firstName: string
  lastName: string
}

async function syncBatch(users: UserRecord[], concurrency = 5) {
  const results: PromiseSettledResult<unknown>[] = []

  // Process in chunks to respect rate limits
  for (let i = 0; i < users.length; i += concurrency) {
    const chunk = users.slice(i, i + concurrency)
    const chunkResults = await Promise.allSettled(
      chunk.map((user) => upsertContact(user.email, {
        firstName: user.firstName,
        lastName: user.lastName,
      }))
    )
    results.push(...chunkResults)
  }

  const succeeded = results.filter((r) => r.status === 'fulfilled').length
  const failed = results.filter((r) => r.status === 'rejected').length
  console.log(`Synced: ${succeeded} succeeded, ${failed} failed`)

  return results
}
Rate Limits

Die API erzwingt Rate Limits pro Schlüssel. Wenn Sie Tausende von Kontakten synchronisieren, halten Sie die Nebenläufigkeit niedrig (3–5) und fügen Sie eine Pause zwischen den Chunks ein, falls Sie 429-Antworten erhalten. Details zu den Rate Limits finden Sie unter Authentifizierung.

Synchronisierte Kontakte einem Topic hinzufügen

Nach der Synchronisierung können Sie Kontakte einem Topic hinzufügen, um gezielte Kampagnen zu fahren:

async function syncAndAddToTopic(users: UserRecord[], topicId: string) {
  // 1. Sync contacts
  await syncBatch(users)

  // 2. Add each to the topic
  const topicResults = await Promise.allSettled(
    users.map((user) =>
      owlat.topics.addContact({
        topicId,
        email: user.email,
      })
    )
  )

  const added = topicResults.filter((r) => r.status === 'fulfilled').length
  console.log(`Added ${added}/${users.length} contacts to topic ${topicId}`)
}

Vollständiges Sync-Skript

Alles zusammengesetzt — ein Skript, das Benutzer aus Ihrer Datenbank liest und sie nach Owlat synchronisiert:

import { Owlat, ConflictError } from '@owlat/sdk-js'

const owlat = new Owlat(process.env.OWLAT_API_KEY!)

async function upsertContact(email: string, data: { firstName?: string; lastName?: string }) {
  try {
    return await owlat.contacts.create({ email, ...data })
  } catch (error) {
    if (error instanceof ConflictError) {
      return await owlat.contacts.update(email, data)
    }
    throw error
  }
}

async function main() {
  // Replace with your actual database query
  const users = await db.users.findMany({
    where: { emailVerified: true },
    select: { email: true, firstName: true, lastName: true },
  })

  console.log(`Syncing ${users.length} contacts...`)

  for (let i = 0; i < users.length; i += 5) {
    const chunk = users.slice(i, i + 5)
    await Promise.allSettled(
      chunk.map((u) => upsertContact(u.email, {
        firstName: u.firstName,
        lastName: u.lastName,
      }))
    )
    console.log(`Progress: ${Math.min(i + 5, users.length)}/${users.length}`)
  }
}

main()

Nächste Schritte