import { logDone, logError, logIntent } from "../../config/logger.js"; export interface DispatchResult { success: boolean; providerResponse?: string; error?: string; } function formatResponseFailure(endpoint: string, data: unknown): string { const serialized = JSON.stringify(data); return `${endpoint} returned success=false${serialized && serialized !== "{}" ? ` data=${serialized}` : " without error details"}`; } function getApiBaseUrl(): string { const raw = process.env.API_URL || ""; if (!raw.trim()) { return ""; } try { return new URL(raw).origin; } catch { return raw.replace(/\/$/, ""); } } function buildApiUrl(path: string): string { return `${getApiBaseUrl()}${path}`; } function formatDispatchError(error: unknown): string { if (typeof error === "object" && error !== null && "isAxiosError" in error) { const axiosError = error as { message?: string; response?: { status?: number; data?: unknown }; }; const details = [ axiosError.response?.status ? `status=${axiosError.response.status}` : undefined, axiosError.response?.data !== undefined ? `data=${JSON.stringify(axiosError.response.data)}` : undefined, axiosError.message ? `message=${axiosError.message}` : undefined, ].filter(Boolean); return details.join(" ") || "Axios request failed without details"; } return error instanceof Error ? error.message : String(error); } export async function dispatchWhatsApp(params: { companyId: string; appointmentId: string; type: string; systemToken: string; phoneNumber: string; message: string; companyOwnerId: string; }): Promise { try { if (!params.phoneNumber.trim() || !params.message.trim() || !params.companyOwnerId.trim()) { return { success: false, error: "WhatsApp dispatch requires phoneNumber, message, and companyOwnerId" }; } // Send worker-rendered content directly so cancellation jobs survive appointment deletion. const axios = (await import("axios")).default; const response = await axios.post( buildApiUrl("/notifications/send-wap"), { systemToken: params.systemToken, phoneNumber: params.phoneNumber, message: params.message, companyId: params.companyId, sessionUser: params.companyOwnerId, }, { headers: { "Content-Type": "application/json" }, } ); logDone(`WhatsApp dispatched for company ${params.companyId}`); return { success: true, providerResponse: JSON.stringify(response.data) }; } catch (error) { const msg = formatDispatchError(error); logError(`WhatsApp dispatch failed for company ${params.companyId}:`, msg); return { success: false, error: msg }; } } export async function dispatchEmail(params: { appointmentId: string; systemToken: string; type: string; email: string; subject: string; message: string; }): Promise { try { if (!params.email.trim() || !params.subject.trim() || !params.message.trim()) { return { success: false, error: "Email dispatch requires email, subject, and message" }; } // Send worker-rendered content directly so cancellation jobs survive appointment deletion. const axios = (await import("axios")).default; const response = await axios.post( buildApiUrl("/notifications/send-email"), { systemToken: params.systemToken, email: params.email, subject: params.subject, message: params.message, }, { headers: { "Content-Type": "application/json" }, } ); const responseData = response.data as { success?: boolean }; if (responseData.success === false) { return { success: false, error: formatResponseFailure("notifications/send-email", response.data), }; } logDone(`Email dispatched to ${params.email}`); return { success: true, providerResponse: JSON.stringify(response.data) }; } catch (error) { const msg = formatDispatchError(error); logError(`Email dispatch failed for ${params.email}:`, msg); return { success: false, error: msg }; } } export async function dispatchSystem(params: { systemToken: string; userId: string; subject: string; message: string; companyId?: string; serviceId?: number; conversationId?: string; type?: string; code?: string; }): Promise { try { if (!params.userId.trim() || !params.subject.trim() || !params.message.trim()) { return { success: false, error: "System dispatch requires userId, subject, and message" }; } // Delegate to the server API for system notification const axios = (await import("axios")).default; const response = await axios.post( buildApiUrl("/systemnotifications/create"), { userId: params.userId, subject: params.subject, message: params.message, companyId: params.companyId, serviceId: params.serviceId, conversationId: params.conversationId, type: params.type, code: params.code, systemToken: params.systemToken, }, { headers: { "Content-Type": "application/json" }, } ); const responseData = response.data as { success?: boolean }; if (responseData.success === false) { return { success: false, error: formatResponseFailure("systemnotifications/create", response.data), }; } logDone(`System notification dispatched to user ${params.userId}`); return { success: true, providerResponse: JSON.stringify(response.data) }; } catch (error) { const msg = formatDispatchError(error); logError(`System notification dispatch failed for user ${params.userId}:`, msg); return { success: false, error: msg }; } }