Campaigns helpers
Helpers exported by @morevoice/sdk from src/lib/campaigns.ts.
Exported from @morevoice/sdk (source: packages/sdk-ts/src/lib/campaigns.ts).
RejectedReasons
Section titled “RejectedReasons”Rejected rows by reason (WS05 W2-09). Reasons are open: newer servers may add some. [W2 merge] The implemented API
reports dnc, invalid and duplicate (contacts without consent are imported and counted in without_consent).
interface RejectedReasons { dnc: number; invalid: number; duplicate: number; [reason: string]: number;}ContactImport
Section titled “ContactImport”The asynchronous import job (GET /v1/imports/{id}). The facade’s imports.retrieve returns the full generated type.
interface ContactImport { id: string; object?: "import"; campaign_id?: string; status: "pending" | "processing" | "succeeded" | "completed" | "failed" | (string & {}); imported: number; rejected: number; rejected_reasons: RejectedReasons; errors_url?: string | null; error?: { code: string; message: string } | null; [field: string]: unknown;}CsvSource
Section titled “CsvSource”What importCsv accepts as the file.
type CsvSource = | Blob | ArrayBuffer | ArrayBufferView | ReadableStream<Uint8Array> | AsyncIterable<Uint8Array | string> /** A file path (Node only). */ | string;ImportCsvOptions
Section titled “ImportCsvOptions”interface ImportCsvOptions { /** Contact field → column header, e.g. `{ phone: "Mobile", first_name: "Name" }`. Omitted: the server guesses. */ mapping?: Record<string, string>; /** Country for numbers without a country code (default IL). */ default_country?: string; /** Where the §30A marketing consent was collected (consent provenance). */ consent_source?: string; /** The file name sent with the upload (default: the path's or File's name, else contacts.csv); `.xlsx` marks a spreadsheet. */ filename?: string; /** Check every row's phone number before uploading (needs the optional peer libphonenumber-js). */ validate?: boolean; /** Retrying importCsv with the same key never imports twice (default: a fresh key per call). */ idempotencyKey?: string; signal?: AbortSignal; /** Give up waiting for the import after this long (default 30 minutes). The import itself continues on the server. */ timeoutMs?: number; /** First polling interval (default 1000 ms), ×1.5 per poll up to 10 s. */ pollIntervalMs?: number; /** Called with every state of the import job. */ onProgress?: (job: ContactImport) => void;}ImportCsvResult
Section titled “ImportCsvResult”interface ImportCsvResult<I extends ContactImport = ContactImport> { /** `imp_…` */ id: string; status: I["status"]; imported: number; rejected: number; rejected_reasons: RejectedReasons; /** A CSV of the rejected rows with their reasons (short-lived), when there are any. */ errors_url: string | null; /** The final import object, as the API returned it. */ import: I; /** The client-side check, with `validate: true`. */ validation?: CsvValidationReport;}UploadBody
Section titled “UploadBody”One multipart upload, ready to send.
interface UploadBody { /** FormData (fetch sets the boundary) or a streamed multipart body. */ body: FormData | ReadableStream<Uint8Array>; /** The Content-Type to send; null lets fetch set it (FormData). */ contentType: string | null; /** A streamed body: needs `duplex: "half"` and cannot be retried. */ streaming: boolean;}ImportDeps
Section titled “ImportDeps”What importCsv needs from the client.
interface ImportDeps<I extends ContactImport> { upload(campaignId: string, upload: UploadBody, options: { idempotencyKey: string; signal: AbortSignal }): Promise<I>; retrieve(importId: string, options: { signal: AbortSignal }): Promise<I>; /** Upload retries for re-readable sources (the client's maxRetries). */ maxRetries: number;}DEFAULT_IMPORT_TIMEOUT_MS
Section titled “DEFAULT_IMPORT_TIMEOUT_MS”const DEFAULT_IMPORT_TIMEOUT_MS;contentTypeFor()
Section titled “contentTypeFor()”The upload’s file Content-Type, from its name.
function contentTypeFor(filename: string): string;importFields()
Section titled “importFields()”Form fields besides the file, in a stable order.
function importFields(options: ImportCsvOptions): [string, string][];multipartStream()
Section titled “multipartStream()”A streamed multipart/form-data body: the fields, then the file part fed from file, then the closing boundary.
function multipartStream(fields: [string, string][], file: { filename: string; contentType: string; chunks: AsyncIterable<Uint8Array> }, boundary: string): ReadableStream<Uint8Array>;importCsv()
Section titled “importCsv()”Upload a contact file to a campaign and wait for the import job. See the file header.
function importCsv<I extends ContactImport>(deps: ImportDeps<I>, campaignId: string, source: CsvSource, options: ImportCsvOptions = {}): Promise<ImportCsvResult<I>>;