Add bounce mailbox processing

This commit is contained in:
2026-07-31 22:48:07 +02:00
parent 2721ee6542
commit fe309dbff5
13 changed files with 1770 additions and 7 deletions
+66
View File
@@ -139,6 +139,72 @@ export type MailSettingsDeltaResponse = {
full: boolean;
};
export type MailBounceSource = {
id: string;
tenant_id: string;
profile_id: string;
folder: string;
imap_server_id?: string | null;
imap_credential_id?: string | null;
expected_imap_transport_revision: string;
is_active: boolean;
uidvalidity?: string | null;
highest_processed_uid: number;
last_scanned_at?: string | null;
last_success_at?: string | null;
last_error?: string | null;
};
export type MailBounceObservation = {
id: string;
profile_id: string;
folder: string;
uid: string;
original_message_id?: string | null;
command_id?: string | null;
recipient?: string | null;
action: string;
status_code?: string | null;
diagnostic?: string | null;
permanent: boolean;
observed_at: string;
matched: boolean;
evidence: Record<string, unknown>;
};
export type MailBounceSourcePayload = {
profile_id: string;
folder: string;
imap_server_id?: string | null;
imap_credential_id?: string | null;
is_active: boolean;
};
export async function listMailBounceSources(settings: ApiSettings): Promise<MailBounceSource[]> {
const response = await apiFetch<{ sources: MailBounceSource[] }>(settings, "/api/v1/mail/bounce-sources");
return response.sources;
}
export async function saveMailBounceSource(settings: ApiSettings, payload: MailBounceSourcePayload): Promise<MailBounceSource> {
return apiFetch<MailBounceSource>(settings, "/api/v1/mail/bounce-sources", {
method: "POST",
body: JSON.stringify(payload)
});
}
export async function removeMailBounceSource(settings: ApiSettings, sourceId: string): Promise<void> {
await apiFetch<void>(settings, `/api/v1/mail/bounce-sources/${encodeURIComponent(sourceId)}`, { method: "DELETE" });
}
export async function scanMailBounceSource(settings: ApiSettings, sourceId: string): Promise<{ sources: number; processed_messages: number; observations: number; failures: Array<Record<string, string>> }> {
return apiFetch(settings, `/api/v1/mail/bounce-sources/${encodeURIComponent(sourceId)}/scan`, { method: "POST" });
}
export async function listMailBounceObservations(settings: ApiSettings, limit = 100): Promise<MailBounceObservation[]> {
const response = await apiFetch<{ observations: MailBounceObservation[] }>(settings, apiPath("/api/v1/mail/bounce-observations", { limit }));
return response.observations;
}
export async function lookupMailAddresses(settings: ApiSettings, query: string, limit = 25): Promise<MailAddressLookupResponse> {
return apiFetch<MailAddressLookupResponse>(settings, apiPath("/api/v1/mail/address-lookup", { query, limit }));
}