audiencemanager-js
v0.2.5
Published
Klientbibliotek för audiencemanager Lead Ingest API – retry, auto-idempotens och typad felhantering.
Maintainers
Readme
audiencemanager-js
Klientbibliotek för audiencemanager Lead Ingest API. Wrappar POST /api/public/source/v1/leads med inbyggd retry, auto-idempotens, lokal validering och typad felhantering.
För dig som äger en egen tjänst: du behöver inte ändra AudienceManager-kod. Skapa en API-nyckel under Sources, skicka payloads från din backend, och håll nyckeln borta från webbläsaren.
Installation
npm install audiencemanager-jsI Deno (t.ex. edge functions) behövs ingen installation:
import { AudienceManagerClient } from "npm:audiencemanager-js";Paketet byggs som fristående ESM (zod är inbakad). Exports:
| Import | Syfte |
| --- | --- |
| audiencemanager-js | Klient + submit + schema |
| audiencemanager-js/contract | Delad v1/v2-schema (server/SDK) |
| audiencemanager-js/forms | Formulärfält-validators utan API-nyckel |
Snabbstart (v2 – rekommenderat)
import { AudienceManagerClient } from "audiencemanager-js";
const client = new AudienceManagerClient({
apiKey: process.env.AM_API_KEY!, // skapas under Sources i appen — endast på servern
});
const result = await client.submitLead({
schema_version: "v2",
lead_type: "service", // routing-sträng som avtalats i AM
external_id: "order-10231",
contact: {
first_name: "Anna",
last_name: "Lind",
email: "[email protected]",
phone: "+46701234567",
},
location: {
postal_code: "12345",
city: "Stockholm",
address: "Exempelgatan 1",
},
request_data: {
service: {
category: "cleaning",
type: "home_cleaning",
description: "Veckostädning",
},
property: { type: "apartment", area_sqm: 68 },
},
extensions: {
// Nischfält som inte finns i standardkontraktet ännu
preferred_cleaner_id: "c-9",
},
attribution: { utm_source: "google" },
});
if (result.status === "accepted") console.log("Lead:", result.lead_id);
if (result.status === "duplicate") console.log("Redan inskickat:", result.lead_id);
if (result.status === "rejected") console.error("Avvisat:", result.errors);Minimal payload (alla business-fält är valfria):
await client.submitLead({
schema_version: "v2",
lead_type: "service",
contact: { email: "[email protected]" },
request_data: { service: { description: "Hej" } },
});Vehicle-exempel:
await client.submitLead({
schema_version: "v2",
lead_type: "vehicle",
contact: { first_name: "Bo", last_name: "Berg", phone: "+46701112233" },
location: { city: "Göteborg", postal_code: "41101", country_code: "SE" },
request_data: {
vehicle: { make: "Volvo", model: "V60", model_year: 2019, mileage: 4500 },
valuation: { dealer: { min: 120000, max: 140000 } },
},
});Utan schema_version (eller med "v1") gäller legacy-kontraktet: öppen request_data, geografi på contact.
Var lägger jag fält?
| Sektion | Innehåll | Auto-mappas? |
| --- | --- | --- |
| contact | Person: namn, e-post, telefon | Ja (v2 standard) |
| location | Plats för uppdrag/fastighet (inte automatiskt bostad) | Ja (v2 standard) |
| request_data | Typade sektioner: service, property, vehicle, valuation | Ja för kända sökvägar |
| attribution | UTM + landing_page | Ja |
| extensions | Custom / framtida vertikal | Nej — lagras; mappa manuellt i AM om det behövs för regler/kort |
Okända nycklar i contact / location / request_data / attribution avvisas på v2. Lägg dem i extensions.
Typed verticals i den här releasen: cleaning-formad service + vehicle. Mäklare, rug cleaning, övriga nischer → extensions tills de får egna sektioner.
Blank/null = saknas. false och 0 behålls. Ogiltiga värden (t.ex. trasig e-post) ger valideringsfel även om fältet är valfritt.
Browser vs server
- Server:
AudienceManagerClient+ API-nyckel - Browser: importera
audiencemanager-js/formsför fältvalidering — skicka aldrig API-nyckeln till klienten
Beteende
- Auto-idempotens: varje anrop får en
Idempotency-Keyautomatiskt –ext:<external_id>om den finns, annars en UUID. Omförsök återanvänder samma nyckel. Tidigare avvisade eller failed anrop blockerar inte en korrigerad omsändning. - Retry med backoff: nätverksfel, 429 och 5xx upp till 3 gånger.
- Lokal validering: samma zod-regler som servern (
validate: falsestänger av).
Felhantering
import {
AudienceManagerError,
AuthError,
ValidationError,
PayloadTooLargeError,
NetworkError,
} from "audiencemanager-js";
try {
await client.submitLead(payload);
} catch (err) {
if (err instanceof AuthError) {
// 401 – kontrollera API-nyckeln
} else if (err instanceof ValidationError) {
// lokal validering – err.issues listar felfälten
} else if (err instanceof PayloadTooLargeError) {
// 413 – max 200 KB
} else if (err instanceof NetworkError) {
// nätverksfel/5xx kvarstod efter alla omförsök
} else if (err instanceof AudienceManagerError) {
// övriga API-fel – err.code, err.status
}
}En payload som passerar lokal validering men avvisas av servern returneras som { status: "rejected", errors: [...] }.
API
new AudienceManagerClient(options)
| Option | Typ | Default | Beskrivning |
| --- | --- | --- | --- |
| apiKey | string | – | Source-bunden API-nyckel (obligatorisk) |
| baseUrl | string | produktionsinstansen | Bas-URL |
| validate | boolean | true | Lokal zod-validering före sändning |
| maxRetries | number | 3 | Omförsök vid nätverksfel/5xx/429 |
| baseDelayMs | number | 500 | Bas för exponentiell backoff |
| fetchFn | typeof fetch | global fetch | Egen fetch (t.ex. vid test) |
| idempotencyKey | (payload) => string | auto | Egen nyckelgenerator |
client.submitLead(payload, options?)
Returnerar Promise<SubmitResult> där status är "accepted" | "duplicate" | "rejected".
Release
Ändringar under packages/audiencemanager-js/ som når main triggar workflowen SDK auto bump and tag, som bumpa patch och publicerar till npm. Behandla merge till main som en avsiktlig SDK-release.
Krav
Node 18+ eller modern browser (global fetch och crypto.randomUUID).
Licens
MIT
