@biobarica/seller-resolution
v1.0.2
Published
Resolves a seller from Firestore by phone number or country using Pipedrive
Downloads
140
Maintainers
Readme
@biobarica/seller-resolution
Resolves a Pipedrive seller for a given phone number or country code using Firestore as the seller registry.
How it works
- By phone — searches Pipedrive for an existing contact with that number. If one is found and already has an owner, that owner is returned. Otherwise the phone's country is extracted and the flow continues as below.
- By country — fetches all sellers from the
user_detailsFirestore collection that are assigned to that country (or to the"ROW"catch-all), then picks one at random weighted by their configured country weights.
Installation
npm install @biobarica/seller-resolutionUsage
With a Firestore instance
Use this when you already have firebase-admin initialised in your app.
import { SellersService, BusinessUnit } from "@biobarica/seller-resolution";
import { getFirestore } from "firebase-admin/firestore";
const service = new SellersService({
pipedriveApiKey: process.env.PIPEDRIVE_API_KEY,
businessUnit: BusinessUnit.OXY,
defaultSellerId: 42,
defaultUserId: "fallback-uid",
db: getFirestore(),
});With a service account
Use this when you don't have firebase-admin set up yet. The package initialises it internally.
import { SellersService, BusinessUnit } from "@biobarica/seller-resolution";
import serviceAccount from "./service-account.json";
const service = new SellersService({
pipedriveApiKey: process.env.PIPEDRIVE_API_KEY,
businessUnit: BusinessUnit.OXY,
defaultSellerId: 42,
defaultUserId: "fallback-uid",
serviceAccount,
});
dbandserviceAccountare mutually exclusive — TypeScript will report an error if you pass both.
API
new SellersService(options, logger?)
| Option | Type | Required | Description |
|---|---|---|---|
| pipedriveApiKey | string | Yes | Pipedrive API key |
| businessUnit | string | Yes | Business unit key used to scope seller selection (e.g. "oxy") |
| db | Firestore | One of | An existing Firestore instance |
| serviceAccount | ServiceAccountCredentials | One of | Firebase service account credentials object |
| defaultSellerId | number | No | Fallback Pipedrive seller id when no seller can be resolved |
| defaultUserId | string | No | Fallback Firestore user id when no seller can be resolved |
An optional second argument accepts a custom Logger ({ info, warn, error }). Defaults to console.
getSeller(phoneNumber)
Resolves a seller for a phone number. Accepts E.164 format (+5491123456789) or without the leading +.
const result = await service.getSeller("+5491123456789");
// result.sellerId — Pipedrive seller id (number | undefined)
// result.userId — Firestore user document id (string | undefined)
// result.displayName — seller display name (string | undefined)
// result.calendarLink — booking calendar URL (string | undefined)
// result.discoveryCallCalendarLink — discovery call calendar URL (string | undefined)
// result.whatsappNumber — WhatsApp contact number (string | undefined)getSellerByCountry(countryCode)
Resolves a seller directly from a country code, skipping the Pipedrive lookup.
const { sellerId, userId, displayName, calendarLink } = await service.getSellerByCountry("AR");Firestore data model
The service reads from the user_details collection. Each seller document must have at least:
{
"id": "firestore-doc-id",
"roles": ["seller"],
"sellerInfo": {
"pipedriveSellerId": 42,
"assignedCountries": ["AR", "CL"], // ISO 3166-1 alpha-2 or "ROW" as catch-all
"countryWeights": { "AR": 0.7, "CL": 0.3 },
"businessUnits": ["oxy"] // omit to make available to all business units
}
}Per-business-unit overrides
A seller can override assignedCountries and countryWeights for a specific business unit by nesting them under the business unit key:
{
"sellerInfo": {
"pipedriveSellerId": 42,
"assignedCountries": ["ROW"],
"oxy": {
"assignedCountries": ["AR", "BR"],
"countryWeights": { "AR": 0.6, "BR": 0.4 }
}
}
}Country weights
Weights do not need to sum to 1 — the selection is proportional. A seller with weight 2 is twice as likely to be picked as one with weight 1. If no weight is configured for a country, all eligible sellers share equal probability.
Custom logger
import { SellersService, Logger } from "@biobarica/seller-resolution";
const logger: Logger = {
info: (msg) => myLogger.info(msg),
warn: (msg) => myLogger.warn(msg),
error: (msg) => myLogger.error(msg),
};
const service = new SellersService({ ... }, logger);