354 lines
11 KiB
TypeScript
354 lines
11 KiB
TypeScript
import type { ApiSettings, CampaignListItem } from "../types";
|
|
import { apiFetch } from "./client";
|
|
|
|
export type CampaignListResponse =
|
|
| CampaignListItem[]
|
|
| {
|
|
campaigns?: CampaignListItem[];
|
|
items?: CampaignListItem[];
|
|
results?: CampaignListItem[];
|
|
};
|
|
|
|
|
|
export type CampaignUpdatePayload = {
|
|
external_id?: string | null;
|
|
name?: string | null;
|
|
status?: string | null;
|
|
description?: string | null;
|
|
};
|
|
|
|
export type CampaignCreateMinimalPayload = {
|
|
external_id?: string;
|
|
name?: string;
|
|
description?: string | null;
|
|
current_flow?: string;
|
|
current_step?: string;
|
|
};
|
|
|
|
export type CampaignCreateResponse = {
|
|
campaign: CampaignListItem & {
|
|
current_version_id?: string | null;
|
|
};
|
|
version: CampaignVersionListItem;
|
|
};
|
|
|
|
export type CampaignVersionListItem = {
|
|
id: string;
|
|
campaign_id: string;
|
|
version_number: number;
|
|
schema_version?: string;
|
|
source_filename?: string | null;
|
|
source_base_path?: string | null;
|
|
workflow_state?: string;
|
|
current_flow?: string;
|
|
current_step?: string | null;
|
|
is_complete?: boolean;
|
|
editor_state?: Record<string, unknown>;
|
|
autosaved_at?: string | null;
|
|
published_at?: string | null;
|
|
locked_at?: string | null;
|
|
locked_by_user_id?: string | null;
|
|
created_at?: string;
|
|
updated_at?: string;
|
|
validation_summary?: Record<string, unknown> | null;
|
|
build_summary?: Record<string, unknown> | null;
|
|
};
|
|
|
|
export type CampaignVersionDetail = CampaignVersionListItem & {
|
|
raw_json: Record<string, unknown>;
|
|
campaign_json?: Record<string, unknown>;
|
|
};
|
|
|
|
export type CampaignVersionUpdatePayload = {
|
|
campaign_json?: Record<string, unknown> | null;
|
|
current_flow?: string | null;
|
|
current_step?: string | null;
|
|
workflow_state?: string | null;
|
|
is_complete?: boolean | null;
|
|
editor_state?: Record<string, unknown> | null;
|
|
source_filename?: string | null;
|
|
source_base_path?: string | null;
|
|
};
|
|
|
|
export type CampaignPartialValidationPayload = {
|
|
campaign_json?: Record<string, unknown> | null;
|
|
section?: string | null;
|
|
};
|
|
|
|
export type CampaignPartialValidationResponse = {
|
|
ok: boolean;
|
|
section?: string | null;
|
|
error_count: number;
|
|
warning_count: number;
|
|
info_count: number;
|
|
issues: Record<string, unknown>[];
|
|
};
|
|
|
|
export type CampaignSummary = {
|
|
generated_at?: string;
|
|
campaign?: CampaignListItem;
|
|
current_version?: {
|
|
id: string;
|
|
version_number?: number;
|
|
schema_version?: string;
|
|
source_filename?: string | null;
|
|
created_at?: string | null;
|
|
validation_summary?: Record<string, unknown> | null;
|
|
build_summary?: Record<string, unknown> | null;
|
|
} | null;
|
|
cards?: {
|
|
jobs_total?: number;
|
|
queueable?: number;
|
|
needs_attention?: number;
|
|
sent?: number;
|
|
failed?: number;
|
|
imap_appended?: number;
|
|
imap_failed?: number;
|
|
};
|
|
status_counts?: Record<string, Record<string, number>>;
|
|
issues?: Record<string, unknown>;
|
|
attachments?: Record<string, unknown>;
|
|
attempts?: Record<string, unknown>;
|
|
delivery?: Record<string, unknown>;
|
|
recent_failures?: Record<string, unknown>[];
|
|
};
|
|
|
|
export type CampaignQueuePayload = {
|
|
version_id?: string | null;
|
|
include_warnings?: boolean;
|
|
enqueue_celery?: boolean;
|
|
dry_run?: boolean;
|
|
};
|
|
|
|
export type CampaignSendNowPayload = {
|
|
version_id?: string | null;
|
|
include_warnings?: boolean;
|
|
check_files?: boolean;
|
|
validate_before_send?: boolean;
|
|
build_before_send?: boolean;
|
|
dry_run?: boolean;
|
|
use_rate_limit?: boolean;
|
|
enqueue_imap_task?: boolean;
|
|
};
|
|
|
|
|
|
export async function listCampaigns(settings: ApiSettings): Promise<CampaignListItem[]> {
|
|
const response = await apiFetch<CampaignListResponse>(settings, "/api/v1/campaigns");
|
|
|
|
if (Array.isArray(response)) {
|
|
return response;
|
|
}
|
|
|
|
return response.campaigns ?? response.items ?? response.results ?? [];
|
|
}
|
|
|
|
export async function getCampaign(settings: ApiSettings, campaignId: string): Promise<CampaignListItem> {
|
|
return apiFetch<CampaignListItem>(settings, `/api/v1/campaigns/${campaignId}`);
|
|
}
|
|
|
|
export async function updateCampaignMetadata(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
payload: CampaignUpdatePayload
|
|
): Promise<CampaignListItem> {
|
|
return apiFetch<CampaignListItem>(settings, `/api/v1/campaigns/${campaignId}`, {
|
|
method: "PUT",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function createNewCampaign(
|
|
settings: ApiSettings,
|
|
overrides: CampaignCreateMinimalPayload = {}
|
|
): Promise<CampaignCreateResponse> {
|
|
const now = new Date();
|
|
const stamp = now.toISOString().slice(0, 19).replace(/[-:T]/g, "");
|
|
const payload = {
|
|
external_id: overrides.external_id ?? `new-campaign-${stamp}`,
|
|
name: overrides.name ?? "New Campaign",
|
|
description: overrides.description ?? "",
|
|
current_flow: overrides.current_flow ?? "create",
|
|
current_step: overrides.current_step ?? "basics"
|
|
};
|
|
|
|
return apiFetch<CampaignCreateResponse>(settings, "/api/v1/campaigns/new", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function getCampaignSchema(settings: ApiSettings): Promise<unknown> {
|
|
return apiFetch(settings, "/api/v1/schemas/campaign");
|
|
}
|
|
|
|
export async function listCampaignVersions(
|
|
settings: ApiSettings,
|
|
campaignId: string
|
|
): Promise<CampaignVersionListItem[]> {
|
|
return apiFetch<CampaignVersionListItem[]>(settings, `/api/v1/campaigns/${campaignId}/versions`);
|
|
}
|
|
|
|
export async function getCampaignVersion(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
versionId: string
|
|
): Promise<CampaignVersionDetail> {
|
|
return apiFetch<CampaignVersionDetail>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}`);
|
|
}
|
|
|
|
export async function unlockCampaignVersionValidation(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
versionId: string
|
|
): Promise<CampaignVersionDetail> {
|
|
return apiFetch<CampaignVersionDetail>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/unlock-validation`, {
|
|
method: "POST"
|
|
});
|
|
}
|
|
|
|
export async function updateCampaignVersion(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
versionId: string,
|
|
payload: CampaignVersionUpdatePayload
|
|
): Promise<CampaignVersionDetail> {
|
|
return apiFetch<CampaignVersionDetail>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}`, {
|
|
method: "PUT",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function forkCampaignVersion(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
versionId: string,
|
|
payload: CampaignVersionUpdatePayload = {}
|
|
): Promise<CampaignCreateResponse> {
|
|
return apiFetch<CampaignCreateResponse>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/fork`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function autosaveCampaignVersion(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
versionId: string,
|
|
payload: CampaignVersionUpdatePayload
|
|
): Promise<CampaignVersionDetail> {
|
|
return apiFetch<CampaignVersionDetail>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/autosave`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function setCampaignVersionStep(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
versionId: string,
|
|
currentStep: string,
|
|
currentFlow?: string | null
|
|
): Promise<CampaignVersionDetail> {
|
|
return apiFetch<CampaignVersionDetail>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/set-step`, {
|
|
method: "POST",
|
|
body: JSON.stringify({ current_flow: currentFlow, current_step: currentStep })
|
|
});
|
|
}
|
|
|
|
export async function validatePartial(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
versionId: string,
|
|
payload: CampaignPartialValidationPayload = {}
|
|
): Promise<CampaignPartialValidationResponse> {
|
|
return apiFetch<CampaignPartialValidationResponse>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/validate-partial`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function publishCampaignVersion(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
versionId: string
|
|
): Promise<CampaignVersionDetail> {
|
|
return apiFetch<CampaignVersionDetail>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/publish`, {
|
|
method: "POST"
|
|
});
|
|
}
|
|
|
|
export async function validateVersion(
|
|
settings: ApiSettings,
|
|
versionId: string,
|
|
checkFiles = false
|
|
): Promise<Record<string, unknown>> {
|
|
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/versions/${versionId}/validate`, {
|
|
method: "POST",
|
|
body: JSON.stringify({ check_files: checkFiles })
|
|
});
|
|
}
|
|
|
|
export async function buildVersion(
|
|
settings: ApiSettings,
|
|
versionId: string,
|
|
writeEml = true
|
|
): Promise<Record<string, unknown>> {
|
|
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/versions/${versionId}/build`, {
|
|
method: "POST",
|
|
body: JSON.stringify({ write_eml: writeEml })
|
|
});
|
|
}
|
|
|
|
export async function getCampaignSummary(settings: ApiSettings, campaignId: string): Promise<CampaignSummary> {
|
|
return apiFetch<CampaignSummary>(settings, `/api/v1/campaigns/${campaignId}/summary`);
|
|
}
|
|
|
|
export async function getCampaignJobs(settings: ApiSettings, campaignId: string): Promise<{ jobs: Record<string, unknown>[] }> {
|
|
return apiFetch<{ jobs: Record<string, unknown>[] }>(settings, `/api/v1/campaigns/${campaignId}/jobs`);
|
|
}
|
|
|
|
export async function queueCampaign(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
payload: CampaignQueuePayload = {}
|
|
): Promise<Record<string, unknown>> {
|
|
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/${campaignId}/queue`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function sendCampaignNow(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
payload: CampaignSendNowPayload = {}
|
|
): Promise<Record<string, unknown>> {
|
|
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/${campaignId}/send-now`, {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export async function pauseCampaign(settings: ApiSettings, campaignId: string): Promise<Record<string, unknown>> {
|
|
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/${campaignId}/pause`, { method: "POST" });
|
|
}
|
|
|
|
export async function resumeCampaign(settings: ApiSettings, campaignId: string): Promise<Record<string, unknown>> {
|
|
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/${campaignId}/resume`, { method: "POST" });
|
|
}
|
|
|
|
export async function cancelCampaign(settings: ApiSettings, campaignId: string): Promise<Record<string, unknown>> {
|
|
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/${campaignId}/cancel`, { method: "POST" });
|
|
}
|
|
|
|
export async function appendSent(
|
|
settings: ApiSettings,
|
|
campaignId: string,
|
|
dryRun = false
|
|
): Promise<Record<string, unknown>> {
|
|
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/${campaignId}/append-sent`, {
|
|
method: "POST",
|
|
body: JSON.stringify({ dry_run: dryRun })
|
|
});
|
|
}
|