novapsis 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -48,7 +48,7 @@ var HttpClient = class {
48
48
  headers: {
49
49
  "Authorization": `Bearer ${this.apiKey}`,
50
50
  "Content-Type": "application/json",
51
- "User-Agent": "Novapsis-SDK-Node/1.1.0"
51
+ "User-Agent": "Novapsis-SDK-Node/1.1.1"
52
52
  },
53
53
  body: body ? JSON.stringify(body) : void 0,
54
54
  signal: controller.signal
@@ -461,7 +461,7 @@ var index_default = Novapsis;
461
461
  * Universal typed client for WhatsApp Business Cloud API, Hosted Onboarding,
462
462
  * CRM, AI Agents and HMAC Webhook Verification.
463
463
  *
464
- * @version 1.1.0
464
+ * @version 1.1.1
465
465
  * @author Novapsis Technologies
466
466
  * @license MIT
467
467
  * ══════════════════════════════════════════════════════════════════════════════
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["crypto"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * novapsis - Official TypeScript / JavaScript SDK\n * ══════════════════════════════════════════════════════════════════════════════\n * Official SDK for Novapsis SM.\n * Universal typed client for WhatsApp Business Cloud API, Hosted Onboarding,\n * CRM, AI Agents and HMAC Webhook Verification.\n *\n * @version 1.1.0\n * @author Novapsis Technologies\n * @license MIT\n * ══════════════════════════════════════════════════════════════════════════════\n */\n\nimport crypto from 'crypto';\n\n// ── TYPES & DEFINITIONS ──────────────────────────────────────────────────────\n\nexport interface NovapsisClientOptions {\n /** Clave de API de Novapsis (empieza por nvs_live_ o nvs_test_) */\n apiKey: string;\n /** URL base de la API (por defecto: https://app.novapsis.com) */\n baseUrl?: string;\n /** Timeout en milisegundos para peticiones HTTP (por defecto: 15000) */\n timeoutMs?: number;\n /** Número máximo de reintentos automáticos ante fallos de red transitorios (por defecto: 2) */\n maxRetries?: number;\n}\n\nexport interface APIResponse<T = any> {\n success: boolean;\n data?: T;\n error?: {\n code: string;\n message: string;\n details?: any;\n };\n}\n\nexport class NovapsisAPIError extends Error {\n public readonly code: string;\n public readonly status: number;\n public readonly details?: any;\n\n constructor(message: string, code = 'API_ERROR', status = 500, details?: any) {\n super(message);\n this.name = 'NovapsisAPIError';\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\n// ── WHATSAPP TYPES ───────────────────────────────────────────────────────────\n\nexport interface SendBaseOptions {\n /** Número destinatario con código de país, sin '+' ni espacios (ej: '34600112233') */\n to: string;\n /** UUID de la conexión o Phone Number ID de Meta desde el cual enviar. Si se omite, usa la línea principal. */\n connectionId?: string;\n}\n\nexport interface SendTextOptions extends SendBaseOptions {\n /** Cuerpo del mensaje de texto */\n text: string;\n /** Si es true, genera vista previa de los enlaces web incluidos en el texto */\n previewUrl?: boolean;\n}\n\nexport interface SendImageOptions extends SendBaseOptions {\n /** URL HTTPS pública de la imagen (JPG, PNG, WebP) */\n imageUrl: string;\n /** Pie de foto opcional */\n caption?: string;\n}\n\nexport interface SendAudioOptions extends SendBaseOptions {\n /** URL HTTPS pública del archivo de audio (MP3, AAC, OGG, M4A) */\n audioUrl: string;\n}\n\nexport interface SendDocumentOptions extends SendBaseOptions {\n /** URL HTTPS pública del documento o PDF */\n documentUrl: string;\n /** Nombre visible del archivo (ej: 'factura_2026.pdf') */\n filename?: string;\n /** Descripción o pie opcional */\n caption?: string;\n}\n\nexport interface SendVideoOptions extends SendBaseOptions {\n /** URL HTTPS pública del video (MP4, 3GP) */\n videoUrl: string;\n /** Pie de video opcional */\n caption?: string;\n}\n\nexport interface SendLocationOptions extends SendBaseOptions {\n /** Coordenada de latitud decimal (ej: 40.416775) */\n latitude: number | string;\n /** Coordenada de longitud decimal (ej: -3.703790) */\n longitude: number | string;\n /** Nombre del lugar o establecimiento (ej: 'Sede Central Madrid') */\n name?: string;\n /** Dirección postal completa */\n address?: string;\n}\n\nexport interface SendContactCardOptions extends SendBaseOptions {\n /** Nombre completo del contacto a compartir */\n name: string;\n /** Número de teléfono del contacto compartido */\n phone: string;\n}\n\nexport interface SendTemplateOptions extends SendBaseOptions {\n /** Nombre exacto de la plantilla aprobada en Meta */\n templateName: string;\n /** Código de idioma (por defecto: 'es') */\n languageCode?: string;\n /** Componentes y variables dinámicas de la plantilla */\n components?: Array<{\n type: 'header' | 'body' | 'button';\n sub_type?: string;\n index?: string | number;\n parameters?: Array<{\n type: 'text' | 'image' | 'document' | 'video' | 'currency' | 'date_time';\n text?: string;\n [key: string]: any;\n }>;\n }>;\n}\n\nexport interface SendMessageResult {\n message_id: string;\n recipient: string;\n connection_id?: string;\n phone_number_id?: string;\n business_phone_number?: string | null;\n type: string;\n status: string;\n conversation_id: string | null;\n}\n\nexport interface WhatsAppConnection {\n id: string;\n display_name: string;\n phone_number: string | null;\n phone_number_id: string;\n waba_id?: string | null;\n verified_name: string | null;\n quality_rating?: string | null;\n status: string;\n webhook_subscribed: boolean;\n created_at?: string;\n}\n\nexport interface WhatsAppTemplate {\n id: string;\n template_name?: string;\n display_name?: string;\n name?: string;\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION' | string;\n language: string;\n status: 'APPROVED' | 'PENDING' | 'REJECTED' | 'PAUSED' | string;\n quality_rating?: string | null;\n components: any[];\n meta_template_id?: string | null;\n rejection_reason?: string | null;\n waba_id?: string | null;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ListTemplatesOptions {\n /** Filtrar por estado en Meta (ej: 'APPROVED', 'PENDING', 'REJECTED') */\n status?: 'APPROVED' | 'PENDING' | 'REJECTED' | 'PAUSED' | string;\n /** Filtrar por categoría oficial */\n category?: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION' | string;\n}\n\nexport interface CreateTemplateOptions {\n /** Nombre técnico en Meta (solo minúsculas, números y guiones bajos, ej: 'confirmacion_pedido_v1') */\n name?: string;\n template_name?: string;\n /** Nombre descriptivo para el panel */\n displayName?: string;\n display_name?: string;\n /** Categoría oficial de Meta */\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION';\n /** Código de idioma (por defecto: 'es') */\n language?: string;\n /** Componentes según especificación de Meta Graph API (HEADER, BODY, BUTTONS, etc.) */\n components?: any[];\n /** Texto plano del cuerpo si no se envían componentes avanzados */\n bodyText?: string;\n /** ID de conexión de WhatsApp (opcional si la cuenta tiene una sola activa) */\n connectionId?: string;\n connection_id?: string;\n /** TTL de entrega en segundos (opcional) */\n messageSendTtlSeconds?: number;\n}\n\n// ── ORGANIZATION & SETTINGS TYPES ───────────────────────────────────────────\n\nexport interface OrganizationDetails {\n id: string;\n name: string;\n timezone: string;\n tier: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UpdateOrganizationOptions {\n /** Nombre de la empresa o aplicación (cambio de nombre / settings de la app) */\n name?: string;\n /** Zona horaria IANA (ej: 'Europe/Madrid', 'America/Bogota', 'America/Mexico_City') */\n timezone?: string;\n}\n\n// ── AI AGENTS & RAG TYPES ───────────────────────────────────────────────────\n\nexport interface AgentDetails {\n id: string;\n name: string;\n system_prompt: string;\n model: string;\n mode: 'agent' | 'rag' | 'both';\n temperature: number;\n is_active: boolean;\n grouping_timeout_seconds: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CreateAgentOptions {\n /** Nombre del agente de IA (ej: 'Asistente Ventas') */\n name: string;\n /** Prompt de sistema e instrucciones de comportamiento */\n systemPrompt: string;\n /** Modelo de IA a utilizar (por defecto: 'gemini-2.5-flash') */\n model?: string;\n /** Modo de operación: 'agent', 'rag' o 'both' */\n mode?: 'agent' | 'rag' | 'both';\n /** Creatividad (temperatura 0.0 - 1.0) */\n temperature?: number;\n /** Si el agente está activo respondiendo chats */\n isActive?: boolean;\n /** Ventana de agrupación de mensajes en segundos */\n groupingTimeoutSeconds?: number;\n}\n\nexport interface UpdateAgentOptions {\n /** Nuevo nombre del agente (cambio de nombre del bot) */\n name?: string;\n /** Nuevo prompt de sistema */\n systemPrompt?: string;\n /** Modelo de IA */\n model?: string;\n /** Modo de operación */\n mode?: 'agent' | 'rag' | 'both';\n /** Creatividad */\n temperature?: number;\n /** Estado activo o inactivo */\n isActive?: boolean;\n /** Ventana de agrupación en segundos */\n groupingTimeoutSeconds?: number;\n}\n\nexport interface AgentSchedule {\n id: string;\n agent_id: string;\n name: string;\n days: number[]; // 1=Lunes, 7=Domingo\n active_from: string; // \"HH:MM\"\n active_until: string; // \"HH:MM\"\n is_active: boolean;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface SetScheduleOptions {\n /** Días activos: 1=Lunes, 2=Martes, 3=Miércoles, 4=Jueves, 5=Viernes, 6=Sábado, 7=Domingo */\n days: number[];\n /** Hora de apertura en formato HH:MM (ej: '09:00') */\n activeFrom: string;\n /** Hora de cierre en formato HH:MM (ej: '19:00') */\n activeUntil: string;\n /** Nombre de la franja horaria */\n name?: string;\n /** Si el horario está habilitado */\n isActive?: boolean;\n}\n\nexport interface KnowledgeDocument {\n id: string;\n title: string;\n description?: string | null;\n file_type: string;\n total_chunks?: number;\n created_at: string;\n updated_at?: string;\n}\n\nexport interface AddKnowledgeOptions {\n /** Título o tema del documento (ej: 'Políticas de garantía y devoluciones') */\n title: string;\n /** Contenido en texto plano a vectorizar para RAG */\n content: string;\n /** Descripción contextual */\n description?: string;\n}\n\n// ── ONBOARDING TYPES ─────────────────────────────────────────────────────────\n\nexport interface OnboardingFeatureBullet {\n title: string;\n description?: string;\n}\n\nexport interface CreateOnboardingSessionOptions {\n /** Nombre del cliente, empresa o sede (ej: 'Clínica Dental') */\n clientName?: string;\n /** Nombre corporativo visible */\n companyName?: string;\n /** URL de retorno tras conectar exitosamente con WhatsApp */\n redirectUrl?: string;\n /** URL pública del logotipo corporativo para marca blanca (PNG, SVG, JPG) */\n logoUrl?: string;\n\n // ── Personalización de Estilos y Colores (Marca Blanca) ──\n /** Color de acento principal (ej: '#0ea5e9') */\n brandColor?: string;\n /** Color de fondo general de la pantalla (ej: '#0f172a' o '#ffffff') */\n backgroundColor?: string;\n /** Color de fondo de la tarjeta/modal (ej: '#1e293b' o '#ffffff') */\n cardBackgroundColor?: string;\n /** Color del borde de la tarjeta (ej: 'rgba(255,255,255,0.1)') */\n cardBorderColor?: string;\n /** Color de los títulos y textos principales (ej: '#ffffff' o '#0f172a') */\n textColor?: string;\n /** Color de los textos secundarios y descripciones (ej: '#94a3b8') */\n textSecondaryColor?: string;\n /** Color de fondo del botón de acción (por defecto usa brandColor o verde WhatsApp) */\n buttonColor?: string;\n /** Color del texto dentro del botón de acción */\n buttonTextColor?: string;\n /** Color de fondo de la píldora superior */\n badgeColor?: string;\n /** Color del texto de la píldora superior */\n badgeTextColor?: string;\n\n // ── Personalización de Copys y Textos ──\n /** Título principal (por defecto: 'Conecta WhatsApp Business') */\n title?: string;\n /** Texto explicativo debajo del título */\n description?: string;\n /** Texto del botón principal (por defecto: 'Conectar con WhatsApp') */\n buttonText?: string;\n /** Texto de la píldora superior (por defecto: 'Vinculación Oficial', o '' para ocultar) */\n badgeText?: string;\n /** Texto legal o footer de la tarjeta */\n footerText?: string;\n /** Viñetas de beneficios o false para ocultar la caja */\n features?: OnboardingFeatureBullet[] | boolean;\n /** Título de la pantalla de éxito tras vincular */\n successTitle?: string;\n /** Descripción de la pantalla de éxito */\n successDescription?: string;\n /** Texto del botón en la pantalla de éxito */\n successButtonText?: string;\n /** Si es true, oculta el badge 'Meta Tech Provider Verified' del encabezado */\n hideMetaBadge?: boolean;\n /** Si es true, oculta el pie de página de copyright */\n hideFooter?: boolean;\n\n /** Horas de validez de la sesión antes de expirar (por defecto: 168 = 7 días) */\n expiresInHours?: number;\n /** Metadata personalizada para tracking en tu CRM */\n metadata?: Record<string, any>;\n}\n\nexport interface OnboardingSession {\n id: string;\n session_id: string;\n session_url: string;\n status: 'started' | 'completed' | 'expired' | 'failed';\n expires_at: string;\n created_at: string;\n}\n\n// ── WEBHOOK TYPES ────────────────────────────────────────────────────────────\n\nexport type NovapsisWebhookEvent =\n | 'whatsapp.message_received'\n | 'whatsapp.message_sent'\n | 'whatsapp.connected'\n | 'conversation.started'\n | 'lead.completed'\n | 'call.completed'\n | 'review.received'\n | '*';\n\nexport interface WhatsAppMessageReceivedData {\n conversation_id: string;\n message_id: string;\n external_message_id?: string | null;\n platform: 'whatsapp' | string;\n\n // ── Datos completos de la línea receptora (Empresa) ──\n connection_id: string;\n phone_number_id: string;\n waba_id?: string | null;\n business_phone_number: string | null;\n business_name?: string | null;\n connection_name?: string | null;\n to: string | null;\n\n // ── Datos del cliente emisor ──\n from: string;\n external_user_id: string;\n external_user_name: string;\n\n // ── Contenido y Multimedia ──\n content: string;\n media_type: 'image' | 'audio' | 'video' | 'document' | null;\n media_url: string | null;\n timestamp: string;\n}\n\nexport interface WhatsAppMessageSentData {\n conversation_id: string;\n message_id: string;\n platform: 'whatsapp' | string;\n\n // ── Datos completos de la línea emisora (Empresa) ──\n connection_id: string;\n phone_number_id: string;\n waba_id?: string | null;\n business_phone_number: string | null;\n business_name?: string | null;\n connection_name?: string | null;\n from: string | null;\n\n // ── Datos del destinatario (Cliente) ──\n to: string;\n external_user_id: string;\n\n role: 'assistant';\n sender_type: 'ai' | 'human';\n content: string;\n media_type?: string | null;\n media_url?: string | null;\n timestamp: string;\n}\n\nexport interface CreateWebhookSubscriptionOptions {\n /** Nombre descriptivo de la suscripción (ej: 'CRM Sincronizador') */\n name: string;\n /** URL HTTPS de tu backend que recibirá los eventos POST */\n url: string;\n /** Lista de eventos a escuchar */\n events: NovapsisWebhookEvent[];\n /** Secreto opcional para firma HMAC. Si se omite, Novapsis generará uno automáticamente. */\n secret?: string;\n}\n\nexport interface WebhookSubscription {\n id: string;\n name: string;\n url: string;\n events: string[];\n secret: string;\n is_active: boolean;\n created_at: string;\n}\n\nexport interface InboundWebhookPayload<T = any> {\n event: NovapsisWebhookEvent;\n timestamp: string;\n organization_id: string;\n data: T;\n}\n\n// ── CRM & CONTACTS TYPES ─────────────────────────────────────────────────────\n\nexport interface UpsertContactOptions {\n phone: string;\n name?: string;\n email?: string;\n tags?: string[];\n metadata?: Record<string, any>;\n}\n\nexport interface Contact {\n id: string;\n phone: string;\n name: string | null;\n email: string | null;\n tags: string[];\n created_at: string;\n}\n\n// ── INTERNAL HTTP CLIENT ────────────────────────────────────────────────────\n\nclass HttpClient {\n private apiKey: string;\n private baseUrl: string;\n private timeoutMs: number;\n private maxRetries: number;\n\n constructor(options: NovapsisClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl || 'https://app.novapsis.com').replace(/\\/+$/, '');\n this.timeoutMs = options.timeoutMs || 15000;\n this.maxRetries = options.maxRetries ?? 2;\n }\n\n async request<T>(method: string, path: string, body?: any, query?: Record<string, string>): Promise<T> {\n let url = `${this.baseUrl}/api/v1${path.startsWith('/') ? path : `/${path}`}`;\n if (query && Object.keys(query).length > 0) {\n const qs = new URLSearchParams(query).toString();\n url += `?${qs}`;\n }\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'Novapsis-SDK-Node/1.1.0',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const data: APIResponse<T> = await response.json().catch(() => ({\n success: false,\n error: { code: 'INVALID_JSON_RESPONSE', message: `HTTP ${response.status} Sin cuerpo JSON válido.` },\n }));\n\n if (!response.ok || !data.success) {\n throw new NovapsisAPIError(\n data.error?.message || `Error en petición HTTP ${response.status}`,\n data.error?.code || `HTTP_${response.status}`,\n response.status,\n data.error?.details\n );\n }\n\n return data.data as T;\n } catch (err: any) {\n clearTimeout(timeoutId);\n lastError = err;\n\n // No reintentar errores de validación de cliente 4xx\n if (err instanceof NovapsisAPIError && err.status >= 400 && err.status < 500) {\n throw err;\n }\n\n // Si es el último intento, lanzar el error\n if (attempt === this.maxRetries) {\n break;\n }\n\n // Backoff exponencial: 300ms, 900ms...\n await new Promise((resolve) => setTimeout(resolve, 300 * Math.pow(3, attempt)));\n }\n }\n\n throw lastError || new NovapsisAPIError('Error de red al comunicarse con Novapsis API', 'NETWORK_ERROR', 0);\n }\n}\n\n// ── SDK SERVICES ────────────────────────────────────────────────────────────\n\n/** Servicio para envíos y gestión de WhatsApp Cloud API */\nexport class WhatsAppService {\n constructor(private http: HttpClient) {}\n\n /** Envía un mensaje de texto plano */\n async sendText(options: SendTextOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'text',\n text: options.text,\n });\n }\n\n /** Envía una imagen o fotografía */\n async sendImage(options: SendImageOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'image',\n media_url: options.imageUrl,\n caption: options.caption,\n });\n }\n\n /** Envía un archivo de audio o nota de voz */\n async sendAudio(options: SendAudioOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'audio',\n media_url: options.audioUrl,\n });\n }\n\n /** Envía un documento (PDF, Word, Excel, etc.) con nombre de archivo personalizado */\n async sendDocument(options: SendDocumentOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'document',\n media_url: options.documentUrl,\n filename: options.filename,\n caption: options.caption,\n });\n }\n\n /** Envía un video */\n async sendVideo(options: SendVideoOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'video',\n media_url: options.videoUrl,\n caption: options.caption,\n });\n }\n\n /** Envía una ubicación con coordenadas y dirección en el mapa */\n async sendLocation(options: SendLocationOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'location',\n latitude: options.latitude,\n longitude: options.longitude,\n location_name: options.name,\n location_address: options.address,\n });\n }\n\n /** Envía una tarjeta de contacto (vCard) interactiva */\n async sendContact(options: SendContactCardOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'contacts',\n contact_name: options.name,\n contact_phone: options.phone,\n });\n }\n\n /** Envía una plantilla oficial aprobada por Meta con variables dinámicas */\n async sendTemplate(options: SendTemplateOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'template',\n template_name: options.templateName,\n language_code: options.languageCode || 'es',\n components: options.components || [],\n });\n }\n\n /** Marca un mensaje o chat como leído */\n async markAsRead(options: { to: string; connectionId?: string; messageId?: string }): Promise<any> {\n return this.http.request('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'mark_read',\n message_id: options.messageId,\n });\n }\n\n /** Obtiene la lista de líneas y números de WhatsApp conectados en la organización */\n async listConnections(): Promise<WhatsAppConnection[]> {\n const res = await this.http.request<{ connections: WhatsAppConnection[] }>('GET', '/whatsapp/connections');\n return res.connections;\n }\n\n /** Lista las plantillas oficiales de Meta con filtros opcionales de estado y categoría */\n async listTemplates(options: ListTemplatesOptions = {}): Promise<WhatsAppTemplate[]> {\n const query: Record<string, string> = {};\n if (options.status) query.status = options.status;\n if (options.category) query.category = options.category;\n const res = await this.http.request<{ templates: WhatsAppTemplate[] }>('GET', '/whatsapp/templates', undefined, query);\n return res.templates;\n }\n\n /** Obtiene las plantillas oficiales de Meta aprobadas (alias directo de listTemplates) */\n async getTemplates(): Promise<WhatsAppTemplate[]> {\n return this.listTemplates();\n }\n\n /** Crea una nueva plantilla oficial de WhatsApp para someter a revisión y aprobación en Meta */\n async createTemplate(options: CreateTemplateOptions): Promise<{ template: WhatsAppTemplate }> {\n const templateName = options.template_name || options.name;\n if (!templateName) {\n throw new NovapsisAPIError('Se requiere `name` o `template_name` para crear una plantilla.', 'VALIDATION_ERROR', 400);\n }\n const components = options.components || (options.bodyText ? [{ type: 'BODY', text: options.bodyText }] : []);\n\n return this.http.request<{ template: WhatsAppTemplate }>('POST', '/whatsapp/templates', {\n template_name: templateName,\n display_name: options.displayName || options.display_name,\n category: options.category,\n language: options.language || 'es',\n components,\n connection_id: options.connectionId || options.connection_id,\n message_send_ttl_seconds: options.messageSendTtlSeconds,\n });\n }\n\n /** Lista las campañas masivas de WhatsApp configuradas */\n async listCampaigns(): Promise<any[]> {\n const res = await this.http.request<{ campaigns: any[] }>('GET', '/whatsapp/campaigns');\n return res.campaigns;\n }\n\n /** Ejecuta una campaña masiva */\n async executeCampaign(campaignId: string): Promise<any> {\n return this.http.request('POST', `/whatsapp/campaigns/${campaignId}/execute`);\n }\n}\n\n/** Servicio para onboarding y conexión de WhatsApp de clientes B2B (Marca Blanca) */\nexport class OnboardingService {\n constructor(private http: HttpClient) {}\n\n /**\n * Crea una sesión de conexión hosted para que un cliente o sede vincule su WhatsApp.\n * Devuelve `session_url` que puedes abrir en un modal o popup en tu CRM.\n */\n async createSession(options: CreateOnboardingSessionOptions = {}): Promise<OnboardingSession> {\n return this.http.request<OnboardingSession>('POST', '/onboarding/sessions', {\n client_name: options.clientName,\n company_name: options.companyName,\n redirect_url: options.redirectUrl,\n logo_url: options.logoUrl,\n brand_color: options.brandColor,\n background_color: options.backgroundColor,\n card_background_color: options.cardBackgroundColor,\n card_border_color: options.cardBorderColor,\n text_color: options.textColor,\n text_secondary_color: options.textSecondaryColor,\n button_color: options.buttonColor,\n button_text_color: options.buttonTextColor,\n badge_color: options.badgeColor,\n badge_text_color: options.badgeTextColor,\n title: options.title,\n description: options.description,\n button_text: options.buttonText,\n badge_text: options.badgeText,\n footer_text: options.footerText,\n features: options.features,\n success_title: options.successTitle,\n success_description: options.successDescription,\n success_button_text: options.successButtonText,\n hide_meta_badge: options.hideMetaBadge,\n hide_footer: options.hideFooter,\n expires_in_hours: options.expiresInHours,\n metadata: options.metadata,\n });\n }\n\n /** Consulta el estado de una sesión de onboarding por su ID */\n async getSessionStatus(sessionId: string): Promise<OnboardingSession> {\n return this.http.request<OnboardingSession>('GET', `/onboarding/sessions/${sessionId}`);\n }\n}\n\n/** Servicio para gestionar Webhooks salientes en tiempo real */\nexport class WebhookService {\n constructor(private http: HttpClient) {}\n\n /** Suscribe una URL de tu backend para recibir eventos en tiempo real */\n async subscribe(options: CreateWebhookSubscriptionOptions): Promise<WebhookSubscription> {\n return this.http.request<WebhookSubscription>('POST', '/webhooks/subscriptions', {\n name: options.name,\n url: options.url,\n events: options.events,\n secret: options.secret,\n is_active: true,\n });\n }\n\n /** Lista todas las suscripciones de webhooks activas */\n async list(): Promise<WebhookSubscription[]> {\n const res = await this.http.request<{ subscriptions: WebhookSubscription[] }>('GET', '/webhooks/subscriptions');\n return res.subscriptions;\n }\n\n /** Elimina una suscripción de webhook */\n async delete(webhookId: string): Promise<boolean> {\n const res = await this.http.request<{ success: boolean }>('DELETE', `/webhooks/subscriptions/${webhookId}`);\n return res.success;\n }\n\n /**\n * Valida la firma criptográfica HMAC SHA-256 de un webhook recibido de Novapsis SM.\n * Evita ataques de suplantación garantizando que la petición proviene de Novapsis.\n *\n * @param rawBody - El cuerpo crudo recibido en el request (string sin parsear)\n * @param signatureHeader - El header 'X-Novapsis-Signature'\n * @param secret - Tu secreto de webhook de Novapsis\n */\n verifySignature(rawBody: string, signatureHeader: string | null | undefined, secret: string): boolean {\n if (!signatureHeader || !secret || !rawBody) return false;\n try {\n const cleanSig = signatureHeader.startsWith('sha256=')\n ? signatureHeader.slice(7)\n : signatureHeader;\n const computed = crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex');\n const bufA = Buffer.from(computed, 'hex');\n const bufB = Buffer.from(cleanSig, 'hex');\n if (bufA.length !== bufB.length) return false;\n return crypto.timingSafeEqual(bufA, bufB);\n } catch {\n return false;\n }\n }\n}\n\n/** Servicio para gestionar Contactos del CRM */\nexport class ContactsService {\n constructor(private http: HttpClient) {}\n\n /** Lista contactos del CRM */\n async list(): Promise<Contact[]> {\n const res = await this.http.request<{ contacts: Contact[] }>('GET', '/contacts');\n return res.contacts;\n }\n\n /** Crea o actualiza un contacto por número de teléfono */\n async upsert(options: UpsertContactOptions): Promise<Contact> {\n return this.http.request<Contact>('POST', '/contacts', options);\n }\n}\n\n/** Servicio para gestión de la organización y configuración general (Marca / Settings) */\nexport class OrganizationService {\n constructor(private http: HttpClient) {}\n\n /** Obtiene la información y configuración de la organización actual */\n async get(): Promise<OrganizationDetails> {\n const res = await this.http.request<{ organization: OrganizationDetails }>('GET', '/organization');\n return res.organization;\n }\n\n /**\n * Actualiza la configuración de la organización (cambio de nombre de la app/empresa, zona horaria)\n */\n async update(options: UpdateOrganizationOptions): Promise<OrganizationDetails> {\n const res = await this.http.request<{ organization: OrganizationDetails }>('PATCH', '/organization', {\n name: options.name,\n timezone: options.timezone,\n });\n return res.organization;\n }\n}\n\n/** Servicio para interactuar y configurar Agentes de Inteligencia Artificial (Headless AI) */\nexport class AIService {\n constructor(private http: HttpClient) {}\n\n /** Lista los agentes de IA configurados en la organización */\n async listAgents(): Promise<AgentDetails[]> {\n const res = await this.http.request<{ agents: AgentDetails[] }>('GET', '/ai/agents');\n return res.agents;\n }\n\n /** Obtiene la configuración completa de un agente por su ID */\n async getAgent(agentId: string): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('GET', `/ai/agents/${agentId}`);\n return res.agent;\n }\n\n /** Crea un nuevo agente de IA para la organización */\n async createAgent(options: CreateAgentOptions): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('POST', '/ai/agents', {\n name: options.name,\n system_prompt: options.systemPrompt,\n model: options.model,\n mode: options.mode,\n temperature: options.temperature,\n is_active: options.isActive,\n grouping_timeout_seconds: options.groupingTimeoutSeconds,\n });\n return res.agent;\n }\n\n /** Actualiza nombre, prompt de sistema, modelo o configuración de un agente */\n async updateAgent(agentId: string, options: UpdateAgentOptions): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('PATCH', `/ai/agents/${agentId}`, {\n name: options.name,\n system_prompt: options.systemPrompt,\n model: options.model,\n mode: options.mode,\n temperature: options.temperature,\n is_active: options.isActive,\n grouping_timeout_seconds: options.groupingTimeoutSeconds,\n });\n return res.agent;\n }\n\n /** Consulta el horario de atención configurado para el agente y la zona horaria */\n async getSchedule(agentId: string): Promise<{ schedule: AgentSchedule | null; timezone: string }> {\n return this.http.request<{ schedule: AgentSchedule | null; timezone: string }>('GET', `/ai/agents/${agentId}/schedule`);\n }\n\n /** Configura o reemplaza el horario de atención activa del agente */\n async setSchedule(agentId: string, options: SetScheduleOptions): Promise<{ schedule: AgentSchedule; timezone: string }> {\n return this.http.request<{ schedule: AgentSchedule; timezone: string }>('PUT', `/ai/agents/${agentId}/schedule`, {\n days: options.days,\n active_from: options.activeFrom,\n active_until: options.activeUntil,\n name: options.name,\n is_active: options.isActive,\n });\n }\n\n /** Lista los documentos de la base de conocimiento RAG asociados al agente */\n async listKnowledge(agentId: string): Promise<KnowledgeDocument[]> {\n const res = await this.http.request<{ documents: KnowledgeDocument[] }>('GET', `/ai/agents/${agentId}/knowledge`);\n return res.documents;\n }\n\n /** Ingesta y vectoriza nuevo conocimiento en texto plano directamente al agente */\n async addKnowledge(agentId: string, options: AddKnowledgeOptions): Promise<KnowledgeDocument> {\n const res = await this.http.request<{ document: KnowledgeDocument }>('POST', `/ai/agents/${agentId}/knowledge`, {\n title: options.title,\n content: options.content,\n description: options.description,\n });\n return res.document;\n }\n\n /** Ejecuta una consulta conversacional contra el agente y su base de conocimiento RAG */\n async execute(options: { agentId: string; message: string }): Promise<{ response: string; tokens_used?: number }> {\n return this.http.request('POST', `/ai/agents/${options.agentId}/execute`, {\n message: options.message,\n });\n }\n}\n\n// ── MAIN CLIENT ─────────────────────────────────────────────────────────────\n\n/**\n * Cliente oficial de Novapsis SM.\n * Punto de entrada principal para interactuar con todos los servicios.\n *\n * @example\n * ```typescript\n * import { Novapsis } from 'novapsis';\n *\n * const client = new Novapsis({\n * apiKey: 'nvs_live_sample_abcdef1234567890',\n * });\n *\n * // Enviar mensaje de texto\n * await client.whatsapp.sendText({\n * to: '34600112233',\n * text: '¡Hola desde Novapsis SDK!'\n * });\n * ```\n */\nexport class Novapsis {\n private http: HttpClient;\n\n /** Métodos para ajustes de la organización y cambio de nombre de la app */\n public readonly organization: OrganizationService;\n /** Métodos para envíos y operaciones de WhatsApp */\n public readonly whatsapp: WhatsAppService;\n /** Métodos para onboarding hosted y vinculación B2B */\n public readonly onboarding: OnboardingService;\n /** Métodos para suscripción y validación de Webhooks */\n public readonly webhooks: WebhookService;\n /** Métodos para contactos del CRM */\n public readonly contacts: ContactsService;\n /** Métodos para Agentes de Inteligencia Artificial (prompts, RAG, horarios) */\n public readonly ai: AIService;\n\n constructor(options: NovapsisClientOptions) {\n if (!options.apiKey) {\n throw new NovapsisAPIError('Se requiere una apiKey válida para inicializar el cliente de Novapsis.', 'CONFIG_ERROR', 400);\n }\n this.http = new HttpClient(options);\n this.organization = new OrganizationService(this.http);\n this.whatsapp = new WhatsAppService(this.http);\n this.onboarding = new OnboardingService(this.http);\n this.webhooks = new WebhookService(this.http);\n this.contacts = new ContactsService(this.http);\n this.ai = new AIService(this.http);\n }\n}\n\n// Default export\nexport default Novapsis;\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["crypto"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * novapsis - Official TypeScript / JavaScript SDK\n * ══════════════════════════════════════════════════════════════════════════════\n * Official SDK for Novapsis SM.\n * Universal typed client for WhatsApp Business Cloud API, Hosted Onboarding,\n * CRM, AI Agents and HMAC Webhook Verification.\n *\n * @version 1.1.1\n * @author Novapsis Technologies\n * @license MIT\n * ══════════════════════════════════════════════════════════════════════════════\n */\n\nimport crypto from 'crypto';\n\n// ── TYPES & DEFINITIONS ──────────────────────────────────────────────────────\n\nexport interface NovapsisClientOptions {\n /** Clave de API de Novapsis (empieza por nvs_live_ o nvs_test_) */\n apiKey: string;\n /** URL base de la API (por defecto: https://app.novapsis.com) */\n baseUrl?: string;\n /** Timeout en milisegundos para peticiones HTTP (por defecto: 15000) */\n timeoutMs?: number;\n /** Número máximo de reintentos automáticos ante fallos de red transitorios (por defecto: 2) */\n maxRetries?: number;\n}\n\nexport interface APIResponse<T = any> {\n success: boolean;\n data?: T;\n error?: {\n code: string;\n message: string;\n details?: any;\n };\n}\n\nexport class NovapsisAPIError extends Error {\n public readonly code: string;\n public readonly status: number;\n public readonly details?: any;\n\n constructor(message: string, code = 'API_ERROR', status = 500, details?: any) {\n super(message);\n this.name = 'NovapsisAPIError';\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\n// ── WHATSAPP TYPES ───────────────────────────────────────────────────────────\n\nexport interface SendBaseOptions {\n /** Número destinatario con código de país, sin '+' ni espacios (ej: '34600112233') */\n to: string;\n /** UUID de la conexión o Phone Number ID de Meta desde el cual enviar. Si se omite, usa la línea principal. */\n connectionId?: string;\n}\n\nexport interface SendTextOptions extends SendBaseOptions {\n /** Cuerpo del mensaje de texto */\n text: string;\n /** Si es true, genera vista previa de los enlaces web incluidos en el texto */\n previewUrl?: boolean;\n}\n\nexport interface SendImageOptions extends SendBaseOptions {\n /** URL HTTPS pública de la imagen (JPG, PNG, WebP) */\n imageUrl: string;\n /** Pie de foto opcional */\n caption?: string;\n}\n\nexport interface SendAudioOptions extends SendBaseOptions {\n /** URL HTTPS pública del archivo de audio (MP3, AAC, OGG, M4A) */\n audioUrl: string;\n}\n\nexport interface SendDocumentOptions extends SendBaseOptions {\n /** URL HTTPS pública del documento o PDF */\n documentUrl: string;\n /** Nombre visible del archivo (ej: 'factura_2026.pdf') */\n filename?: string;\n /** Descripción o pie opcional */\n caption?: string;\n}\n\nexport interface SendVideoOptions extends SendBaseOptions {\n /** URL HTTPS pública del video (MP4, 3GP) */\n videoUrl: string;\n /** Pie de video opcional */\n caption?: string;\n}\n\nexport interface SendLocationOptions extends SendBaseOptions {\n /** Coordenada de latitud decimal (ej: 40.416775) */\n latitude: number | string;\n /** Coordenada de longitud decimal (ej: -3.703790) */\n longitude: number | string;\n /** Nombre del lugar o establecimiento (ej: 'Sede Central Madrid') */\n name?: string;\n /** Dirección postal completa */\n address?: string;\n}\n\nexport interface SendContactCardOptions extends SendBaseOptions {\n /** Nombre completo del contacto a compartir */\n name: string;\n /** Número de teléfono del contacto compartido */\n phone: string;\n}\n\nexport interface SendTemplateOptions extends SendBaseOptions {\n /** Nombre exacto de la plantilla aprobada en Meta */\n templateName: string;\n /** Código de idioma (por defecto: 'es') */\n languageCode?: string;\n /** Componentes y variables dinámicas de la plantilla */\n components?: Array<{\n type: 'header' | 'body' | 'button';\n sub_type?: string;\n index?: string | number;\n parameters?: Array<{\n type: 'text' | 'image' | 'document' | 'video' | 'currency' | 'date_time';\n text?: string;\n [key: string]: any;\n }>;\n }>;\n}\n\nexport interface SendMessageResult {\n message_id: string;\n recipient: string;\n connection_id?: string;\n phone_number_id?: string;\n business_phone_number?: string | null;\n type: string;\n status: string;\n conversation_id: string | null;\n}\n\nexport interface WhatsAppConnection {\n id: string;\n display_name: string;\n phone_number: string | null;\n phone_number_id: string;\n waba_id?: string | null;\n verified_name: string | null;\n quality_rating?: string | null;\n status: string;\n webhook_subscribed: boolean;\n created_at?: string;\n}\n\nexport interface WhatsAppTemplate {\n id: string;\n template_name?: string;\n display_name?: string;\n name?: string;\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION' | string;\n language: string;\n status: 'APPROVED' | 'PENDING' | 'REJECTED' | 'PAUSED' | string;\n quality_rating?: string | null;\n components: any[];\n meta_template_id?: string | null;\n rejection_reason?: string | null;\n waba_id?: string | null;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ListTemplatesOptions {\n /** Filtrar por estado en Meta (ej: 'APPROVED', 'PENDING', 'REJECTED') */\n status?: 'APPROVED' | 'PENDING' | 'REJECTED' | 'PAUSED' | string;\n /** Filtrar por categoría oficial */\n category?: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION' | string;\n}\n\nexport interface CreateTemplateOptions {\n /** Nombre técnico en Meta (solo minúsculas, números y guiones bajos, ej: 'confirmacion_pedido_v1') */\n name?: string;\n template_name?: string;\n /** Nombre descriptivo para el panel */\n displayName?: string;\n display_name?: string;\n /** Categoría oficial de Meta */\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION';\n /** Código de idioma (por defecto: 'es') */\n language?: string;\n /** Componentes según especificación de Meta Graph API (HEADER, BODY, BUTTONS, etc.) */\n components?: any[];\n /** Texto plano del cuerpo si no se envían componentes avanzados */\n bodyText?: string;\n /** ID de conexión de WhatsApp (opcional si la cuenta tiene una sola activa) */\n connectionId?: string;\n connection_id?: string;\n /** TTL de entrega en segundos (opcional) */\n messageSendTtlSeconds?: number;\n}\n\n// ── ORGANIZATION & SETTINGS TYPES ───────────────────────────────────────────\n\nexport interface OrganizationDetails {\n id: string;\n name: string;\n timezone: string;\n tier: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UpdateOrganizationOptions {\n /** Nombre de la empresa o aplicación (cambio de nombre / settings de la app) */\n name?: string;\n /** Zona horaria IANA (ej: 'Europe/Madrid', 'America/Bogota', 'America/Mexico_City') */\n timezone?: string;\n}\n\n// ── AI AGENTS & RAG TYPES ───────────────────────────────────────────────────\n\nexport interface AgentDetails {\n id: string;\n name: string;\n system_prompt: string;\n model: string;\n mode: 'agent' | 'rag' | 'both';\n temperature: number;\n is_active: boolean;\n grouping_timeout_seconds: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CreateAgentOptions {\n /** Nombre del agente de IA (ej: 'Asistente Ventas') */\n name: string;\n /** Prompt de sistema e instrucciones de comportamiento */\n systemPrompt: string;\n /** Modelo de IA a utilizar (por defecto: 'gemini-2.5-flash') */\n model?: string;\n /** Modo de operación: 'agent', 'rag' o 'both' */\n mode?: 'agent' | 'rag' | 'both';\n /** Creatividad (temperatura 0.0 - 1.0) */\n temperature?: number;\n /** Si el agente está activo respondiendo chats */\n isActive?: boolean;\n /** Ventana de agrupación de mensajes en segundos */\n groupingTimeoutSeconds?: number;\n}\n\nexport interface UpdateAgentOptions {\n /** Nuevo nombre del agente (cambio de nombre del bot) */\n name?: string;\n /** Nuevo prompt de sistema */\n systemPrompt?: string;\n /** Modelo de IA */\n model?: string;\n /** Modo de operación */\n mode?: 'agent' | 'rag' | 'both';\n /** Creatividad */\n temperature?: number;\n /** Estado activo o inactivo */\n isActive?: boolean;\n /** Ventana de agrupación en segundos */\n groupingTimeoutSeconds?: number;\n}\n\nexport interface AgentSchedule {\n id: string;\n agent_id: string;\n name: string;\n days: number[]; // 1=Lunes, 7=Domingo\n active_from: string; // \"HH:MM\"\n active_until: string; // \"HH:MM\"\n is_active: boolean;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface SetScheduleOptions {\n /** Días activos: 1=Lunes, 2=Martes, 3=Miércoles, 4=Jueves, 5=Viernes, 6=Sábado, 7=Domingo */\n days: number[];\n /** Hora de apertura en formato HH:MM (ej: '09:00') */\n activeFrom: string;\n /** Hora de cierre en formato HH:MM (ej: '19:00') */\n activeUntil: string;\n /** Nombre de la franja horaria */\n name?: string;\n /** Si el horario está habilitado */\n isActive?: boolean;\n}\n\nexport interface KnowledgeDocument {\n id: string;\n title: string;\n description?: string | null;\n file_type: string;\n total_chunks?: number;\n created_at: string;\n updated_at?: string;\n}\n\nexport interface AddKnowledgeOptions {\n /** Título o tema del documento (ej: 'Políticas de garantía y devoluciones') */\n title: string;\n /** Contenido en texto plano a vectorizar para RAG */\n content: string;\n /** Descripción contextual */\n description?: string;\n}\n\n// ── ONBOARDING TYPES ─────────────────────────────────────────────────────────\n\nexport interface OnboardingFeatureBullet {\n title: string;\n description?: string;\n}\n\nexport interface CreateOnboardingSessionOptions {\n /** Nombre del cliente, empresa o sede (ej: 'Clínica Dental') */\n clientName?: string;\n /** Nombre corporativo visible */\n companyName?: string;\n /** URL de retorno tras conectar exitosamente con WhatsApp */\n redirectUrl?: string;\n /** URL pública del logotipo corporativo para marca blanca (PNG, SVG, JPG) */\n logoUrl?: string;\n\n // ── Personalización de Estilos y Colores (Marca Blanca) ──\n /** Color de acento principal (ej: '#0ea5e9') */\n brandColor?: string;\n /** Color de fondo general de la pantalla (ej: '#0f172a' o '#ffffff') */\n backgroundColor?: string;\n /** Color de fondo de la tarjeta/modal (ej: '#1e293b' o '#ffffff') */\n cardBackgroundColor?: string;\n /** Color del borde de la tarjeta (ej: 'rgba(255,255,255,0.1)') */\n cardBorderColor?: string;\n /** Color de los títulos y textos principales (ej: '#ffffff' o '#0f172a') */\n textColor?: string;\n /** Color de los textos secundarios y descripciones (ej: '#94a3b8') */\n textSecondaryColor?: string;\n /** Color de fondo del botón de acción (por defecto usa brandColor o verde WhatsApp) */\n buttonColor?: string;\n /** Color del texto dentro del botón de acción */\n buttonTextColor?: string;\n /** Color de fondo de la píldora superior */\n badgeColor?: string;\n /** Color del texto de la píldora superior */\n badgeTextColor?: string;\n\n // ── Personalización de Copys y Textos ──\n /** Título principal (por defecto: 'Conecta WhatsApp Business') */\n title?: string;\n /** Texto explicativo debajo del título */\n description?: string;\n /** Texto del botón principal (por defecto: 'Conectar con WhatsApp') */\n buttonText?: string;\n /** Texto de la píldora superior (por defecto: 'Vinculación Oficial', o '' para ocultar) */\n badgeText?: string;\n /** Texto legal o footer de la tarjeta */\n footerText?: string;\n /** Viñetas de beneficios o false para ocultar la caja */\n features?: OnboardingFeatureBullet[] | boolean;\n /** Título de la pantalla de éxito tras vincular */\n successTitle?: string;\n /** Descripción de la pantalla de éxito */\n successDescription?: string;\n /** Texto del botón en la pantalla de éxito */\n successButtonText?: string;\n /** Si es true, oculta el badge 'Meta Tech Provider Verified' del encabezado */\n hideMetaBadge?: boolean;\n /** Si es true, oculta el pie de página de copyright */\n hideFooter?: boolean;\n\n /** Horas de validez de la sesión antes de expirar (por defecto: 168 = 7 días) */\n expiresInHours?: number;\n /** Metadata personalizada para tracking en tu CRM */\n metadata?: Record<string, any>;\n}\n\nexport interface OnboardingSession {\n id: string;\n session_id: string;\n session_url: string;\n status: 'started' | 'completed' | 'expired' | 'failed';\n expires_at: string;\n created_at: string;\n}\n\n// ── WEBHOOK TYPES ────────────────────────────────────────────────────────────\n\nexport type NovapsisWebhookEvent =\n | 'whatsapp.message_received'\n | 'whatsapp.message_sent'\n | 'whatsapp.connected'\n | 'conversation.started'\n | 'lead.completed'\n | 'call.completed'\n | 'review.received'\n | '*';\n\nexport interface WhatsAppMessageReceivedData {\n conversation_id: string;\n message_id: string;\n external_message_id?: string | null;\n platform: 'whatsapp' | string;\n\n // ── Datos completos de la línea receptora (Empresa) ──\n connection_id: string;\n phone_number_id: string;\n waba_id?: string | null;\n business_phone_number: string | null;\n business_name?: string | null;\n connection_name?: string | null;\n to: string | null;\n\n // ── Datos del cliente emisor ──\n from: string;\n external_user_id: string;\n external_user_name: string;\n\n // ── Contenido y Multimedia ──\n content: string;\n media_type: 'image' | 'audio' | 'video' | 'document' | null;\n media_url: string | null;\n timestamp: string;\n}\n\nexport interface WhatsAppMessageSentData {\n conversation_id: string;\n message_id: string;\n platform: 'whatsapp' | string;\n\n // ── Datos completos de la línea emisora (Empresa) ──\n connection_id: string;\n phone_number_id: string;\n waba_id?: string | null;\n business_phone_number: string | null;\n business_name?: string | null;\n connection_name?: string | null;\n from: string | null;\n\n // ── Datos del destinatario (Cliente) ──\n to: string;\n external_user_id: string;\n\n role: 'assistant';\n sender_type: 'ai' | 'human';\n content: string;\n media_type?: string | null;\n media_url?: string | null;\n timestamp: string;\n}\n\nexport interface CreateWebhookSubscriptionOptions {\n /** Nombre descriptivo de la suscripción (ej: 'CRM Sincronizador') */\n name: string;\n /** URL HTTPS de tu backend que recibirá los eventos POST */\n url: string;\n /** Lista de eventos a escuchar */\n events: NovapsisWebhookEvent[];\n /** Secreto opcional para firma HMAC. Si se omite, Novapsis generará uno automáticamente. */\n secret?: string;\n}\n\nexport interface WebhookSubscription {\n id: string;\n name: string;\n url: string;\n events: string[];\n secret: string;\n is_active: boolean;\n created_at: string;\n}\n\nexport interface InboundWebhookPayload<T = any> {\n event: NovapsisWebhookEvent;\n timestamp: string;\n organization_id: string;\n data: T;\n}\n\n// ── CRM & CONTACTS TYPES ─────────────────────────────────────────────────────\n\nexport interface UpsertContactOptions {\n phone: string;\n name?: string;\n email?: string;\n tags?: string[];\n metadata?: Record<string, any>;\n}\n\nexport interface Contact {\n id: string;\n phone: string;\n name: string | null;\n email: string | null;\n tags: string[];\n created_at: string;\n}\n\n// ── INTERNAL HTTP CLIENT ────────────────────────────────────────────────────\n\nclass HttpClient {\n private apiKey: string;\n private baseUrl: string;\n private timeoutMs: number;\n private maxRetries: number;\n\n constructor(options: NovapsisClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl || 'https://app.novapsis.com').replace(/\\/+$/, '');\n this.timeoutMs = options.timeoutMs || 15000;\n this.maxRetries = options.maxRetries ?? 2;\n }\n\n async request<T>(method: string, path: string, body?: any, query?: Record<string, string>): Promise<T> {\n let url = `${this.baseUrl}/api/v1${path.startsWith('/') ? path : `/${path}`}`;\n if (query && Object.keys(query).length > 0) {\n const qs = new URLSearchParams(query).toString();\n url += `?${qs}`;\n }\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'Novapsis-SDK-Node/1.1.1',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const data: APIResponse<T> = await response.json().catch(() => ({\n success: false,\n error: { code: 'INVALID_JSON_RESPONSE', message: `HTTP ${response.status} Sin cuerpo JSON válido.` },\n }));\n\n if (!response.ok || !data.success) {\n throw new NovapsisAPIError(\n data.error?.message || `Error en petición HTTP ${response.status}`,\n data.error?.code || `HTTP_${response.status}`,\n response.status,\n data.error?.details\n );\n }\n\n return data.data as T;\n } catch (err: any) {\n clearTimeout(timeoutId);\n lastError = err;\n\n // No reintentar errores de validación de cliente 4xx\n if (err instanceof NovapsisAPIError && err.status >= 400 && err.status < 500) {\n throw err;\n }\n\n // Si es el último intento, lanzar el error\n if (attempt === this.maxRetries) {\n break;\n }\n\n // Backoff exponencial: 300ms, 900ms...\n await new Promise((resolve) => setTimeout(resolve, 300 * Math.pow(3, attempt)));\n }\n }\n\n throw lastError || new NovapsisAPIError('Error de red al comunicarse con Novapsis API', 'NETWORK_ERROR', 0);\n }\n}\n\n// ── SDK SERVICES ────────────────────────────────────────────────────────────\n\n/** Servicio para envíos y gestión de WhatsApp Cloud API */\nexport class WhatsAppService {\n constructor(private http: HttpClient) {}\n\n /** Envía un mensaje de texto plano */\n async sendText(options: SendTextOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'text',\n text: options.text,\n });\n }\n\n /** Envía una imagen o fotografía */\n async sendImage(options: SendImageOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'image',\n media_url: options.imageUrl,\n caption: options.caption,\n });\n }\n\n /** Envía un archivo de audio o nota de voz */\n async sendAudio(options: SendAudioOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'audio',\n media_url: options.audioUrl,\n });\n }\n\n /** Envía un documento (PDF, Word, Excel, etc.) con nombre de archivo personalizado */\n async sendDocument(options: SendDocumentOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'document',\n media_url: options.documentUrl,\n filename: options.filename,\n caption: options.caption,\n });\n }\n\n /** Envía un video */\n async sendVideo(options: SendVideoOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'video',\n media_url: options.videoUrl,\n caption: options.caption,\n });\n }\n\n /** Envía una ubicación con coordenadas y dirección en el mapa */\n async sendLocation(options: SendLocationOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'location',\n latitude: options.latitude,\n longitude: options.longitude,\n location_name: options.name,\n location_address: options.address,\n });\n }\n\n /** Envía una tarjeta de contacto (vCard) interactiva */\n async sendContact(options: SendContactCardOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'contacts',\n contact_name: options.name,\n contact_phone: options.phone,\n });\n }\n\n /** Envía una plantilla oficial aprobada por Meta con variables dinámicas */\n async sendTemplate(options: SendTemplateOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'template',\n template_name: options.templateName,\n language_code: options.languageCode || 'es',\n components: options.components || [],\n });\n }\n\n /** Marca un mensaje o chat como leído */\n async markAsRead(options: { to: string; connectionId?: string; messageId?: string }): Promise<any> {\n return this.http.request('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'mark_read',\n message_id: options.messageId,\n });\n }\n\n /** Obtiene la lista de líneas y números de WhatsApp conectados en la organización */\n async listConnections(): Promise<WhatsAppConnection[]> {\n const res = await this.http.request<{ connections: WhatsAppConnection[] }>('GET', '/whatsapp/connections');\n return res.connections;\n }\n\n /** Lista las plantillas oficiales de Meta con filtros opcionales de estado y categoría */\n async listTemplates(options: ListTemplatesOptions = {}): Promise<WhatsAppTemplate[]> {\n const query: Record<string, string> = {};\n if (options.status) query.status = options.status;\n if (options.category) query.category = options.category;\n const res = await this.http.request<{ templates: WhatsAppTemplate[] }>('GET', '/whatsapp/templates', undefined, query);\n return res.templates;\n }\n\n /** Obtiene las plantillas oficiales de Meta aprobadas (alias directo de listTemplates) */\n async getTemplates(): Promise<WhatsAppTemplate[]> {\n return this.listTemplates();\n }\n\n /** Crea una nueva plantilla oficial de WhatsApp para someter a revisión y aprobación en Meta */\n async createTemplate(options: CreateTemplateOptions): Promise<{ template: WhatsAppTemplate }> {\n const templateName = options.template_name || options.name;\n if (!templateName) {\n throw new NovapsisAPIError('Se requiere `name` o `template_name` para crear una plantilla.', 'VALIDATION_ERROR', 400);\n }\n const components = options.components || (options.bodyText ? [{ type: 'BODY', text: options.bodyText }] : []);\n\n return this.http.request<{ template: WhatsAppTemplate }>('POST', '/whatsapp/templates', {\n template_name: templateName,\n display_name: options.displayName || options.display_name,\n category: options.category,\n language: options.language || 'es',\n components,\n connection_id: options.connectionId || options.connection_id,\n message_send_ttl_seconds: options.messageSendTtlSeconds,\n });\n }\n\n /** Lista las campañas masivas de WhatsApp configuradas */\n async listCampaigns(): Promise<any[]> {\n const res = await this.http.request<{ campaigns: any[] }>('GET', '/whatsapp/campaigns');\n return res.campaigns;\n }\n\n /** Ejecuta una campaña masiva */\n async executeCampaign(campaignId: string): Promise<any> {\n return this.http.request('POST', `/whatsapp/campaigns/${campaignId}/execute`);\n }\n}\n\n/** Servicio para onboarding y conexión de WhatsApp de clientes B2B (Marca Blanca) */\nexport class OnboardingService {\n constructor(private http: HttpClient) {}\n\n /**\n * Crea una sesión de conexión hosted para que un cliente o sede vincule su WhatsApp.\n * Devuelve `session_url` que puedes abrir en un modal o popup en tu CRM.\n */\n async createSession(options: CreateOnboardingSessionOptions = {}): Promise<OnboardingSession> {\n return this.http.request<OnboardingSession>('POST', '/onboarding/sessions', {\n client_name: options.clientName,\n company_name: options.companyName,\n redirect_url: options.redirectUrl,\n logo_url: options.logoUrl,\n brand_color: options.brandColor,\n background_color: options.backgroundColor,\n card_background_color: options.cardBackgroundColor,\n card_border_color: options.cardBorderColor,\n text_color: options.textColor,\n text_secondary_color: options.textSecondaryColor,\n button_color: options.buttonColor,\n button_text_color: options.buttonTextColor,\n badge_color: options.badgeColor,\n badge_text_color: options.badgeTextColor,\n title: options.title,\n description: options.description,\n button_text: options.buttonText,\n badge_text: options.badgeText,\n footer_text: options.footerText,\n features: options.features,\n success_title: options.successTitle,\n success_description: options.successDescription,\n success_button_text: options.successButtonText,\n hide_meta_badge: options.hideMetaBadge,\n hide_footer: options.hideFooter,\n expires_in_hours: options.expiresInHours,\n metadata: options.metadata,\n });\n }\n\n /** Consulta el estado de una sesión de onboarding por su ID */\n async getSessionStatus(sessionId: string): Promise<OnboardingSession> {\n return this.http.request<OnboardingSession>('GET', `/onboarding/sessions/${sessionId}`);\n }\n}\n\n/** Servicio para gestionar Webhooks salientes en tiempo real */\nexport class WebhookService {\n constructor(private http: HttpClient) {}\n\n /** Suscribe una URL de tu backend para recibir eventos en tiempo real */\n async subscribe(options: CreateWebhookSubscriptionOptions): Promise<WebhookSubscription> {\n return this.http.request<WebhookSubscription>('POST', '/webhooks/subscriptions', {\n name: options.name,\n url: options.url,\n events: options.events,\n secret: options.secret,\n is_active: true,\n });\n }\n\n /** Lista todas las suscripciones de webhooks activas */\n async list(): Promise<WebhookSubscription[]> {\n const res = await this.http.request<{ subscriptions: WebhookSubscription[] }>('GET', '/webhooks/subscriptions');\n return res.subscriptions;\n }\n\n /** Elimina una suscripción de webhook */\n async delete(webhookId: string): Promise<boolean> {\n const res = await this.http.request<{ success: boolean }>('DELETE', `/webhooks/subscriptions/${webhookId}`);\n return res.success;\n }\n\n /**\n * Valida la firma criptográfica HMAC SHA-256 de un webhook recibido de Novapsis SM.\n * Evita ataques de suplantación garantizando que la petición proviene de Novapsis.\n *\n * @param rawBody - El cuerpo crudo recibido en el request (string sin parsear)\n * @param signatureHeader - El header 'X-Novapsis-Signature'\n * @param secret - Tu secreto de webhook de Novapsis\n */\n verifySignature(rawBody: string, signatureHeader: string | null | undefined, secret: string): boolean {\n if (!signatureHeader || !secret || !rawBody) return false;\n try {\n const cleanSig = signatureHeader.startsWith('sha256=')\n ? signatureHeader.slice(7)\n : signatureHeader;\n const computed = crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex');\n const bufA = Buffer.from(computed, 'hex');\n const bufB = Buffer.from(cleanSig, 'hex');\n if (bufA.length !== bufB.length) return false;\n return crypto.timingSafeEqual(bufA, bufB);\n } catch {\n return false;\n }\n }\n}\n\n/** Servicio para gestionar Contactos del CRM */\nexport class ContactsService {\n constructor(private http: HttpClient) {}\n\n /** Lista contactos del CRM */\n async list(): Promise<Contact[]> {\n const res = await this.http.request<{ contacts: Contact[] }>('GET', '/contacts');\n return res.contacts;\n }\n\n /** Crea o actualiza un contacto por número de teléfono */\n async upsert(options: UpsertContactOptions): Promise<Contact> {\n return this.http.request<Contact>('POST', '/contacts', options);\n }\n}\n\n/** Servicio para gestión de la organización y configuración general (Marca / Settings) */\nexport class OrganizationService {\n constructor(private http: HttpClient) {}\n\n /** Obtiene la información y configuración de la organización actual */\n async get(): Promise<OrganizationDetails> {\n const res = await this.http.request<{ organization: OrganizationDetails }>('GET', '/organization');\n return res.organization;\n }\n\n /**\n * Actualiza la configuración de la organización (cambio de nombre de la app/empresa, zona horaria)\n */\n async update(options: UpdateOrganizationOptions): Promise<OrganizationDetails> {\n const res = await this.http.request<{ organization: OrganizationDetails }>('PATCH', '/organization', {\n name: options.name,\n timezone: options.timezone,\n });\n return res.organization;\n }\n}\n\n/** Servicio para interactuar y configurar Agentes de Inteligencia Artificial (Headless AI) */\nexport class AIService {\n constructor(private http: HttpClient) {}\n\n /** Lista los agentes de IA configurados en la organización */\n async listAgents(): Promise<AgentDetails[]> {\n const res = await this.http.request<{ agents: AgentDetails[] }>('GET', '/ai/agents');\n return res.agents;\n }\n\n /** Obtiene la configuración completa de un agente por su ID */\n async getAgent(agentId: string): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('GET', `/ai/agents/${agentId}`);\n return res.agent;\n }\n\n /** Crea un nuevo agente de IA para la organización */\n async createAgent(options: CreateAgentOptions): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('POST', '/ai/agents', {\n name: options.name,\n system_prompt: options.systemPrompt,\n model: options.model,\n mode: options.mode,\n temperature: options.temperature,\n is_active: options.isActive,\n grouping_timeout_seconds: options.groupingTimeoutSeconds,\n });\n return res.agent;\n }\n\n /** Actualiza nombre, prompt de sistema, modelo o configuración de un agente */\n async updateAgent(agentId: string, options: UpdateAgentOptions): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('PATCH', `/ai/agents/${agentId}`, {\n name: options.name,\n system_prompt: options.systemPrompt,\n model: options.model,\n mode: options.mode,\n temperature: options.temperature,\n is_active: options.isActive,\n grouping_timeout_seconds: options.groupingTimeoutSeconds,\n });\n return res.agent;\n }\n\n /** Consulta el horario de atención configurado para el agente y la zona horaria */\n async getSchedule(agentId: string): Promise<{ schedule: AgentSchedule | null; timezone: string }> {\n return this.http.request<{ schedule: AgentSchedule | null; timezone: string }>('GET', `/ai/agents/${agentId}/schedule`);\n }\n\n /** Configura o reemplaza el horario de atención activa del agente */\n async setSchedule(agentId: string, options: SetScheduleOptions): Promise<{ schedule: AgentSchedule; timezone: string }> {\n return this.http.request<{ schedule: AgentSchedule; timezone: string }>('PUT', `/ai/agents/${agentId}/schedule`, {\n days: options.days,\n active_from: options.activeFrom,\n active_until: options.activeUntil,\n name: options.name,\n is_active: options.isActive,\n });\n }\n\n /** Lista los documentos de la base de conocimiento RAG asociados al agente */\n async listKnowledge(agentId: string): Promise<KnowledgeDocument[]> {\n const res = await this.http.request<{ documents: KnowledgeDocument[] }>('GET', `/ai/agents/${agentId}/knowledge`);\n return res.documents;\n }\n\n /** Ingesta y vectoriza nuevo conocimiento en texto plano directamente al agente */\n async addKnowledge(agentId: string, options: AddKnowledgeOptions): Promise<KnowledgeDocument> {\n const res = await this.http.request<{ document: KnowledgeDocument }>('POST', `/ai/agents/${agentId}/knowledge`, {\n title: options.title,\n content: options.content,\n description: options.description,\n });\n return res.document;\n }\n\n /** Ejecuta una consulta conversacional contra el agente y su base de conocimiento RAG */\n async execute(options: { agentId: string; message: string }): Promise<{ response: string; tokens_used?: number }> {\n return this.http.request('POST', `/ai/agents/${options.agentId}/execute`, {\n message: options.message,\n });\n }\n}\n\n// ── MAIN CLIENT ─────────────────────────────────────────────────────────────\n\n/**\n * Cliente oficial de Novapsis SM.\n * Punto de entrada principal para interactuar con todos los servicios.\n *\n * @example\n * ```typescript\n * import { Novapsis } from 'novapsis';\n *\n * const client = new Novapsis({\n * apiKey: 'nvs_live_sample_abcdef1234567890',\n * });\n *\n * // Enviar mensaje de texto\n * await client.whatsapp.sendText({\n * to: '34600112233',\n * text: '¡Hola desde Novapsis SDK!'\n * });\n * ```\n */\nexport class Novapsis {\n private http: HttpClient;\n\n /** Métodos para ajustes de la organización y cambio de nombre de la app */\n public readonly organization: OrganizationService;\n /** Métodos para envíos y operaciones de WhatsApp */\n public readonly whatsapp: WhatsAppService;\n /** Métodos para onboarding hosted y vinculación B2B */\n public readonly onboarding: OnboardingService;\n /** Métodos para suscripción y validación de Webhooks */\n public readonly webhooks: WebhookService;\n /** Métodos para contactos del CRM */\n public readonly contacts: ContactsService;\n /** Métodos para Agentes de Inteligencia Artificial (prompts, RAG, horarios) */\n public readonly ai: AIService;\n\n constructor(options: NovapsisClientOptions) {\n if (!options.apiKey) {\n throw new NovapsisAPIError('Se requiere una apiKey válida para inicializar el cliente de Novapsis.', 'CONFIG_ERROR', 400);\n }\n this.http = new HttpClient(options);\n this.organization = new OrganizationService(this.http);\n this.whatsapp = new WhatsAppService(this.http);\n this.onboarding = new OnboardingService(this.http);\n this.webhooks = new WebhookService(this.http);\n this.contacts = new ContactsService(this.http);\n this.ai = new AIService(this.http);\n }\n}\n\n// Default export\nexport default Novapsis;\n"]}
package/dist/index.d.mts CHANGED
@@ -5,7 +5,7 @@
5
5
  * Universal typed client for WhatsApp Business Cloud API, Hosted Onboarding,
6
6
  * CRM, AI Agents and HMAC Webhook Verification.
7
7
  *
8
- * @version 1.1.0
8
+ * @version 1.1.1
9
9
  * @author Novapsis Technologies
10
10
  * @license MIT
11
11
  * ══════════════════════════════════════════════════════════════════════════════
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * Universal typed client for WhatsApp Business Cloud API, Hosted Onboarding,
6
6
  * CRM, AI Agents and HMAC Webhook Verification.
7
7
  *
8
- * @version 1.1.0
8
+ * @version 1.1.1
9
9
  * @author Novapsis Technologies
10
10
  * @license MIT
11
11
  * ══════════════════════════════════════════════════════════════════════════════
package/dist/index.mjs CHANGED
@@ -40,7 +40,7 @@ var HttpClient = class {
40
40
  headers: {
41
41
  "Authorization": `Bearer ${this.apiKey}`,
42
42
  "Content-Type": "application/json",
43
- "User-Agent": "Novapsis-SDK-Node/1.1.0"
43
+ "User-Agent": "Novapsis-SDK-Node/1.1.1"
44
44
  },
45
45
  body: body ? JSON.stringify(body) : void 0,
46
46
  signal: controller.signal
@@ -453,7 +453,7 @@ var index_default = Novapsis;
453
453
  * Universal typed client for WhatsApp Business Cloud API, Hosted Onboarding,
454
454
  * CRM, AI Agents and HMAC Webhook Verification.
455
455
  *
456
- * @version 1.1.0
456
+ * @version 1.1.1
457
457
  * @author Novapsis Technologies
458
458
  * @license MIT
459
459
  * ══════════════════════════════════════════════════════════════════════════════
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * novapsis - Official TypeScript / JavaScript SDK\n * ══════════════════════════════════════════════════════════════════════════════\n * Official SDK for Novapsis SM.\n * Universal typed client for WhatsApp Business Cloud API, Hosted Onboarding,\n * CRM, AI Agents and HMAC Webhook Verification.\n *\n * @version 1.1.0\n * @author Novapsis Technologies\n * @license MIT\n * ══════════════════════════════════════════════════════════════════════════════\n */\n\nimport crypto from 'crypto';\n\n// ── TYPES & DEFINITIONS ──────────────────────────────────────────────────────\n\nexport interface NovapsisClientOptions {\n /** Clave de API de Novapsis (empieza por nvs_live_ o nvs_test_) */\n apiKey: string;\n /** URL base de la API (por defecto: https://app.novapsis.com) */\n baseUrl?: string;\n /** Timeout en milisegundos para peticiones HTTP (por defecto: 15000) */\n timeoutMs?: number;\n /** Número máximo de reintentos automáticos ante fallos de red transitorios (por defecto: 2) */\n maxRetries?: number;\n}\n\nexport interface APIResponse<T = any> {\n success: boolean;\n data?: T;\n error?: {\n code: string;\n message: string;\n details?: any;\n };\n}\n\nexport class NovapsisAPIError extends Error {\n public readonly code: string;\n public readonly status: number;\n public readonly details?: any;\n\n constructor(message: string, code = 'API_ERROR', status = 500, details?: any) {\n super(message);\n this.name = 'NovapsisAPIError';\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\n// ── WHATSAPP TYPES ───────────────────────────────────────────────────────────\n\nexport interface SendBaseOptions {\n /** Número destinatario con código de país, sin '+' ni espacios (ej: '34600112233') */\n to: string;\n /** UUID de la conexión o Phone Number ID de Meta desde el cual enviar. Si se omite, usa la línea principal. */\n connectionId?: string;\n}\n\nexport interface SendTextOptions extends SendBaseOptions {\n /** Cuerpo del mensaje de texto */\n text: string;\n /** Si es true, genera vista previa de los enlaces web incluidos en el texto */\n previewUrl?: boolean;\n}\n\nexport interface SendImageOptions extends SendBaseOptions {\n /** URL HTTPS pública de la imagen (JPG, PNG, WebP) */\n imageUrl: string;\n /** Pie de foto opcional */\n caption?: string;\n}\n\nexport interface SendAudioOptions extends SendBaseOptions {\n /** URL HTTPS pública del archivo de audio (MP3, AAC, OGG, M4A) */\n audioUrl: string;\n}\n\nexport interface SendDocumentOptions extends SendBaseOptions {\n /** URL HTTPS pública del documento o PDF */\n documentUrl: string;\n /** Nombre visible del archivo (ej: 'factura_2026.pdf') */\n filename?: string;\n /** Descripción o pie opcional */\n caption?: string;\n}\n\nexport interface SendVideoOptions extends SendBaseOptions {\n /** URL HTTPS pública del video (MP4, 3GP) */\n videoUrl: string;\n /** Pie de video opcional */\n caption?: string;\n}\n\nexport interface SendLocationOptions extends SendBaseOptions {\n /** Coordenada de latitud decimal (ej: 40.416775) */\n latitude: number | string;\n /** Coordenada de longitud decimal (ej: -3.703790) */\n longitude: number | string;\n /** Nombre del lugar o establecimiento (ej: 'Sede Central Madrid') */\n name?: string;\n /** Dirección postal completa */\n address?: string;\n}\n\nexport interface SendContactCardOptions extends SendBaseOptions {\n /** Nombre completo del contacto a compartir */\n name: string;\n /** Número de teléfono del contacto compartido */\n phone: string;\n}\n\nexport interface SendTemplateOptions extends SendBaseOptions {\n /** Nombre exacto de la plantilla aprobada en Meta */\n templateName: string;\n /** Código de idioma (por defecto: 'es') */\n languageCode?: string;\n /** Componentes y variables dinámicas de la plantilla */\n components?: Array<{\n type: 'header' | 'body' | 'button';\n sub_type?: string;\n index?: string | number;\n parameters?: Array<{\n type: 'text' | 'image' | 'document' | 'video' | 'currency' | 'date_time';\n text?: string;\n [key: string]: any;\n }>;\n }>;\n}\n\nexport interface SendMessageResult {\n message_id: string;\n recipient: string;\n connection_id?: string;\n phone_number_id?: string;\n business_phone_number?: string | null;\n type: string;\n status: string;\n conversation_id: string | null;\n}\n\nexport interface WhatsAppConnection {\n id: string;\n display_name: string;\n phone_number: string | null;\n phone_number_id: string;\n waba_id?: string | null;\n verified_name: string | null;\n quality_rating?: string | null;\n status: string;\n webhook_subscribed: boolean;\n created_at?: string;\n}\n\nexport interface WhatsAppTemplate {\n id: string;\n template_name?: string;\n display_name?: string;\n name?: string;\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION' | string;\n language: string;\n status: 'APPROVED' | 'PENDING' | 'REJECTED' | 'PAUSED' | string;\n quality_rating?: string | null;\n components: any[];\n meta_template_id?: string | null;\n rejection_reason?: string | null;\n waba_id?: string | null;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ListTemplatesOptions {\n /** Filtrar por estado en Meta (ej: 'APPROVED', 'PENDING', 'REJECTED') */\n status?: 'APPROVED' | 'PENDING' | 'REJECTED' | 'PAUSED' | string;\n /** Filtrar por categoría oficial */\n category?: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION' | string;\n}\n\nexport interface CreateTemplateOptions {\n /** Nombre técnico en Meta (solo minúsculas, números y guiones bajos, ej: 'confirmacion_pedido_v1') */\n name?: string;\n template_name?: string;\n /** Nombre descriptivo para el panel */\n displayName?: string;\n display_name?: string;\n /** Categoría oficial de Meta */\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION';\n /** Código de idioma (por defecto: 'es') */\n language?: string;\n /** Componentes según especificación de Meta Graph API (HEADER, BODY, BUTTONS, etc.) */\n components?: any[];\n /** Texto plano del cuerpo si no se envían componentes avanzados */\n bodyText?: string;\n /** ID de conexión de WhatsApp (opcional si la cuenta tiene una sola activa) */\n connectionId?: string;\n connection_id?: string;\n /** TTL de entrega en segundos (opcional) */\n messageSendTtlSeconds?: number;\n}\n\n// ── ORGANIZATION & SETTINGS TYPES ───────────────────────────────────────────\n\nexport interface OrganizationDetails {\n id: string;\n name: string;\n timezone: string;\n tier: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UpdateOrganizationOptions {\n /** Nombre de la empresa o aplicación (cambio de nombre / settings de la app) */\n name?: string;\n /** Zona horaria IANA (ej: 'Europe/Madrid', 'America/Bogota', 'America/Mexico_City') */\n timezone?: string;\n}\n\n// ── AI AGENTS & RAG TYPES ───────────────────────────────────────────────────\n\nexport interface AgentDetails {\n id: string;\n name: string;\n system_prompt: string;\n model: string;\n mode: 'agent' | 'rag' | 'both';\n temperature: number;\n is_active: boolean;\n grouping_timeout_seconds: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CreateAgentOptions {\n /** Nombre del agente de IA (ej: 'Asistente Ventas') */\n name: string;\n /** Prompt de sistema e instrucciones de comportamiento */\n systemPrompt: string;\n /** Modelo de IA a utilizar (por defecto: 'gemini-2.5-flash') */\n model?: string;\n /** Modo de operación: 'agent', 'rag' o 'both' */\n mode?: 'agent' | 'rag' | 'both';\n /** Creatividad (temperatura 0.0 - 1.0) */\n temperature?: number;\n /** Si el agente está activo respondiendo chats */\n isActive?: boolean;\n /** Ventana de agrupación de mensajes en segundos */\n groupingTimeoutSeconds?: number;\n}\n\nexport interface UpdateAgentOptions {\n /** Nuevo nombre del agente (cambio de nombre del bot) */\n name?: string;\n /** Nuevo prompt de sistema */\n systemPrompt?: string;\n /** Modelo de IA */\n model?: string;\n /** Modo de operación */\n mode?: 'agent' | 'rag' | 'both';\n /** Creatividad */\n temperature?: number;\n /** Estado activo o inactivo */\n isActive?: boolean;\n /** Ventana de agrupación en segundos */\n groupingTimeoutSeconds?: number;\n}\n\nexport interface AgentSchedule {\n id: string;\n agent_id: string;\n name: string;\n days: number[]; // 1=Lunes, 7=Domingo\n active_from: string; // \"HH:MM\"\n active_until: string; // \"HH:MM\"\n is_active: boolean;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface SetScheduleOptions {\n /** Días activos: 1=Lunes, 2=Martes, 3=Miércoles, 4=Jueves, 5=Viernes, 6=Sábado, 7=Domingo */\n days: number[];\n /** Hora de apertura en formato HH:MM (ej: '09:00') */\n activeFrom: string;\n /** Hora de cierre en formato HH:MM (ej: '19:00') */\n activeUntil: string;\n /** Nombre de la franja horaria */\n name?: string;\n /** Si el horario está habilitado */\n isActive?: boolean;\n}\n\nexport interface KnowledgeDocument {\n id: string;\n title: string;\n description?: string | null;\n file_type: string;\n total_chunks?: number;\n created_at: string;\n updated_at?: string;\n}\n\nexport interface AddKnowledgeOptions {\n /** Título o tema del documento (ej: 'Políticas de garantía y devoluciones') */\n title: string;\n /** Contenido en texto plano a vectorizar para RAG */\n content: string;\n /** Descripción contextual */\n description?: string;\n}\n\n// ── ONBOARDING TYPES ─────────────────────────────────────────────────────────\n\nexport interface OnboardingFeatureBullet {\n title: string;\n description?: string;\n}\n\nexport interface CreateOnboardingSessionOptions {\n /** Nombre del cliente, empresa o sede (ej: 'Clínica Dental') */\n clientName?: string;\n /** Nombre corporativo visible */\n companyName?: string;\n /** URL de retorno tras conectar exitosamente con WhatsApp */\n redirectUrl?: string;\n /** URL pública del logotipo corporativo para marca blanca (PNG, SVG, JPG) */\n logoUrl?: string;\n\n // ── Personalización de Estilos y Colores (Marca Blanca) ──\n /** Color de acento principal (ej: '#0ea5e9') */\n brandColor?: string;\n /** Color de fondo general de la pantalla (ej: '#0f172a' o '#ffffff') */\n backgroundColor?: string;\n /** Color de fondo de la tarjeta/modal (ej: '#1e293b' o '#ffffff') */\n cardBackgroundColor?: string;\n /** Color del borde de la tarjeta (ej: 'rgba(255,255,255,0.1)') */\n cardBorderColor?: string;\n /** Color de los títulos y textos principales (ej: '#ffffff' o '#0f172a') */\n textColor?: string;\n /** Color de los textos secundarios y descripciones (ej: '#94a3b8') */\n textSecondaryColor?: string;\n /** Color de fondo del botón de acción (por defecto usa brandColor o verde WhatsApp) */\n buttonColor?: string;\n /** Color del texto dentro del botón de acción */\n buttonTextColor?: string;\n /** Color de fondo de la píldora superior */\n badgeColor?: string;\n /** Color del texto de la píldora superior */\n badgeTextColor?: string;\n\n // ── Personalización de Copys y Textos ──\n /** Título principal (por defecto: 'Conecta WhatsApp Business') */\n title?: string;\n /** Texto explicativo debajo del título */\n description?: string;\n /** Texto del botón principal (por defecto: 'Conectar con WhatsApp') */\n buttonText?: string;\n /** Texto de la píldora superior (por defecto: 'Vinculación Oficial', o '' para ocultar) */\n badgeText?: string;\n /** Texto legal o footer de la tarjeta */\n footerText?: string;\n /** Viñetas de beneficios o false para ocultar la caja */\n features?: OnboardingFeatureBullet[] | boolean;\n /** Título de la pantalla de éxito tras vincular */\n successTitle?: string;\n /** Descripción de la pantalla de éxito */\n successDescription?: string;\n /** Texto del botón en la pantalla de éxito */\n successButtonText?: string;\n /** Si es true, oculta el badge 'Meta Tech Provider Verified' del encabezado */\n hideMetaBadge?: boolean;\n /** Si es true, oculta el pie de página de copyright */\n hideFooter?: boolean;\n\n /** Horas de validez de la sesión antes de expirar (por defecto: 168 = 7 días) */\n expiresInHours?: number;\n /** Metadata personalizada para tracking en tu CRM */\n metadata?: Record<string, any>;\n}\n\nexport interface OnboardingSession {\n id: string;\n session_id: string;\n session_url: string;\n status: 'started' | 'completed' | 'expired' | 'failed';\n expires_at: string;\n created_at: string;\n}\n\n// ── WEBHOOK TYPES ────────────────────────────────────────────────────────────\n\nexport type NovapsisWebhookEvent =\n | 'whatsapp.message_received'\n | 'whatsapp.message_sent'\n | 'whatsapp.connected'\n | 'conversation.started'\n | 'lead.completed'\n | 'call.completed'\n | 'review.received'\n | '*';\n\nexport interface WhatsAppMessageReceivedData {\n conversation_id: string;\n message_id: string;\n external_message_id?: string | null;\n platform: 'whatsapp' | string;\n\n // ── Datos completos de la línea receptora (Empresa) ──\n connection_id: string;\n phone_number_id: string;\n waba_id?: string | null;\n business_phone_number: string | null;\n business_name?: string | null;\n connection_name?: string | null;\n to: string | null;\n\n // ── Datos del cliente emisor ──\n from: string;\n external_user_id: string;\n external_user_name: string;\n\n // ── Contenido y Multimedia ──\n content: string;\n media_type: 'image' | 'audio' | 'video' | 'document' | null;\n media_url: string | null;\n timestamp: string;\n}\n\nexport interface WhatsAppMessageSentData {\n conversation_id: string;\n message_id: string;\n platform: 'whatsapp' | string;\n\n // ── Datos completos de la línea emisora (Empresa) ──\n connection_id: string;\n phone_number_id: string;\n waba_id?: string | null;\n business_phone_number: string | null;\n business_name?: string | null;\n connection_name?: string | null;\n from: string | null;\n\n // ── Datos del destinatario (Cliente) ──\n to: string;\n external_user_id: string;\n\n role: 'assistant';\n sender_type: 'ai' | 'human';\n content: string;\n media_type?: string | null;\n media_url?: string | null;\n timestamp: string;\n}\n\nexport interface CreateWebhookSubscriptionOptions {\n /** Nombre descriptivo de la suscripción (ej: 'CRM Sincronizador') */\n name: string;\n /** URL HTTPS de tu backend que recibirá los eventos POST */\n url: string;\n /** Lista de eventos a escuchar */\n events: NovapsisWebhookEvent[];\n /** Secreto opcional para firma HMAC. Si se omite, Novapsis generará uno automáticamente. */\n secret?: string;\n}\n\nexport interface WebhookSubscription {\n id: string;\n name: string;\n url: string;\n events: string[];\n secret: string;\n is_active: boolean;\n created_at: string;\n}\n\nexport interface InboundWebhookPayload<T = any> {\n event: NovapsisWebhookEvent;\n timestamp: string;\n organization_id: string;\n data: T;\n}\n\n// ── CRM & CONTACTS TYPES ─────────────────────────────────────────────────────\n\nexport interface UpsertContactOptions {\n phone: string;\n name?: string;\n email?: string;\n tags?: string[];\n metadata?: Record<string, any>;\n}\n\nexport interface Contact {\n id: string;\n phone: string;\n name: string | null;\n email: string | null;\n tags: string[];\n created_at: string;\n}\n\n// ── INTERNAL HTTP CLIENT ────────────────────────────────────────────────────\n\nclass HttpClient {\n private apiKey: string;\n private baseUrl: string;\n private timeoutMs: number;\n private maxRetries: number;\n\n constructor(options: NovapsisClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl || 'https://app.novapsis.com').replace(/\\/+$/, '');\n this.timeoutMs = options.timeoutMs || 15000;\n this.maxRetries = options.maxRetries ?? 2;\n }\n\n async request<T>(method: string, path: string, body?: any, query?: Record<string, string>): Promise<T> {\n let url = `${this.baseUrl}/api/v1${path.startsWith('/') ? path : `/${path}`}`;\n if (query && Object.keys(query).length > 0) {\n const qs = new URLSearchParams(query).toString();\n url += `?${qs}`;\n }\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'Novapsis-SDK-Node/1.1.0',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const data: APIResponse<T> = await response.json().catch(() => ({\n success: false,\n error: { code: 'INVALID_JSON_RESPONSE', message: `HTTP ${response.status} Sin cuerpo JSON válido.` },\n }));\n\n if (!response.ok || !data.success) {\n throw new NovapsisAPIError(\n data.error?.message || `Error en petición HTTP ${response.status}`,\n data.error?.code || `HTTP_${response.status}`,\n response.status,\n data.error?.details\n );\n }\n\n return data.data as T;\n } catch (err: any) {\n clearTimeout(timeoutId);\n lastError = err;\n\n // No reintentar errores de validación de cliente 4xx\n if (err instanceof NovapsisAPIError && err.status >= 400 && err.status < 500) {\n throw err;\n }\n\n // Si es el último intento, lanzar el error\n if (attempt === this.maxRetries) {\n break;\n }\n\n // Backoff exponencial: 300ms, 900ms...\n await new Promise((resolve) => setTimeout(resolve, 300 * Math.pow(3, attempt)));\n }\n }\n\n throw lastError || new NovapsisAPIError('Error de red al comunicarse con Novapsis API', 'NETWORK_ERROR', 0);\n }\n}\n\n// ── SDK SERVICES ────────────────────────────────────────────────────────────\n\n/** Servicio para envíos y gestión de WhatsApp Cloud API */\nexport class WhatsAppService {\n constructor(private http: HttpClient) {}\n\n /** Envía un mensaje de texto plano */\n async sendText(options: SendTextOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'text',\n text: options.text,\n });\n }\n\n /** Envía una imagen o fotografía */\n async sendImage(options: SendImageOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'image',\n media_url: options.imageUrl,\n caption: options.caption,\n });\n }\n\n /** Envía un archivo de audio o nota de voz */\n async sendAudio(options: SendAudioOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'audio',\n media_url: options.audioUrl,\n });\n }\n\n /** Envía un documento (PDF, Word, Excel, etc.) con nombre de archivo personalizado */\n async sendDocument(options: SendDocumentOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'document',\n media_url: options.documentUrl,\n filename: options.filename,\n caption: options.caption,\n });\n }\n\n /** Envía un video */\n async sendVideo(options: SendVideoOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'video',\n media_url: options.videoUrl,\n caption: options.caption,\n });\n }\n\n /** Envía una ubicación con coordenadas y dirección en el mapa */\n async sendLocation(options: SendLocationOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'location',\n latitude: options.latitude,\n longitude: options.longitude,\n location_name: options.name,\n location_address: options.address,\n });\n }\n\n /** Envía una tarjeta de contacto (vCard) interactiva */\n async sendContact(options: SendContactCardOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'contacts',\n contact_name: options.name,\n contact_phone: options.phone,\n });\n }\n\n /** Envía una plantilla oficial aprobada por Meta con variables dinámicas */\n async sendTemplate(options: SendTemplateOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'template',\n template_name: options.templateName,\n language_code: options.languageCode || 'es',\n components: options.components || [],\n });\n }\n\n /** Marca un mensaje o chat como leído */\n async markAsRead(options: { to: string; connectionId?: string; messageId?: string }): Promise<any> {\n return this.http.request('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'mark_read',\n message_id: options.messageId,\n });\n }\n\n /** Obtiene la lista de líneas y números de WhatsApp conectados en la organización */\n async listConnections(): Promise<WhatsAppConnection[]> {\n const res = await this.http.request<{ connections: WhatsAppConnection[] }>('GET', '/whatsapp/connections');\n return res.connections;\n }\n\n /** Lista las plantillas oficiales de Meta con filtros opcionales de estado y categoría */\n async listTemplates(options: ListTemplatesOptions = {}): Promise<WhatsAppTemplate[]> {\n const query: Record<string, string> = {};\n if (options.status) query.status = options.status;\n if (options.category) query.category = options.category;\n const res = await this.http.request<{ templates: WhatsAppTemplate[] }>('GET', '/whatsapp/templates', undefined, query);\n return res.templates;\n }\n\n /** Obtiene las plantillas oficiales de Meta aprobadas (alias directo de listTemplates) */\n async getTemplates(): Promise<WhatsAppTemplate[]> {\n return this.listTemplates();\n }\n\n /** Crea una nueva plantilla oficial de WhatsApp para someter a revisión y aprobación en Meta */\n async createTemplate(options: CreateTemplateOptions): Promise<{ template: WhatsAppTemplate }> {\n const templateName = options.template_name || options.name;\n if (!templateName) {\n throw new NovapsisAPIError('Se requiere `name` o `template_name` para crear una plantilla.', 'VALIDATION_ERROR', 400);\n }\n const components = options.components || (options.bodyText ? [{ type: 'BODY', text: options.bodyText }] : []);\n\n return this.http.request<{ template: WhatsAppTemplate }>('POST', '/whatsapp/templates', {\n template_name: templateName,\n display_name: options.displayName || options.display_name,\n category: options.category,\n language: options.language || 'es',\n components,\n connection_id: options.connectionId || options.connection_id,\n message_send_ttl_seconds: options.messageSendTtlSeconds,\n });\n }\n\n /** Lista las campañas masivas de WhatsApp configuradas */\n async listCampaigns(): Promise<any[]> {\n const res = await this.http.request<{ campaigns: any[] }>('GET', '/whatsapp/campaigns');\n return res.campaigns;\n }\n\n /** Ejecuta una campaña masiva */\n async executeCampaign(campaignId: string): Promise<any> {\n return this.http.request('POST', `/whatsapp/campaigns/${campaignId}/execute`);\n }\n}\n\n/** Servicio para onboarding y conexión de WhatsApp de clientes B2B (Marca Blanca) */\nexport class OnboardingService {\n constructor(private http: HttpClient) {}\n\n /**\n * Crea una sesión de conexión hosted para que un cliente o sede vincule su WhatsApp.\n * Devuelve `session_url` que puedes abrir en un modal o popup en tu CRM.\n */\n async createSession(options: CreateOnboardingSessionOptions = {}): Promise<OnboardingSession> {\n return this.http.request<OnboardingSession>('POST', '/onboarding/sessions', {\n client_name: options.clientName,\n company_name: options.companyName,\n redirect_url: options.redirectUrl,\n logo_url: options.logoUrl,\n brand_color: options.brandColor,\n background_color: options.backgroundColor,\n card_background_color: options.cardBackgroundColor,\n card_border_color: options.cardBorderColor,\n text_color: options.textColor,\n text_secondary_color: options.textSecondaryColor,\n button_color: options.buttonColor,\n button_text_color: options.buttonTextColor,\n badge_color: options.badgeColor,\n badge_text_color: options.badgeTextColor,\n title: options.title,\n description: options.description,\n button_text: options.buttonText,\n badge_text: options.badgeText,\n footer_text: options.footerText,\n features: options.features,\n success_title: options.successTitle,\n success_description: options.successDescription,\n success_button_text: options.successButtonText,\n hide_meta_badge: options.hideMetaBadge,\n hide_footer: options.hideFooter,\n expires_in_hours: options.expiresInHours,\n metadata: options.metadata,\n });\n }\n\n /** Consulta el estado de una sesión de onboarding por su ID */\n async getSessionStatus(sessionId: string): Promise<OnboardingSession> {\n return this.http.request<OnboardingSession>('GET', `/onboarding/sessions/${sessionId}`);\n }\n}\n\n/** Servicio para gestionar Webhooks salientes en tiempo real */\nexport class WebhookService {\n constructor(private http: HttpClient) {}\n\n /** Suscribe una URL de tu backend para recibir eventos en tiempo real */\n async subscribe(options: CreateWebhookSubscriptionOptions): Promise<WebhookSubscription> {\n return this.http.request<WebhookSubscription>('POST', '/webhooks/subscriptions', {\n name: options.name,\n url: options.url,\n events: options.events,\n secret: options.secret,\n is_active: true,\n });\n }\n\n /** Lista todas las suscripciones de webhooks activas */\n async list(): Promise<WebhookSubscription[]> {\n const res = await this.http.request<{ subscriptions: WebhookSubscription[] }>('GET', '/webhooks/subscriptions');\n return res.subscriptions;\n }\n\n /** Elimina una suscripción de webhook */\n async delete(webhookId: string): Promise<boolean> {\n const res = await this.http.request<{ success: boolean }>('DELETE', `/webhooks/subscriptions/${webhookId}`);\n return res.success;\n }\n\n /**\n * Valida la firma criptográfica HMAC SHA-256 de un webhook recibido de Novapsis SM.\n * Evita ataques de suplantación garantizando que la petición proviene de Novapsis.\n *\n * @param rawBody - El cuerpo crudo recibido en el request (string sin parsear)\n * @param signatureHeader - El header 'X-Novapsis-Signature'\n * @param secret - Tu secreto de webhook de Novapsis\n */\n verifySignature(rawBody: string, signatureHeader: string | null | undefined, secret: string): boolean {\n if (!signatureHeader || !secret || !rawBody) return false;\n try {\n const cleanSig = signatureHeader.startsWith('sha256=')\n ? signatureHeader.slice(7)\n : signatureHeader;\n const computed = crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex');\n const bufA = Buffer.from(computed, 'hex');\n const bufB = Buffer.from(cleanSig, 'hex');\n if (bufA.length !== bufB.length) return false;\n return crypto.timingSafeEqual(bufA, bufB);\n } catch {\n return false;\n }\n }\n}\n\n/** Servicio para gestionar Contactos del CRM */\nexport class ContactsService {\n constructor(private http: HttpClient) {}\n\n /** Lista contactos del CRM */\n async list(): Promise<Contact[]> {\n const res = await this.http.request<{ contacts: Contact[] }>('GET', '/contacts');\n return res.contacts;\n }\n\n /** Crea o actualiza un contacto por número de teléfono */\n async upsert(options: UpsertContactOptions): Promise<Contact> {\n return this.http.request<Contact>('POST', '/contacts', options);\n }\n}\n\n/** Servicio para gestión de la organización y configuración general (Marca / Settings) */\nexport class OrganizationService {\n constructor(private http: HttpClient) {}\n\n /** Obtiene la información y configuración de la organización actual */\n async get(): Promise<OrganizationDetails> {\n const res = await this.http.request<{ organization: OrganizationDetails }>('GET', '/organization');\n return res.organization;\n }\n\n /**\n * Actualiza la configuración de la organización (cambio de nombre de la app/empresa, zona horaria)\n */\n async update(options: UpdateOrganizationOptions): Promise<OrganizationDetails> {\n const res = await this.http.request<{ organization: OrganizationDetails }>('PATCH', '/organization', {\n name: options.name,\n timezone: options.timezone,\n });\n return res.organization;\n }\n}\n\n/** Servicio para interactuar y configurar Agentes de Inteligencia Artificial (Headless AI) */\nexport class AIService {\n constructor(private http: HttpClient) {}\n\n /** Lista los agentes de IA configurados en la organización */\n async listAgents(): Promise<AgentDetails[]> {\n const res = await this.http.request<{ agents: AgentDetails[] }>('GET', '/ai/agents');\n return res.agents;\n }\n\n /** Obtiene la configuración completa de un agente por su ID */\n async getAgent(agentId: string): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('GET', `/ai/agents/${agentId}`);\n return res.agent;\n }\n\n /** Crea un nuevo agente de IA para la organización */\n async createAgent(options: CreateAgentOptions): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('POST', '/ai/agents', {\n name: options.name,\n system_prompt: options.systemPrompt,\n model: options.model,\n mode: options.mode,\n temperature: options.temperature,\n is_active: options.isActive,\n grouping_timeout_seconds: options.groupingTimeoutSeconds,\n });\n return res.agent;\n }\n\n /** Actualiza nombre, prompt de sistema, modelo o configuración de un agente */\n async updateAgent(agentId: string, options: UpdateAgentOptions): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('PATCH', `/ai/agents/${agentId}`, {\n name: options.name,\n system_prompt: options.systemPrompt,\n model: options.model,\n mode: options.mode,\n temperature: options.temperature,\n is_active: options.isActive,\n grouping_timeout_seconds: options.groupingTimeoutSeconds,\n });\n return res.agent;\n }\n\n /** Consulta el horario de atención configurado para el agente y la zona horaria */\n async getSchedule(agentId: string): Promise<{ schedule: AgentSchedule | null; timezone: string }> {\n return this.http.request<{ schedule: AgentSchedule | null; timezone: string }>('GET', `/ai/agents/${agentId}/schedule`);\n }\n\n /** Configura o reemplaza el horario de atención activa del agente */\n async setSchedule(agentId: string, options: SetScheduleOptions): Promise<{ schedule: AgentSchedule; timezone: string }> {\n return this.http.request<{ schedule: AgentSchedule; timezone: string }>('PUT', `/ai/agents/${agentId}/schedule`, {\n days: options.days,\n active_from: options.activeFrom,\n active_until: options.activeUntil,\n name: options.name,\n is_active: options.isActive,\n });\n }\n\n /** Lista los documentos de la base de conocimiento RAG asociados al agente */\n async listKnowledge(agentId: string): Promise<KnowledgeDocument[]> {\n const res = await this.http.request<{ documents: KnowledgeDocument[] }>('GET', `/ai/agents/${agentId}/knowledge`);\n return res.documents;\n }\n\n /** Ingesta y vectoriza nuevo conocimiento en texto plano directamente al agente */\n async addKnowledge(agentId: string, options: AddKnowledgeOptions): Promise<KnowledgeDocument> {\n const res = await this.http.request<{ document: KnowledgeDocument }>('POST', `/ai/agents/${agentId}/knowledge`, {\n title: options.title,\n content: options.content,\n description: options.description,\n });\n return res.document;\n }\n\n /** Ejecuta una consulta conversacional contra el agente y su base de conocimiento RAG */\n async execute(options: { agentId: string; message: string }): Promise<{ response: string; tokens_used?: number }> {\n return this.http.request('POST', `/ai/agents/${options.agentId}/execute`, {\n message: options.message,\n });\n }\n}\n\n// ── MAIN CLIENT ─────────────────────────────────────────────────────────────\n\n/**\n * Cliente oficial de Novapsis SM.\n * Punto de entrada principal para interactuar con todos los servicios.\n *\n * @example\n * ```typescript\n * import { Novapsis } from 'novapsis';\n *\n * const client = new Novapsis({\n * apiKey: 'nvs_live_sample_abcdef1234567890',\n * });\n *\n * // Enviar mensaje de texto\n * await client.whatsapp.sendText({\n * to: '34600112233',\n * text: '¡Hola desde Novapsis SDK!'\n * });\n * ```\n */\nexport class Novapsis {\n private http: HttpClient;\n\n /** Métodos para ajustes de la organización y cambio de nombre de la app */\n public readonly organization: OrganizationService;\n /** Métodos para envíos y operaciones de WhatsApp */\n public readonly whatsapp: WhatsAppService;\n /** Métodos para onboarding hosted y vinculación B2B */\n public readonly onboarding: OnboardingService;\n /** Métodos para suscripción y validación de Webhooks */\n public readonly webhooks: WebhookService;\n /** Métodos para contactos del CRM */\n public readonly contacts: ContactsService;\n /** Métodos para Agentes de Inteligencia Artificial (prompts, RAG, horarios) */\n public readonly ai: AIService;\n\n constructor(options: NovapsisClientOptions) {\n if (!options.apiKey) {\n throw new NovapsisAPIError('Se requiere una apiKey válida para inicializar el cliente de Novapsis.', 'CONFIG_ERROR', 400);\n }\n this.http = new HttpClient(options);\n this.organization = new OrganizationService(this.http);\n this.whatsapp = new WhatsAppService(this.http);\n this.onboarding = new OnboardingService(this.http);\n this.webhooks = new WebhookService(this.http);\n this.contacts = new ContactsService(this.http);\n this.ai = new AIService(this.http);\n }\n}\n\n// Default export\nexport default Novapsis;\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * novapsis - Official TypeScript / JavaScript SDK\n * ══════════════════════════════════════════════════════════════════════════════\n * Official SDK for Novapsis SM.\n * Universal typed client for WhatsApp Business Cloud API, Hosted Onboarding,\n * CRM, AI Agents and HMAC Webhook Verification.\n *\n * @version 1.1.1\n * @author Novapsis Technologies\n * @license MIT\n * ══════════════════════════════════════════════════════════════════════════════\n */\n\nimport crypto from 'crypto';\n\n// ── TYPES & DEFINITIONS ──────────────────────────────────────────────────────\n\nexport interface NovapsisClientOptions {\n /** Clave de API de Novapsis (empieza por nvs_live_ o nvs_test_) */\n apiKey: string;\n /** URL base de la API (por defecto: https://app.novapsis.com) */\n baseUrl?: string;\n /** Timeout en milisegundos para peticiones HTTP (por defecto: 15000) */\n timeoutMs?: number;\n /** Número máximo de reintentos automáticos ante fallos de red transitorios (por defecto: 2) */\n maxRetries?: number;\n}\n\nexport interface APIResponse<T = any> {\n success: boolean;\n data?: T;\n error?: {\n code: string;\n message: string;\n details?: any;\n };\n}\n\nexport class NovapsisAPIError extends Error {\n public readonly code: string;\n public readonly status: number;\n public readonly details?: any;\n\n constructor(message: string, code = 'API_ERROR', status = 500, details?: any) {\n super(message);\n this.name = 'NovapsisAPIError';\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\n// ── WHATSAPP TYPES ───────────────────────────────────────────────────────────\n\nexport interface SendBaseOptions {\n /** Número destinatario con código de país, sin '+' ni espacios (ej: '34600112233') */\n to: string;\n /** UUID de la conexión o Phone Number ID de Meta desde el cual enviar. Si se omite, usa la línea principal. */\n connectionId?: string;\n}\n\nexport interface SendTextOptions extends SendBaseOptions {\n /** Cuerpo del mensaje de texto */\n text: string;\n /** Si es true, genera vista previa de los enlaces web incluidos en el texto */\n previewUrl?: boolean;\n}\n\nexport interface SendImageOptions extends SendBaseOptions {\n /** URL HTTPS pública de la imagen (JPG, PNG, WebP) */\n imageUrl: string;\n /** Pie de foto opcional */\n caption?: string;\n}\n\nexport interface SendAudioOptions extends SendBaseOptions {\n /** URL HTTPS pública del archivo de audio (MP3, AAC, OGG, M4A) */\n audioUrl: string;\n}\n\nexport interface SendDocumentOptions extends SendBaseOptions {\n /** URL HTTPS pública del documento o PDF */\n documentUrl: string;\n /** Nombre visible del archivo (ej: 'factura_2026.pdf') */\n filename?: string;\n /** Descripción o pie opcional */\n caption?: string;\n}\n\nexport interface SendVideoOptions extends SendBaseOptions {\n /** URL HTTPS pública del video (MP4, 3GP) */\n videoUrl: string;\n /** Pie de video opcional */\n caption?: string;\n}\n\nexport interface SendLocationOptions extends SendBaseOptions {\n /** Coordenada de latitud decimal (ej: 40.416775) */\n latitude: number | string;\n /** Coordenada de longitud decimal (ej: -3.703790) */\n longitude: number | string;\n /** Nombre del lugar o establecimiento (ej: 'Sede Central Madrid') */\n name?: string;\n /** Dirección postal completa */\n address?: string;\n}\n\nexport interface SendContactCardOptions extends SendBaseOptions {\n /** Nombre completo del contacto a compartir */\n name: string;\n /** Número de teléfono del contacto compartido */\n phone: string;\n}\n\nexport interface SendTemplateOptions extends SendBaseOptions {\n /** Nombre exacto de la plantilla aprobada en Meta */\n templateName: string;\n /** Código de idioma (por defecto: 'es') */\n languageCode?: string;\n /** Componentes y variables dinámicas de la plantilla */\n components?: Array<{\n type: 'header' | 'body' | 'button';\n sub_type?: string;\n index?: string | number;\n parameters?: Array<{\n type: 'text' | 'image' | 'document' | 'video' | 'currency' | 'date_time';\n text?: string;\n [key: string]: any;\n }>;\n }>;\n}\n\nexport interface SendMessageResult {\n message_id: string;\n recipient: string;\n connection_id?: string;\n phone_number_id?: string;\n business_phone_number?: string | null;\n type: string;\n status: string;\n conversation_id: string | null;\n}\n\nexport interface WhatsAppConnection {\n id: string;\n display_name: string;\n phone_number: string | null;\n phone_number_id: string;\n waba_id?: string | null;\n verified_name: string | null;\n quality_rating?: string | null;\n status: string;\n webhook_subscribed: boolean;\n created_at?: string;\n}\n\nexport interface WhatsAppTemplate {\n id: string;\n template_name?: string;\n display_name?: string;\n name?: string;\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION' | string;\n language: string;\n status: 'APPROVED' | 'PENDING' | 'REJECTED' | 'PAUSED' | string;\n quality_rating?: string | null;\n components: any[];\n meta_template_id?: string | null;\n rejection_reason?: string | null;\n waba_id?: string | null;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ListTemplatesOptions {\n /** Filtrar por estado en Meta (ej: 'APPROVED', 'PENDING', 'REJECTED') */\n status?: 'APPROVED' | 'PENDING' | 'REJECTED' | 'PAUSED' | string;\n /** Filtrar por categoría oficial */\n category?: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION' | string;\n}\n\nexport interface CreateTemplateOptions {\n /** Nombre técnico en Meta (solo minúsculas, números y guiones bajos, ej: 'confirmacion_pedido_v1') */\n name?: string;\n template_name?: string;\n /** Nombre descriptivo para el panel */\n displayName?: string;\n display_name?: string;\n /** Categoría oficial de Meta */\n category: 'MARKETING' | 'UTILITY' | 'AUTHENTICATION';\n /** Código de idioma (por defecto: 'es') */\n language?: string;\n /** Componentes según especificación de Meta Graph API (HEADER, BODY, BUTTONS, etc.) */\n components?: any[];\n /** Texto plano del cuerpo si no se envían componentes avanzados */\n bodyText?: string;\n /** ID de conexión de WhatsApp (opcional si la cuenta tiene una sola activa) */\n connectionId?: string;\n connection_id?: string;\n /** TTL de entrega en segundos (opcional) */\n messageSendTtlSeconds?: number;\n}\n\n// ── ORGANIZATION & SETTINGS TYPES ───────────────────────────────────────────\n\nexport interface OrganizationDetails {\n id: string;\n name: string;\n timezone: string;\n tier: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface UpdateOrganizationOptions {\n /** Nombre de la empresa o aplicación (cambio de nombre / settings de la app) */\n name?: string;\n /** Zona horaria IANA (ej: 'Europe/Madrid', 'America/Bogota', 'America/Mexico_City') */\n timezone?: string;\n}\n\n// ── AI AGENTS & RAG TYPES ───────────────────────────────────────────────────\n\nexport interface AgentDetails {\n id: string;\n name: string;\n system_prompt: string;\n model: string;\n mode: 'agent' | 'rag' | 'both';\n temperature: number;\n is_active: boolean;\n grouping_timeout_seconds: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CreateAgentOptions {\n /** Nombre del agente de IA (ej: 'Asistente Ventas') */\n name: string;\n /** Prompt de sistema e instrucciones de comportamiento */\n systemPrompt: string;\n /** Modelo de IA a utilizar (por defecto: 'gemini-2.5-flash') */\n model?: string;\n /** Modo de operación: 'agent', 'rag' o 'both' */\n mode?: 'agent' | 'rag' | 'both';\n /** Creatividad (temperatura 0.0 - 1.0) */\n temperature?: number;\n /** Si el agente está activo respondiendo chats */\n isActive?: boolean;\n /** Ventana de agrupación de mensajes en segundos */\n groupingTimeoutSeconds?: number;\n}\n\nexport interface UpdateAgentOptions {\n /** Nuevo nombre del agente (cambio de nombre del bot) */\n name?: string;\n /** Nuevo prompt de sistema */\n systemPrompt?: string;\n /** Modelo de IA */\n model?: string;\n /** Modo de operación */\n mode?: 'agent' | 'rag' | 'both';\n /** Creatividad */\n temperature?: number;\n /** Estado activo o inactivo */\n isActive?: boolean;\n /** Ventana de agrupación en segundos */\n groupingTimeoutSeconds?: number;\n}\n\nexport interface AgentSchedule {\n id: string;\n agent_id: string;\n name: string;\n days: number[]; // 1=Lunes, 7=Domingo\n active_from: string; // \"HH:MM\"\n active_until: string; // \"HH:MM\"\n is_active: boolean;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface SetScheduleOptions {\n /** Días activos: 1=Lunes, 2=Martes, 3=Miércoles, 4=Jueves, 5=Viernes, 6=Sábado, 7=Domingo */\n days: number[];\n /** Hora de apertura en formato HH:MM (ej: '09:00') */\n activeFrom: string;\n /** Hora de cierre en formato HH:MM (ej: '19:00') */\n activeUntil: string;\n /** Nombre de la franja horaria */\n name?: string;\n /** Si el horario está habilitado */\n isActive?: boolean;\n}\n\nexport interface KnowledgeDocument {\n id: string;\n title: string;\n description?: string | null;\n file_type: string;\n total_chunks?: number;\n created_at: string;\n updated_at?: string;\n}\n\nexport interface AddKnowledgeOptions {\n /** Título o tema del documento (ej: 'Políticas de garantía y devoluciones') */\n title: string;\n /** Contenido en texto plano a vectorizar para RAG */\n content: string;\n /** Descripción contextual */\n description?: string;\n}\n\n// ── ONBOARDING TYPES ─────────────────────────────────────────────────────────\n\nexport interface OnboardingFeatureBullet {\n title: string;\n description?: string;\n}\n\nexport interface CreateOnboardingSessionOptions {\n /** Nombre del cliente, empresa o sede (ej: 'Clínica Dental') */\n clientName?: string;\n /** Nombre corporativo visible */\n companyName?: string;\n /** URL de retorno tras conectar exitosamente con WhatsApp */\n redirectUrl?: string;\n /** URL pública del logotipo corporativo para marca blanca (PNG, SVG, JPG) */\n logoUrl?: string;\n\n // ── Personalización de Estilos y Colores (Marca Blanca) ──\n /** Color de acento principal (ej: '#0ea5e9') */\n brandColor?: string;\n /** Color de fondo general de la pantalla (ej: '#0f172a' o '#ffffff') */\n backgroundColor?: string;\n /** Color de fondo de la tarjeta/modal (ej: '#1e293b' o '#ffffff') */\n cardBackgroundColor?: string;\n /** Color del borde de la tarjeta (ej: 'rgba(255,255,255,0.1)') */\n cardBorderColor?: string;\n /** Color de los títulos y textos principales (ej: '#ffffff' o '#0f172a') */\n textColor?: string;\n /** Color de los textos secundarios y descripciones (ej: '#94a3b8') */\n textSecondaryColor?: string;\n /** Color de fondo del botón de acción (por defecto usa brandColor o verde WhatsApp) */\n buttonColor?: string;\n /** Color del texto dentro del botón de acción */\n buttonTextColor?: string;\n /** Color de fondo de la píldora superior */\n badgeColor?: string;\n /** Color del texto de la píldora superior */\n badgeTextColor?: string;\n\n // ── Personalización de Copys y Textos ──\n /** Título principal (por defecto: 'Conecta WhatsApp Business') */\n title?: string;\n /** Texto explicativo debajo del título */\n description?: string;\n /** Texto del botón principal (por defecto: 'Conectar con WhatsApp') */\n buttonText?: string;\n /** Texto de la píldora superior (por defecto: 'Vinculación Oficial', o '' para ocultar) */\n badgeText?: string;\n /** Texto legal o footer de la tarjeta */\n footerText?: string;\n /** Viñetas de beneficios o false para ocultar la caja */\n features?: OnboardingFeatureBullet[] | boolean;\n /** Título de la pantalla de éxito tras vincular */\n successTitle?: string;\n /** Descripción de la pantalla de éxito */\n successDescription?: string;\n /** Texto del botón en la pantalla de éxito */\n successButtonText?: string;\n /** Si es true, oculta el badge 'Meta Tech Provider Verified' del encabezado */\n hideMetaBadge?: boolean;\n /** Si es true, oculta el pie de página de copyright */\n hideFooter?: boolean;\n\n /** Horas de validez de la sesión antes de expirar (por defecto: 168 = 7 días) */\n expiresInHours?: number;\n /** Metadata personalizada para tracking en tu CRM */\n metadata?: Record<string, any>;\n}\n\nexport interface OnboardingSession {\n id: string;\n session_id: string;\n session_url: string;\n status: 'started' | 'completed' | 'expired' | 'failed';\n expires_at: string;\n created_at: string;\n}\n\n// ── WEBHOOK TYPES ────────────────────────────────────────────────────────────\n\nexport type NovapsisWebhookEvent =\n | 'whatsapp.message_received'\n | 'whatsapp.message_sent'\n | 'whatsapp.connected'\n | 'conversation.started'\n | 'lead.completed'\n | 'call.completed'\n | 'review.received'\n | '*';\n\nexport interface WhatsAppMessageReceivedData {\n conversation_id: string;\n message_id: string;\n external_message_id?: string | null;\n platform: 'whatsapp' | string;\n\n // ── Datos completos de la línea receptora (Empresa) ──\n connection_id: string;\n phone_number_id: string;\n waba_id?: string | null;\n business_phone_number: string | null;\n business_name?: string | null;\n connection_name?: string | null;\n to: string | null;\n\n // ── Datos del cliente emisor ──\n from: string;\n external_user_id: string;\n external_user_name: string;\n\n // ── Contenido y Multimedia ──\n content: string;\n media_type: 'image' | 'audio' | 'video' | 'document' | null;\n media_url: string | null;\n timestamp: string;\n}\n\nexport interface WhatsAppMessageSentData {\n conversation_id: string;\n message_id: string;\n platform: 'whatsapp' | string;\n\n // ── Datos completos de la línea emisora (Empresa) ──\n connection_id: string;\n phone_number_id: string;\n waba_id?: string | null;\n business_phone_number: string | null;\n business_name?: string | null;\n connection_name?: string | null;\n from: string | null;\n\n // ── Datos del destinatario (Cliente) ──\n to: string;\n external_user_id: string;\n\n role: 'assistant';\n sender_type: 'ai' | 'human';\n content: string;\n media_type?: string | null;\n media_url?: string | null;\n timestamp: string;\n}\n\nexport interface CreateWebhookSubscriptionOptions {\n /** Nombre descriptivo de la suscripción (ej: 'CRM Sincronizador') */\n name: string;\n /** URL HTTPS de tu backend que recibirá los eventos POST */\n url: string;\n /** Lista de eventos a escuchar */\n events: NovapsisWebhookEvent[];\n /** Secreto opcional para firma HMAC. Si se omite, Novapsis generará uno automáticamente. */\n secret?: string;\n}\n\nexport interface WebhookSubscription {\n id: string;\n name: string;\n url: string;\n events: string[];\n secret: string;\n is_active: boolean;\n created_at: string;\n}\n\nexport interface InboundWebhookPayload<T = any> {\n event: NovapsisWebhookEvent;\n timestamp: string;\n organization_id: string;\n data: T;\n}\n\n// ── CRM & CONTACTS TYPES ─────────────────────────────────────────────────────\n\nexport interface UpsertContactOptions {\n phone: string;\n name?: string;\n email?: string;\n tags?: string[];\n metadata?: Record<string, any>;\n}\n\nexport interface Contact {\n id: string;\n phone: string;\n name: string | null;\n email: string | null;\n tags: string[];\n created_at: string;\n}\n\n// ── INTERNAL HTTP CLIENT ────────────────────────────────────────────────────\n\nclass HttpClient {\n private apiKey: string;\n private baseUrl: string;\n private timeoutMs: number;\n private maxRetries: number;\n\n constructor(options: NovapsisClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl || 'https://app.novapsis.com').replace(/\\/+$/, '');\n this.timeoutMs = options.timeoutMs || 15000;\n this.maxRetries = options.maxRetries ?? 2;\n }\n\n async request<T>(method: string, path: string, body?: any, query?: Record<string, string>): Promise<T> {\n let url = `${this.baseUrl}/api/v1${path.startsWith('/') ? path : `/${path}`}`;\n if (query && Object.keys(query).length > 0) {\n const qs = new URLSearchParams(query).toString();\n url += `?${qs}`;\n }\n\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'Novapsis-SDK-Node/1.1.1',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const data: APIResponse<T> = await response.json().catch(() => ({\n success: false,\n error: { code: 'INVALID_JSON_RESPONSE', message: `HTTP ${response.status} Sin cuerpo JSON válido.` },\n }));\n\n if (!response.ok || !data.success) {\n throw new NovapsisAPIError(\n data.error?.message || `Error en petición HTTP ${response.status}`,\n data.error?.code || `HTTP_${response.status}`,\n response.status,\n data.error?.details\n );\n }\n\n return data.data as T;\n } catch (err: any) {\n clearTimeout(timeoutId);\n lastError = err;\n\n // No reintentar errores de validación de cliente 4xx\n if (err instanceof NovapsisAPIError && err.status >= 400 && err.status < 500) {\n throw err;\n }\n\n // Si es el último intento, lanzar el error\n if (attempt === this.maxRetries) {\n break;\n }\n\n // Backoff exponencial: 300ms, 900ms...\n await new Promise((resolve) => setTimeout(resolve, 300 * Math.pow(3, attempt)));\n }\n }\n\n throw lastError || new NovapsisAPIError('Error de red al comunicarse con Novapsis API', 'NETWORK_ERROR', 0);\n }\n}\n\n// ── SDK SERVICES ────────────────────────────────────────────────────────────\n\n/** Servicio para envíos y gestión de WhatsApp Cloud API */\nexport class WhatsAppService {\n constructor(private http: HttpClient) {}\n\n /** Envía un mensaje de texto plano */\n async sendText(options: SendTextOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'text',\n text: options.text,\n });\n }\n\n /** Envía una imagen o fotografía */\n async sendImage(options: SendImageOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'image',\n media_url: options.imageUrl,\n caption: options.caption,\n });\n }\n\n /** Envía un archivo de audio o nota de voz */\n async sendAudio(options: SendAudioOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'audio',\n media_url: options.audioUrl,\n });\n }\n\n /** Envía un documento (PDF, Word, Excel, etc.) con nombre de archivo personalizado */\n async sendDocument(options: SendDocumentOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'document',\n media_url: options.documentUrl,\n filename: options.filename,\n caption: options.caption,\n });\n }\n\n /** Envía un video */\n async sendVideo(options: SendVideoOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'video',\n media_url: options.videoUrl,\n caption: options.caption,\n });\n }\n\n /** Envía una ubicación con coordenadas y dirección en el mapa */\n async sendLocation(options: SendLocationOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'location',\n latitude: options.latitude,\n longitude: options.longitude,\n location_name: options.name,\n location_address: options.address,\n });\n }\n\n /** Envía una tarjeta de contacto (vCard) interactiva */\n async sendContact(options: SendContactCardOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'contacts',\n contact_name: options.name,\n contact_phone: options.phone,\n });\n }\n\n /** Envía una plantilla oficial aprobada por Meta con variables dinámicas */\n async sendTemplate(options: SendTemplateOptions): Promise<SendMessageResult> {\n return this.http.request<SendMessageResult>('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'template',\n template_name: options.templateName,\n language_code: options.languageCode || 'es',\n components: options.components || [],\n });\n }\n\n /** Marca un mensaje o chat como leído */\n async markAsRead(options: { to: string; connectionId?: string; messageId?: string }): Promise<any> {\n return this.http.request('POST', '/whatsapp/messages', {\n recipient: options.to,\n connection_id: options.connectionId,\n type: 'mark_read',\n message_id: options.messageId,\n });\n }\n\n /** Obtiene la lista de líneas y números de WhatsApp conectados en la organización */\n async listConnections(): Promise<WhatsAppConnection[]> {\n const res = await this.http.request<{ connections: WhatsAppConnection[] }>('GET', '/whatsapp/connections');\n return res.connections;\n }\n\n /** Lista las plantillas oficiales de Meta con filtros opcionales de estado y categoría */\n async listTemplates(options: ListTemplatesOptions = {}): Promise<WhatsAppTemplate[]> {\n const query: Record<string, string> = {};\n if (options.status) query.status = options.status;\n if (options.category) query.category = options.category;\n const res = await this.http.request<{ templates: WhatsAppTemplate[] }>('GET', '/whatsapp/templates', undefined, query);\n return res.templates;\n }\n\n /** Obtiene las plantillas oficiales de Meta aprobadas (alias directo de listTemplates) */\n async getTemplates(): Promise<WhatsAppTemplate[]> {\n return this.listTemplates();\n }\n\n /** Crea una nueva plantilla oficial de WhatsApp para someter a revisión y aprobación en Meta */\n async createTemplate(options: CreateTemplateOptions): Promise<{ template: WhatsAppTemplate }> {\n const templateName = options.template_name || options.name;\n if (!templateName) {\n throw new NovapsisAPIError('Se requiere `name` o `template_name` para crear una plantilla.', 'VALIDATION_ERROR', 400);\n }\n const components = options.components || (options.bodyText ? [{ type: 'BODY', text: options.bodyText }] : []);\n\n return this.http.request<{ template: WhatsAppTemplate }>('POST', '/whatsapp/templates', {\n template_name: templateName,\n display_name: options.displayName || options.display_name,\n category: options.category,\n language: options.language || 'es',\n components,\n connection_id: options.connectionId || options.connection_id,\n message_send_ttl_seconds: options.messageSendTtlSeconds,\n });\n }\n\n /** Lista las campañas masivas de WhatsApp configuradas */\n async listCampaigns(): Promise<any[]> {\n const res = await this.http.request<{ campaigns: any[] }>('GET', '/whatsapp/campaigns');\n return res.campaigns;\n }\n\n /** Ejecuta una campaña masiva */\n async executeCampaign(campaignId: string): Promise<any> {\n return this.http.request('POST', `/whatsapp/campaigns/${campaignId}/execute`);\n }\n}\n\n/** Servicio para onboarding y conexión de WhatsApp de clientes B2B (Marca Blanca) */\nexport class OnboardingService {\n constructor(private http: HttpClient) {}\n\n /**\n * Crea una sesión de conexión hosted para que un cliente o sede vincule su WhatsApp.\n * Devuelve `session_url` que puedes abrir en un modal o popup en tu CRM.\n */\n async createSession(options: CreateOnboardingSessionOptions = {}): Promise<OnboardingSession> {\n return this.http.request<OnboardingSession>('POST', '/onboarding/sessions', {\n client_name: options.clientName,\n company_name: options.companyName,\n redirect_url: options.redirectUrl,\n logo_url: options.logoUrl,\n brand_color: options.brandColor,\n background_color: options.backgroundColor,\n card_background_color: options.cardBackgroundColor,\n card_border_color: options.cardBorderColor,\n text_color: options.textColor,\n text_secondary_color: options.textSecondaryColor,\n button_color: options.buttonColor,\n button_text_color: options.buttonTextColor,\n badge_color: options.badgeColor,\n badge_text_color: options.badgeTextColor,\n title: options.title,\n description: options.description,\n button_text: options.buttonText,\n badge_text: options.badgeText,\n footer_text: options.footerText,\n features: options.features,\n success_title: options.successTitle,\n success_description: options.successDescription,\n success_button_text: options.successButtonText,\n hide_meta_badge: options.hideMetaBadge,\n hide_footer: options.hideFooter,\n expires_in_hours: options.expiresInHours,\n metadata: options.metadata,\n });\n }\n\n /** Consulta el estado de una sesión de onboarding por su ID */\n async getSessionStatus(sessionId: string): Promise<OnboardingSession> {\n return this.http.request<OnboardingSession>('GET', `/onboarding/sessions/${sessionId}`);\n }\n}\n\n/** Servicio para gestionar Webhooks salientes en tiempo real */\nexport class WebhookService {\n constructor(private http: HttpClient) {}\n\n /** Suscribe una URL de tu backend para recibir eventos en tiempo real */\n async subscribe(options: CreateWebhookSubscriptionOptions): Promise<WebhookSubscription> {\n return this.http.request<WebhookSubscription>('POST', '/webhooks/subscriptions', {\n name: options.name,\n url: options.url,\n events: options.events,\n secret: options.secret,\n is_active: true,\n });\n }\n\n /** Lista todas las suscripciones de webhooks activas */\n async list(): Promise<WebhookSubscription[]> {\n const res = await this.http.request<{ subscriptions: WebhookSubscription[] }>('GET', '/webhooks/subscriptions');\n return res.subscriptions;\n }\n\n /** Elimina una suscripción de webhook */\n async delete(webhookId: string): Promise<boolean> {\n const res = await this.http.request<{ success: boolean }>('DELETE', `/webhooks/subscriptions/${webhookId}`);\n return res.success;\n }\n\n /**\n * Valida la firma criptográfica HMAC SHA-256 de un webhook recibido de Novapsis SM.\n * Evita ataques de suplantación garantizando que la petición proviene de Novapsis.\n *\n * @param rawBody - El cuerpo crudo recibido en el request (string sin parsear)\n * @param signatureHeader - El header 'X-Novapsis-Signature'\n * @param secret - Tu secreto de webhook de Novapsis\n */\n verifySignature(rawBody: string, signatureHeader: string | null | undefined, secret: string): boolean {\n if (!signatureHeader || !secret || !rawBody) return false;\n try {\n const cleanSig = signatureHeader.startsWith('sha256=')\n ? signatureHeader.slice(7)\n : signatureHeader;\n const computed = crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex');\n const bufA = Buffer.from(computed, 'hex');\n const bufB = Buffer.from(cleanSig, 'hex');\n if (bufA.length !== bufB.length) return false;\n return crypto.timingSafeEqual(bufA, bufB);\n } catch {\n return false;\n }\n }\n}\n\n/** Servicio para gestionar Contactos del CRM */\nexport class ContactsService {\n constructor(private http: HttpClient) {}\n\n /** Lista contactos del CRM */\n async list(): Promise<Contact[]> {\n const res = await this.http.request<{ contacts: Contact[] }>('GET', '/contacts');\n return res.contacts;\n }\n\n /** Crea o actualiza un contacto por número de teléfono */\n async upsert(options: UpsertContactOptions): Promise<Contact> {\n return this.http.request<Contact>('POST', '/contacts', options);\n }\n}\n\n/** Servicio para gestión de la organización y configuración general (Marca / Settings) */\nexport class OrganizationService {\n constructor(private http: HttpClient) {}\n\n /** Obtiene la información y configuración de la organización actual */\n async get(): Promise<OrganizationDetails> {\n const res = await this.http.request<{ organization: OrganizationDetails }>('GET', '/organization');\n return res.organization;\n }\n\n /**\n * Actualiza la configuración de la organización (cambio de nombre de la app/empresa, zona horaria)\n */\n async update(options: UpdateOrganizationOptions): Promise<OrganizationDetails> {\n const res = await this.http.request<{ organization: OrganizationDetails }>('PATCH', '/organization', {\n name: options.name,\n timezone: options.timezone,\n });\n return res.organization;\n }\n}\n\n/** Servicio para interactuar y configurar Agentes de Inteligencia Artificial (Headless AI) */\nexport class AIService {\n constructor(private http: HttpClient) {}\n\n /** Lista los agentes de IA configurados en la organización */\n async listAgents(): Promise<AgentDetails[]> {\n const res = await this.http.request<{ agents: AgentDetails[] }>('GET', '/ai/agents');\n return res.agents;\n }\n\n /** Obtiene la configuración completa de un agente por su ID */\n async getAgent(agentId: string): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('GET', `/ai/agents/${agentId}`);\n return res.agent;\n }\n\n /** Crea un nuevo agente de IA para la organización */\n async createAgent(options: CreateAgentOptions): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('POST', '/ai/agents', {\n name: options.name,\n system_prompt: options.systemPrompt,\n model: options.model,\n mode: options.mode,\n temperature: options.temperature,\n is_active: options.isActive,\n grouping_timeout_seconds: options.groupingTimeoutSeconds,\n });\n return res.agent;\n }\n\n /** Actualiza nombre, prompt de sistema, modelo o configuración de un agente */\n async updateAgent(agentId: string, options: UpdateAgentOptions): Promise<AgentDetails> {\n const res = await this.http.request<{ agent: AgentDetails }>('PATCH', `/ai/agents/${agentId}`, {\n name: options.name,\n system_prompt: options.systemPrompt,\n model: options.model,\n mode: options.mode,\n temperature: options.temperature,\n is_active: options.isActive,\n grouping_timeout_seconds: options.groupingTimeoutSeconds,\n });\n return res.agent;\n }\n\n /** Consulta el horario de atención configurado para el agente y la zona horaria */\n async getSchedule(agentId: string): Promise<{ schedule: AgentSchedule | null; timezone: string }> {\n return this.http.request<{ schedule: AgentSchedule | null; timezone: string }>('GET', `/ai/agents/${agentId}/schedule`);\n }\n\n /** Configura o reemplaza el horario de atención activa del agente */\n async setSchedule(agentId: string, options: SetScheduleOptions): Promise<{ schedule: AgentSchedule; timezone: string }> {\n return this.http.request<{ schedule: AgentSchedule; timezone: string }>('PUT', `/ai/agents/${agentId}/schedule`, {\n days: options.days,\n active_from: options.activeFrom,\n active_until: options.activeUntil,\n name: options.name,\n is_active: options.isActive,\n });\n }\n\n /** Lista los documentos de la base de conocimiento RAG asociados al agente */\n async listKnowledge(agentId: string): Promise<KnowledgeDocument[]> {\n const res = await this.http.request<{ documents: KnowledgeDocument[] }>('GET', `/ai/agents/${agentId}/knowledge`);\n return res.documents;\n }\n\n /** Ingesta y vectoriza nuevo conocimiento en texto plano directamente al agente */\n async addKnowledge(agentId: string, options: AddKnowledgeOptions): Promise<KnowledgeDocument> {\n const res = await this.http.request<{ document: KnowledgeDocument }>('POST', `/ai/agents/${agentId}/knowledge`, {\n title: options.title,\n content: options.content,\n description: options.description,\n });\n return res.document;\n }\n\n /** Ejecuta una consulta conversacional contra el agente y su base de conocimiento RAG */\n async execute(options: { agentId: string; message: string }): Promise<{ response: string; tokens_used?: number }> {\n return this.http.request('POST', `/ai/agents/${options.agentId}/execute`, {\n message: options.message,\n });\n }\n}\n\n// ── MAIN CLIENT ─────────────────────────────────────────────────────────────\n\n/**\n * Cliente oficial de Novapsis SM.\n * Punto de entrada principal para interactuar con todos los servicios.\n *\n * @example\n * ```typescript\n * import { Novapsis } from 'novapsis';\n *\n * const client = new Novapsis({\n * apiKey: 'nvs_live_sample_abcdef1234567890',\n * });\n *\n * // Enviar mensaje de texto\n * await client.whatsapp.sendText({\n * to: '34600112233',\n * text: '¡Hola desde Novapsis SDK!'\n * });\n * ```\n */\nexport class Novapsis {\n private http: HttpClient;\n\n /** Métodos para ajustes de la organización y cambio de nombre de la app */\n public readonly organization: OrganizationService;\n /** Métodos para envíos y operaciones de WhatsApp */\n public readonly whatsapp: WhatsAppService;\n /** Métodos para onboarding hosted y vinculación B2B */\n public readonly onboarding: OnboardingService;\n /** Métodos para suscripción y validación de Webhooks */\n public readonly webhooks: WebhookService;\n /** Métodos para contactos del CRM */\n public readonly contacts: ContactsService;\n /** Métodos para Agentes de Inteligencia Artificial (prompts, RAG, horarios) */\n public readonly ai: AIService;\n\n constructor(options: NovapsisClientOptions) {\n if (!options.apiKey) {\n throw new NovapsisAPIError('Se requiere una apiKey válida para inicializar el cliente de Novapsis.', 'CONFIG_ERROR', 400);\n }\n this.http = new HttpClient(options);\n this.organization = new OrganizationService(this.http);\n this.whatsapp = new WhatsAppService(this.http);\n this.onboarding = new OnboardingService(this.http);\n this.webhooks = new WebhookService(this.http);\n this.contacts = new ContactsService(this.http);\n this.ai = new AIService(this.http);\n }\n}\n\n// Default export\nexport default Novapsis;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "novapsis",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "SDK oficial de Novapsis SM para Node.js, Next.js y TypeScript. WhatsApp Cloud API, Onboarding B2B Marca Blanca, CRM y Webhooks HMAC.",
5
5
  "author": "Novapsis Technologies <soporte@novapsis.com> (https://app.novapsis.com)",
6
6
  "license": "MIT",