@utilia-os/sdk-js 1.0.0
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/README.md +187 -0
- package/dist/index.d.mts +872 -0
- package/dist/index.d.ts +872 -0
- package/dist/index.js +817 -0
- package/dist/index.mjs +777 -0
- package/package.json +71 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,872 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tipos de configuracion del SDK
|
|
3
|
+
*/
|
|
4
|
+
interface UtiliaSDKConfig {
|
|
5
|
+
/** URL base de la API (ej: https://os.utilia.ai/api) */
|
|
6
|
+
baseURL: string;
|
|
7
|
+
/** API Key para autenticacion */
|
|
8
|
+
apiKey: string;
|
|
9
|
+
/** Timeout en milisegundos (default: 30000) */
|
|
10
|
+
timeout?: number;
|
|
11
|
+
/** Numero de reintentos en caso de error (default: 3) */
|
|
12
|
+
retryAttempts?: number;
|
|
13
|
+
/** Habilitar logs de debug (default: false) */
|
|
14
|
+
debug?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface RequestConfig {
|
|
17
|
+
headers?: Record<string, string>;
|
|
18
|
+
params?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Cliente HTTP base para el SDK
|
|
23
|
+
* Maneja la comunicacion con la API de UTILIA OS
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
declare class UtiliaClient {
|
|
27
|
+
private readonly axios;
|
|
28
|
+
private readonly config;
|
|
29
|
+
constructor(config: UtiliaSDKConfig);
|
|
30
|
+
/**
|
|
31
|
+
* Configura los interceptores de request y response
|
|
32
|
+
*/
|
|
33
|
+
private setupInterceptors;
|
|
34
|
+
/**
|
|
35
|
+
* Convierte un error de Axios en un UtiliaSDKError
|
|
36
|
+
*/
|
|
37
|
+
private toSDKError;
|
|
38
|
+
/**
|
|
39
|
+
* Determina si un error es recuperable y se debe reintentar
|
|
40
|
+
*/
|
|
41
|
+
private isRetryableError;
|
|
42
|
+
/**
|
|
43
|
+
* Ejecuta una funcion con reintentos y backoff exponencial
|
|
44
|
+
*/
|
|
45
|
+
private executeWithRetry;
|
|
46
|
+
/**
|
|
47
|
+
* Helper para esperar un tiempo
|
|
48
|
+
*/
|
|
49
|
+
private sleep;
|
|
50
|
+
/**
|
|
51
|
+
* Realiza una peticion GET
|
|
52
|
+
*/
|
|
53
|
+
get<T>(url: string, config?: RequestConfig): Promise<T>;
|
|
54
|
+
/**
|
|
55
|
+
* Realiza una peticion POST
|
|
56
|
+
*/
|
|
57
|
+
post<T>(url: string, data?: unknown, config?: RequestConfig): Promise<T>;
|
|
58
|
+
/**
|
|
59
|
+
* Realiza una peticion PATCH
|
|
60
|
+
*/
|
|
61
|
+
patch<T>(url: string, data?: unknown, config?: RequestConfig): Promise<T>;
|
|
62
|
+
/**
|
|
63
|
+
* Realiza una peticion PUT
|
|
64
|
+
*/
|
|
65
|
+
put<T>(url: string, data?: unknown, config?: RequestConfig): Promise<T>;
|
|
66
|
+
/**
|
|
67
|
+
* Realiza una peticion DELETE
|
|
68
|
+
*/
|
|
69
|
+
delete<T>(url: string, config?: RequestConfig): Promise<T>;
|
|
70
|
+
/**
|
|
71
|
+
* Realiza una peticion POST con FormData (para subir archivos)
|
|
72
|
+
*/
|
|
73
|
+
postForm<T>(url: string, formData: FormData, onProgress?: (progress: number) => void): Promise<T>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Tipos relacionados con archivos adjuntos
|
|
78
|
+
*/
|
|
79
|
+
/**
|
|
80
|
+
* Opciones para subir un archivo
|
|
81
|
+
*/
|
|
82
|
+
interface UploadFileOptions {
|
|
83
|
+
/** Nombre personalizado para el archivo (opcional) */
|
|
84
|
+
name?: string;
|
|
85
|
+
/** Metadatos adicionales (opcional) */
|
|
86
|
+
metadata?: Record<string, unknown>;
|
|
87
|
+
/** Callback de progreso (opcional) */
|
|
88
|
+
onProgress?: (progress: number) => void;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Respuesta al subir un archivo
|
|
92
|
+
*/
|
|
93
|
+
interface UploadedFile {
|
|
94
|
+
/** ID del archivo para usar en attachmentIds */
|
|
95
|
+
id: string;
|
|
96
|
+
/** Nombre original del archivo */
|
|
97
|
+
originalName: string;
|
|
98
|
+
/** Tipo MIME */
|
|
99
|
+
mimeType: string;
|
|
100
|
+
/** Tamano en bytes */
|
|
101
|
+
size: number;
|
|
102
|
+
/** URL temporal de descarga */
|
|
103
|
+
downloadUrl: string;
|
|
104
|
+
/** Fecha de creacion */
|
|
105
|
+
createdAt: string;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Informacion de quota de almacenamiento
|
|
109
|
+
*/
|
|
110
|
+
interface FileQuota {
|
|
111
|
+
/** Bytes usados */
|
|
112
|
+
usedBytes: number;
|
|
113
|
+
/** Bytes maximos permitidos */
|
|
114
|
+
maxBytes: number;
|
|
115
|
+
/** Tamano maximo por archivo */
|
|
116
|
+
maxFileSizeBytes: number;
|
|
117
|
+
/** Porcentaje de uso (0-100) */
|
|
118
|
+
usagePercent: number;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Servicio de archivos adjuntos
|
|
123
|
+
* Permite subir archivos para adjuntar a tickets
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
declare class FilesService {
|
|
127
|
+
private readonly client;
|
|
128
|
+
private readonly basePath;
|
|
129
|
+
constructor(client: UtiliaClient);
|
|
130
|
+
/**
|
|
131
|
+
* Subir un archivo para adjuntar a tickets
|
|
132
|
+
*
|
|
133
|
+
* @param file - Archivo a subir (File o Blob)
|
|
134
|
+
* @param options - Opciones de subida
|
|
135
|
+
* @returns Archivo subido con su ID
|
|
136
|
+
*
|
|
137
|
+
* @example Browser
|
|
138
|
+
* ```typescript
|
|
139
|
+
* // Desde input file
|
|
140
|
+
* const input = document.querySelector('input[type="file"]');
|
|
141
|
+
* const file = input.files[0];
|
|
142
|
+
* const uploaded = await sdk.files.upload(file);
|
|
143
|
+
*
|
|
144
|
+
* // Usar en ticket
|
|
145
|
+
* await sdk.tickets.create({
|
|
146
|
+
* ...ticketData,
|
|
147
|
+
* attachmentIds: [uploaded.id],
|
|
148
|
+
* });
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
upload(file: File | Blob, options?: UploadFileOptions): Promise<UploadedFile>;
|
|
152
|
+
/**
|
|
153
|
+
* Obtener URL de descarga para un archivo
|
|
154
|
+
*
|
|
155
|
+
* @param fileId - ID del archivo
|
|
156
|
+
* @returns URL temporal de descarga
|
|
157
|
+
*/
|
|
158
|
+
getUrl(fileId: string): Promise<string>;
|
|
159
|
+
/**
|
|
160
|
+
* Obtener informacion de quota de almacenamiento
|
|
161
|
+
*
|
|
162
|
+
* @returns Informacion de uso y limites
|
|
163
|
+
*/
|
|
164
|
+
getQuota(): Promise<FileQuota>;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Tipos comunes compartidos en el SDK
|
|
169
|
+
*/
|
|
170
|
+
type TicketStatus = 'OPEN' | 'IN_REVIEW' | 'RESOLVED' | 'CLOSED';
|
|
171
|
+
type TicketCategory = 'CONSULTA' | 'PROBLEMA' | 'SUGERENCIA' | 'OTRO';
|
|
172
|
+
type TicketPriority = 'BAJA' | 'MEDIA' | 'ALTA' | 'CRITICA';
|
|
173
|
+
interface PaginationMeta {
|
|
174
|
+
page: number;
|
|
175
|
+
limit: number;
|
|
176
|
+
total: number;
|
|
177
|
+
totalPages: number;
|
|
178
|
+
}
|
|
179
|
+
interface PaginatedResponse<T> {
|
|
180
|
+
data: T[];
|
|
181
|
+
pagination: PaginationMeta;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Tipos relacionados con tickets de soporte
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Datos del usuario para crear ticket
|
|
190
|
+
*/
|
|
191
|
+
interface CreateTicketUser {
|
|
192
|
+
/** ID unico del usuario en tu sistema */
|
|
193
|
+
externalId: string;
|
|
194
|
+
/** Email del usuario (opcional) */
|
|
195
|
+
email?: string;
|
|
196
|
+
/** Nombre del usuario (opcional) */
|
|
197
|
+
name?: string;
|
|
198
|
+
/** Metadatos adicionales del usuario (opcional) */
|
|
199
|
+
metadata?: Record<string, unknown>;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Contexto adicional del ticket
|
|
203
|
+
*/
|
|
204
|
+
interface TicketContext {
|
|
205
|
+
/** URL donde se origino el ticket */
|
|
206
|
+
url?: string;
|
|
207
|
+
/** Version de la aplicacion */
|
|
208
|
+
appVersion?: string;
|
|
209
|
+
/** Informacion del navegador */
|
|
210
|
+
browserInfo?: string;
|
|
211
|
+
/** Datos personalizados adicionales */
|
|
212
|
+
customData?: Record<string, unknown>;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* DTO para crear un nuevo ticket
|
|
216
|
+
*/
|
|
217
|
+
interface CreateTicketInput {
|
|
218
|
+
/** Datos del usuario que crea el ticket */
|
|
219
|
+
user: CreateTicketUser;
|
|
220
|
+
/** Titulo del ticket (5-500 caracteres) */
|
|
221
|
+
title: string;
|
|
222
|
+
/** Descripcion detallada (minimo 10 caracteres) */
|
|
223
|
+
description: string;
|
|
224
|
+
/** Categoria del ticket */
|
|
225
|
+
category?: TicketCategory;
|
|
226
|
+
/** Prioridad del ticket */
|
|
227
|
+
priority?: TicketPriority;
|
|
228
|
+
/** Contexto adicional */
|
|
229
|
+
context?: TicketContext;
|
|
230
|
+
/** IDs de archivos adjuntos (previamente subidos) */
|
|
231
|
+
attachmentIds?: string[];
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Filtros para listar tickets
|
|
235
|
+
*/
|
|
236
|
+
interface TicketFilters {
|
|
237
|
+
/** Filtrar por estado */
|
|
238
|
+
status?: TicketStatus;
|
|
239
|
+
/** Pagina actual (default: 1) */
|
|
240
|
+
page?: number;
|
|
241
|
+
/** Elementos por pagina (default: 20, max: 100) */
|
|
242
|
+
limit?: number;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* DTO para agregar un mensaje a un ticket
|
|
246
|
+
*/
|
|
247
|
+
interface AddMessageInput {
|
|
248
|
+
/** Contenido del mensaje (1-5000 caracteres) */
|
|
249
|
+
content: string;
|
|
250
|
+
/** IDs de archivos adjuntos (opcional) */
|
|
251
|
+
attachmentIds?: string[];
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Respuesta al crear un ticket
|
|
255
|
+
*/
|
|
256
|
+
interface CreatedTicket {
|
|
257
|
+
/** ID interno del ticket */
|
|
258
|
+
id: string;
|
|
259
|
+
/** Clave unica del ticket (ej: APP-0001) */
|
|
260
|
+
ticketKey: string;
|
|
261
|
+
/** Titulo del ticket */
|
|
262
|
+
title: string;
|
|
263
|
+
/** Estado inicial */
|
|
264
|
+
status: TicketStatus;
|
|
265
|
+
/** Fecha de creacion */
|
|
266
|
+
createdAt: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Ticket en listado (version resumida)
|
|
270
|
+
*/
|
|
271
|
+
interface TicketListItem {
|
|
272
|
+
id: string;
|
|
273
|
+
ticketKey: string;
|
|
274
|
+
title: string;
|
|
275
|
+
category: TicketCategory;
|
|
276
|
+
priority: TicketPriority;
|
|
277
|
+
status: TicketStatus;
|
|
278
|
+
/** Numero de mensajes no leidos por el usuario externo */
|
|
279
|
+
unreadByExternal: number;
|
|
280
|
+
createdAt: string;
|
|
281
|
+
lastActivityAt: string;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Autor de un mensaje
|
|
285
|
+
*/
|
|
286
|
+
interface MessageAuthor {
|
|
287
|
+
/** Tipo de autor */
|
|
288
|
+
type: 'EXTERNAL' | 'INTERNAL';
|
|
289
|
+
/** ID del autor (externalId o nombre de agente) */
|
|
290
|
+
id: string;
|
|
291
|
+
/** Nombre visible del autor */
|
|
292
|
+
name: string;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Archivo adjunto
|
|
296
|
+
*/
|
|
297
|
+
interface TicketAttachment {
|
|
298
|
+
id: string;
|
|
299
|
+
filename: string;
|
|
300
|
+
mimeType: string;
|
|
301
|
+
size: number;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Mensaje de un ticket
|
|
305
|
+
*/
|
|
306
|
+
interface TicketMessage {
|
|
307
|
+
id: string;
|
|
308
|
+
content: string;
|
|
309
|
+
author: MessageAuthor;
|
|
310
|
+
attachments: TicketAttachment[];
|
|
311
|
+
createdAt: string;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Detalle completo de un ticket
|
|
315
|
+
*/
|
|
316
|
+
interface TicketDetail {
|
|
317
|
+
id: string;
|
|
318
|
+
ticketKey: string;
|
|
319
|
+
title: string;
|
|
320
|
+
description: string;
|
|
321
|
+
category: TicketCategory;
|
|
322
|
+
priority: TicketPriority;
|
|
323
|
+
status: TicketStatus;
|
|
324
|
+
createdAt: string;
|
|
325
|
+
lastActivityAt: string;
|
|
326
|
+
/** Lista de mensajes del ticket */
|
|
327
|
+
messages: TicketMessage[];
|
|
328
|
+
/** Archivos adjuntos del ticket original */
|
|
329
|
+
attachments: TicketAttachment[];
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Respuesta al crear un mensaje
|
|
333
|
+
*/
|
|
334
|
+
interface CreatedMessage {
|
|
335
|
+
id: string;
|
|
336
|
+
content: string;
|
|
337
|
+
createdAt: string;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Conteo de mensajes no leidos
|
|
341
|
+
*/
|
|
342
|
+
interface UnreadCount {
|
|
343
|
+
count: number;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Tipos relacionados con usuarios externos
|
|
348
|
+
*/
|
|
349
|
+
/**
|
|
350
|
+
* DTO para identificar/actualizar un usuario externo
|
|
351
|
+
*/
|
|
352
|
+
interface IdentifyUserInput {
|
|
353
|
+
/** ID unico del usuario en tu sistema (requerido) */
|
|
354
|
+
externalId: string;
|
|
355
|
+
/** Email del usuario */
|
|
356
|
+
email?: string;
|
|
357
|
+
/** Nombre del usuario */
|
|
358
|
+
name?: string;
|
|
359
|
+
/** URL del avatar del usuario */
|
|
360
|
+
avatarUrl?: string;
|
|
361
|
+
/** Metadatos adicionales del usuario */
|
|
362
|
+
metadata?: Record<string, unknown>;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Usuario externo registrado
|
|
366
|
+
*/
|
|
367
|
+
interface ExternalUser {
|
|
368
|
+
/** ID interno en UTILIA OS */
|
|
369
|
+
id: string;
|
|
370
|
+
/** ID de la aplicacion externa */
|
|
371
|
+
appId: string;
|
|
372
|
+
/** ID del usuario en el sistema externo */
|
|
373
|
+
externalId: string;
|
|
374
|
+
/** Email del usuario */
|
|
375
|
+
email?: string | null;
|
|
376
|
+
/** Nombre del usuario */
|
|
377
|
+
name?: string | null;
|
|
378
|
+
/** URL del avatar */
|
|
379
|
+
avatarUrl?: string | null;
|
|
380
|
+
/** Metadatos adicionales */
|
|
381
|
+
metadata?: Record<string, unknown> | null;
|
|
382
|
+
/** Ultima vez que el usuario estuvo activo */
|
|
383
|
+
lastSeenAt: string;
|
|
384
|
+
/** Contadores relacionados */
|
|
385
|
+
_count?: {
|
|
386
|
+
tickets: number;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Servicio de tickets de soporte
|
|
392
|
+
* Maneja todas las operaciones relacionadas con tickets
|
|
393
|
+
*/
|
|
394
|
+
|
|
395
|
+
declare class TicketsService {
|
|
396
|
+
private readonly client;
|
|
397
|
+
private readonly basePath;
|
|
398
|
+
constructor(client: UtiliaClient);
|
|
399
|
+
/**
|
|
400
|
+
* Crear un nuevo ticket de soporte
|
|
401
|
+
*
|
|
402
|
+
* @param data - Datos del ticket a crear
|
|
403
|
+
* @returns Ticket creado con su ID y clave unica
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* ```typescript
|
|
407
|
+
* const ticket = await sdk.tickets.create({
|
|
408
|
+
* user: { externalId: 'user-123', email: 'user@example.com' },
|
|
409
|
+
* title: 'Problema con facturacion',
|
|
410
|
+
* description: 'No puedo ver mis facturas del mes pasado...',
|
|
411
|
+
* category: 'PROBLEMA',
|
|
412
|
+
* priority: 'MEDIA',
|
|
413
|
+
* });
|
|
414
|
+
* console.log(ticket.ticketKey); // APP-0001
|
|
415
|
+
* ```
|
|
416
|
+
*/
|
|
417
|
+
create(data: CreateTicketInput): Promise<CreatedTicket>;
|
|
418
|
+
/**
|
|
419
|
+
* Listar tickets de un usuario
|
|
420
|
+
*
|
|
421
|
+
* @param userId - ID externo del usuario
|
|
422
|
+
* @param filters - Filtros opcionales (status, paginacion)
|
|
423
|
+
* @returns Lista paginada de tickets
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* const result = await sdk.tickets.list('user-123', {
|
|
428
|
+
* status: 'OPEN',
|
|
429
|
+
* page: 1,
|
|
430
|
+
* limit: 10,
|
|
431
|
+
* });
|
|
432
|
+
* console.log(result.data); // Array de tickets
|
|
433
|
+
* console.log(result.pagination.total); // Total de tickets
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
list(userId: string, filters?: TicketFilters): Promise<PaginatedResponse<TicketListItem>>;
|
|
437
|
+
/**
|
|
438
|
+
* Obtener detalle completo de un ticket
|
|
439
|
+
* Incluye todos los mensajes y adjuntos
|
|
440
|
+
*
|
|
441
|
+
* @param ticketId - ID del ticket
|
|
442
|
+
* @param userId - ID externo del usuario (para verificar acceso)
|
|
443
|
+
* @returns Detalle del ticket con mensajes
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```typescript
|
|
447
|
+
* const ticket = await sdk.tickets.get('ticket-uuid', 'user-123');
|
|
448
|
+
* console.log(ticket.messages); // Array de mensajes
|
|
449
|
+
* ```
|
|
450
|
+
*/
|
|
451
|
+
get(ticketId: string, userId: string): Promise<TicketDetail>;
|
|
452
|
+
/**
|
|
453
|
+
* Obtener conteo de mensajes no leidos para un usuario
|
|
454
|
+
*
|
|
455
|
+
* @param userId - ID externo del usuario
|
|
456
|
+
* @returns Numero de mensajes no leidos
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* ```typescript
|
|
460
|
+
* const { count } = await sdk.tickets.getUnreadCount('user-123');
|
|
461
|
+
* if (count > 0) {
|
|
462
|
+
* console.log(`Tienes ${count} mensajes sin leer`);
|
|
463
|
+
* }
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
getUnreadCount(userId: string): Promise<UnreadCount>;
|
|
467
|
+
/**
|
|
468
|
+
* Agregar un mensaje a un ticket existente
|
|
469
|
+
*
|
|
470
|
+
* @param ticketId - ID del ticket
|
|
471
|
+
* @param userId - ID externo del usuario
|
|
472
|
+
* @param data - Contenido del mensaje
|
|
473
|
+
* @returns Mensaje creado
|
|
474
|
+
*
|
|
475
|
+
* @example
|
|
476
|
+
* ```typescript
|
|
477
|
+
* const message = await sdk.tickets.addMessage('ticket-uuid', 'user-123', {
|
|
478
|
+
* content: 'Gracias por la respuesta, el problema ya fue resuelto.',
|
|
479
|
+
* });
|
|
480
|
+
* ```
|
|
481
|
+
*/
|
|
482
|
+
addMessage(ticketId: string, userId: string, data: AddMessageInput): Promise<CreatedMessage>;
|
|
483
|
+
/**
|
|
484
|
+
* Cerrar un ticket
|
|
485
|
+
* Solo el usuario que creo el ticket puede cerrarlo
|
|
486
|
+
*
|
|
487
|
+
* @param ticketId - ID del ticket
|
|
488
|
+
* @param userId - ID externo del usuario
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```typescript
|
|
492
|
+
* await sdk.tickets.close('ticket-uuid', 'user-123');
|
|
493
|
+
* ```
|
|
494
|
+
*/
|
|
495
|
+
close(ticketId: string, userId: string): Promise<void>;
|
|
496
|
+
/**
|
|
497
|
+
* Reabrir un ticket cerrado
|
|
498
|
+
* Solo el usuario que creo el ticket puede reabrirlo
|
|
499
|
+
*
|
|
500
|
+
* @param ticketId - ID del ticket
|
|
501
|
+
* @param userId - ID externo del usuario
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```typescript
|
|
505
|
+
* await sdk.tickets.reopen('ticket-uuid', 'user-123');
|
|
506
|
+
* ```
|
|
507
|
+
*/
|
|
508
|
+
reopen(ticketId: string, userId: string): Promise<void>;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Servicio de usuarios externos
|
|
513
|
+
* Maneja las operaciones relacionadas con usuarios
|
|
514
|
+
*/
|
|
515
|
+
|
|
516
|
+
declare class UsersService {
|
|
517
|
+
private readonly client;
|
|
518
|
+
private readonly basePath;
|
|
519
|
+
constructor(client: UtiliaClient);
|
|
520
|
+
/**
|
|
521
|
+
* Identificar o actualizar un usuario externo
|
|
522
|
+
* Si el usuario ya existe, actualiza sus datos
|
|
523
|
+
* Si no existe, lo crea
|
|
524
|
+
*
|
|
525
|
+
* @param data - Datos del usuario
|
|
526
|
+
* @returns Usuario creado o actualizado
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```typescript
|
|
530
|
+
* const user = await sdk.users.identify({
|
|
531
|
+
* externalId: 'user-123',
|
|
532
|
+
* email: 'user@example.com',
|
|
533
|
+
* name: 'Juan Perez',
|
|
534
|
+
* metadata: {
|
|
535
|
+
* plan: 'premium',
|
|
536
|
+
* company: 'Acme Inc',
|
|
537
|
+
* },
|
|
538
|
+
* });
|
|
539
|
+
* console.log(user.id); // ID interno en UTILIA OS
|
|
540
|
+
* ```
|
|
541
|
+
*/
|
|
542
|
+
identify(data: IdentifyUserInput): Promise<ExternalUser>;
|
|
543
|
+
/**
|
|
544
|
+
* Listar usuarios de la aplicacion
|
|
545
|
+
*
|
|
546
|
+
* @param page - Pagina actual (default: 1)
|
|
547
|
+
* @param limit - Elementos por pagina (default: 20)
|
|
548
|
+
* @returns Lista paginada de usuarios
|
|
549
|
+
*
|
|
550
|
+
* @example
|
|
551
|
+
* ```typescript
|
|
552
|
+
* const result = await sdk.users.list(1, 50);
|
|
553
|
+
* console.log(result.data); // Array de usuarios
|
|
554
|
+
* console.log(result.pagination.total); // Total de usuarios
|
|
555
|
+
* ```
|
|
556
|
+
*/
|
|
557
|
+
list(page?: number, limit?: number): Promise<PaginatedResponse<ExternalUser>>;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Servicio de IA para el SDK de UTILIA OS
|
|
562
|
+
* Proporciona funcionalidades de transcripcion y sugerencias inteligentes
|
|
563
|
+
*/
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Entrada para solicitar sugerencias de IA
|
|
567
|
+
*/
|
|
568
|
+
interface AiSuggestInput {
|
|
569
|
+
/** ID externo del usuario */
|
|
570
|
+
userId: string;
|
|
571
|
+
/** Texto del problema a analizar (opcional si se envia audio) */
|
|
572
|
+
text?: string;
|
|
573
|
+
/** Audio en base64 para transcribir (webm/mp4/mp3/wav) */
|
|
574
|
+
audioBase64?: string;
|
|
575
|
+
/** Nombre del archivo de audio con extension */
|
|
576
|
+
audioFilename?: string;
|
|
577
|
+
/** Campos existentes del formulario para contexto */
|
|
578
|
+
existingFields?: {
|
|
579
|
+
title?: string;
|
|
580
|
+
description?: string;
|
|
581
|
+
category?: string;
|
|
582
|
+
priority?: string;
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Sugerencias generadas por IA
|
|
587
|
+
*/
|
|
588
|
+
interface AiSuggestions {
|
|
589
|
+
/** Titulo sugerido para el ticket */
|
|
590
|
+
title?: string | null;
|
|
591
|
+
/** Descripcion sugerida */
|
|
592
|
+
description?: string | null;
|
|
593
|
+
/** Categoria sugerida (BUG, CONSULTA, SUGERENCIA) */
|
|
594
|
+
category?: string | null;
|
|
595
|
+
/** Prioridad sugerida (BAJA, MEDIA, ALTA, CRITICA) */
|
|
596
|
+
priority?: string | null;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Estado del job de IA
|
|
600
|
+
*/
|
|
601
|
+
interface AiJobStatus {
|
|
602
|
+
/** Estado actual del job */
|
|
603
|
+
status: 'pending' | 'processing' | 'completed' | 'failed' | 'not_found';
|
|
604
|
+
/** Progreso del job (0-100) */
|
|
605
|
+
progress?: number;
|
|
606
|
+
/** Resultado del job (disponible cuando status es 'completed') */
|
|
607
|
+
result?: {
|
|
608
|
+
/** Transcripcion del audio (si se envio audio) */
|
|
609
|
+
transcription?: string;
|
|
610
|
+
/** Sugerencias generadas */
|
|
611
|
+
suggestions?: AiSuggestions;
|
|
612
|
+
};
|
|
613
|
+
/** Mensaje de error (si status es 'failed') */
|
|
614
|
+
error?: string;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Opciones para el metodo getSuggestions con polling
|
|
618
|
+
*/
|
|
619
|
+
interface GetSuggestionsOptions {
|
|
620
|
+
/** Intervalo de polling en ms (default: 1000) */
|
|
621
|
+
pollInterval?: number;
|
|
622
|
+
/** Tiempo maximo de espera en ms (default: 60000) */
|
|
623
|
+
maxWait?: number;
|
|
624
|
+
/** Callback para reportar progreso */
|
|
625
|
+
onProgress?: (progress: number) => void;
|
|
626
|
+
}
|
|
627
|
+
declare class AiService {
|
|
628
|
+
private readonly client;
|
|
629
|
+
private readonly basePath;
|
|
630
|
+
constructor(client: UtiliaClient);
|
|
631
|
+
/**
|
|
632
|
+
* Solicita sugerencias de IA de forma asincrona.
|
|
633
|
+
* Retorna un jobId que se puede usar para consultar el estado.
|
|
634
|
+
*
|
|
635
|
+
* @param data - Datos para generar sugerencias
|
|
636
|
+
* @returns ID del job para consultar estado
|
|
637
|
+
*
|
|
638
|
+
* @example
|
|
639
|
+
* ```typescript
|
|
640
|
+
* // Con texto
|
|
641
|
+
* const { jobId } = await sdk.ai.requestSuggestions({
|
|
642
|
+
* userId: 'user-123',
|
|
643
|
+
* text: 'No puedo iniciar sesion en la aplicacion',
|
|
644
|
+
* });
|
|
645
|
+
*
|
|
646
|
+
* // Con audio
|
|
647
|
+
* const { jobId } = await sdk.ai.requestSuggestions({
|
|
648
|
+
* userId: 'user-123',
|
|
649
|
+
* audioBase64: '...',
|
|
650
|
+
* audioFilename: 'recording.webm',
|
|
651
|
+
* });
|
|
652
|
+
* ```
|
|
653
|
+
*/
|
|
654
|
+
requestSuggestions(data: AiSuggestInput): Promise<{
|
|
655
|
+
jobId: string;
|
|
656
|
+
}>;
|
|
657
|
+
/**
|
|
658
|
+
* Obtiene el estado de un job de sugerencias
|
|
659
|
+
*
|
|
660
|
+
* @param jobId - ID del job obtenido de requestSuggestions
|
|
661
|
+
* @returns Estado actual del job
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* ```typescript
|
|
665
|
+
* const status = await sdk.ai.getSuggestionsStatus(jobId);
|
|
666
|
+
*
|
|
667
|
+
* if (status.status === 'completed') {
|
|
668
|
+
* console.log(status.result?.suggestions);
|
|
669
|
+
* }
|
|
670
|
+
* ```
|
|
671
|
+
*/
|
|
672
|
+
getSuggestionsStatus(jobId: string): Promise<AiJobStatus>;
|
|
673
|
+
/**
|
|
674
|
+
* Transcribe audio a texto de forma sincrona.
|
|
675
|
+
* Usar solo para audios cortos (<30 segundos).
|
|
676
|
+
*
|
|
677
|
+
* @param audioBase64 - Audio codificado en base64
|
|
678
|
+
* @param audioFilename - Nombre del archivo con extension
|
|
679
|
+
* @returns Texto transcrito
|
|
680
|
+
*
|
|
681
|
+
* @example
|
|
682
|
+
* ```typescript
|
|
683
|
+
* const { transcription } = await sdk.ai.transcribe(
|
|
684
|
+
* audioBase64,
|
|
685
|
+
* 'recording.webm'
|
|
686
|
+
* );
|
|
687
|
+
* console.log(transcription);
|
|
688
|
+
* ```
|
|
689
|
+
*/
|
|
690
|
+
transcribe(audioBase64: string, audioFilename: string): Promise<{
|
|
691
|
+
transcription: string;
|
|
692
|
+
}>;
|
|
693
|
+
/**
|
|
694
|
+
* Metodo helper que solicita sugerencias y espera el resultado.
|
|
695
|
+
* Implementa polling automatico hasta que el job complete o falle.
|
|
696
|
+
*
|
|
697
|
+
* @param data - Datos para generar sugerencias
|
|
698
|
+
* @param options - Opciones de polling
|
|
699
|
+
* @returns Resultado con sugerencias y transcripcion (si aplica)
|
|
700
|
+
* @throws Error si el job falla o excede el timeout
|
|
701
|
+
*
|
|
702
|
+
* @example
|
|
703
|
+
* ```typescript
|
|
704
|
+
* // Uso simple
|
|
705
|
+
* const result = await sdk.ai.getSuggestions({
|
|
706
|
+
* userId: 'user-123',
|
|
707
|
+
* text: 'No puedo ver mis facturas del mes pasado',
|
|
708
|
+
* });
|
|
709
|
+
* console.log(result?.suggestions);
|
|
710
|
+
*
|
|
711
|
+
* // Con progreso
|
|
712
|
+
* const result = await sdk.ai.getSuggestions(
|
|
713
|
+
* { userId: 'user-123', audioBase64: '...', audioFilename: 'rec.webm' },
|
|
714
|
+
* {
|
|
715
|
+
* pollInterval: 500,
|
|
716
|
+
* maxWait: 30000,
|
|
717
|
+
* onProgress: (p) => console.log(`Progreso: ${p}%`),
|
|
718
|
+
* }
|
|
719
|
+
* );
|
|
720
|
+
* ```
|
|
721
|
+
*/
|
|
722
|
+
getSuggestions(data: AiSuggestInput, options?: GetSuggestionsOptions): Promise<AiJobStatus['result']>;
|
|
723
|
+
/**
|
|
724
|
+
* Helper para esperar un tiempo
|
|
725
|
+
*/
|
|
726
|
+
private sleep;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Codigos de error del SDK
|
|
731
|
+
*/
|
|
732
|
+
declare enum ErrorCode {
|
|
733
|
+
/** API Key invalida o faltante */
|
|
734
|
+
UNAUTHORIZED = "UNAUTHORIZED",
|
|
735
|
+
/** Acceso denegado (app desactivada, CORS, etc) */
|
|
736
|
+
FORBIDDEN = "FORBIDDEN",
|
|
737
|
+
/** Recurso no encontrado */
|
|
738
|
+
NOT_FOUND = "NOT_FOUND",
|
|
739
|
+
/** Rate limit excedido */
|
|
740
|
+
RATE_LIMITED = "RATE_LIMITED",
|
|
741
|
+
/** Error de validacion en los datos enviados */
|
|
742
|
+
VALIDATION_ERROR = "VALIDATION_ERROR",
|
|
743
|
+
/** Error de conexion de red */
|
|
744
|
+
NETWORK_ERROR = "NETWORK_ERROR",
|
|
745
|
+
/** Error desconocido */
|
|
746
|
+
UNKNOWN = "UNKNOWN"
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Clase de error personalizada del SDK
|
|
750
|
+
* Permite identificar el tipo de error y tomar acciones apropiadas
|
|
751
|
+
*/
|
|
752
|
+
declare class UtiliaSDKError extends Error {
|
|
753
|
+
/** Codigo del error para identificar el tipo */
|
|
754
|
+
readonly code: ErrorCode;
|
|
755
|
+
/** Timestamp de cuando ocurrio el error */
|
|
756
|
+
readonly timestamp: Date;
|
|
757
|
+
constructor(code: ErrorCode, message: string);
|
|
758
|
+
/**
|
|
759
|
+
* Serializa el error a un objeto JSON
|
|
760
|
+
*/
|
|
761
|
+
toJSON(): {
|
|
762
|
+
name: string;
|
|
763
|
+
code: ErrorCode;
|
|
764
|
+
message: string;
|
|
765
|
+
timestamp: string;
|
|
766
|
+
};
|
|
767
|
+
/**
|
|
768
|
+
* Verifica si el error es de tipo rate limit
|
|
769
|
+
*/
|
|
770
|
+
isRateLimited(): boolean;
|
|
771
|
+
/**
|
|
772
|
+
* Verifica si el error es de autenticacion
|
|
773
|
+
*/
|
|
774
|
+
isUnauthorized(): boolean;
|
|
775
|
+
/**
|
|
776
|
+
* Verifica si el error es recuperable (se puede reintentar)
|
|
777
|
+
*/
|
|
778
|
+
isRetryable(): boolean;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* Constantes y limites del SDK
|
|
783
|
+
*/
|
|
784
|
+
declare const SDK_LIMITS: {
|
|
785
|
+
readonly TICKET_TITLE_MIN: 5;
|
|
786
|
+
readonly TICKET_TITLE_MAX: 500;
|
|
787
|
+
readonly TICKET_DESCRIPTION_MIN: 10;
|
|
788
|
+
readonly MESSAGE_CONTENT_MIN: 1;
|
|
789
|
+
readonly MESSAGE_CONTENT_MAX: 5000;
|
|
790
|
+
readonly FILE_NAME_MAX: 255;
|
|
791
|
+
readonly EXTERNAL_ID_MAX: 255;
|
|
792
|
+
readonly AVATAR_URL_MAX: 2048;
|
|
793
|
+
};
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* UTILIA OS SDK
|
|
797
|
+
*
|
|
798
|
+
* SDK JavaScript/TypeScript para integrar aplicaciones externas
|
|
799
|
+
* con el sistema de soporte de UTILIA OS.
|
|
800
|
+
*
|
|
801
|
+
* @example
|
|
802
|
+
* ```typescript
|
|
803
|
+
* import { UtiliaSDK } from '@utilia-os/sdk-js';
|
|
804
|
+
*
|
|
805
|
+
* const sdk = new UtiliaSDK({
|
|
806
|
+
* baseURL: 'https://os.utilia.ai/api',
|
|
807
|
+
* apiKey: 'tu-api-key',
|
|
808
|
+
* });
|
|
809
|
+
*
|
|
810
|
+
* // Identificar usuario
|
|
811
|
+
* const user = await sdk.users.identify({
|
|
812
|
+
* externalId: 'user-123',
|
|
813
|
+
* email: 'user@example.com',
|
|
814
|
+
* });
|
|
815
|
+
*
|
|
816
|
+
* // Crear ticket
|
|
817
|
+
* const ticket = await sdk.tickets.create({
|
|
818
|
+
* user: { externalId: 'user-123' },
|
|
819
|
+
* title: 'Problema con facturacion',
|
|
820
|
+
* description: 'No puedo ver mis facturas...',
|
|
821
|
+
* });
|
|
822
|
+
* ```
|
|
823
|
+
*
|
|
824
|
+
* @packageDocumentation
|
|
825
|
+
*/
|
|
826
|
+
|
|
827
|
+
/**
|
|
828
|
+
* Clase principal del SDK de UTILIA OS
|
|
829
|
+
*
|
|
830
|
+
* Proporciona acceso a todos los servicios disponibles:
|
|
831
|
+
* - `files`: Operaciones con archivos adjuntos
|
|
832
|
+
* - `tickets`: Operaciones con tickets de soporte
|
|
833
|
+
* - `users`: Operaciones con usuarios externos
|
|
834
|
+
* - `ai`: Funcionalidades de IA (transcripcion, sugerencias)
|
|
835
|
+
*/
|
|
836
|
+
declare class UtiliaSDK {
|
|
837
|
+
/** Servicio de archivos adjuntos */
|
|
838
|
+
readonly files: FilesService;
|
|
839
|
+
/** Servicio de tickets de soporte */
|
|
840
|
+
readonly tickets: TicketsService;
|
|
841
|
+
/** Servicio de usuarios externos */
|
|
842
|
+
readonly users: UsersService;
|
|
843
|
+
/** Servicio de IA para transcripcion y sugerencias */
|
|
844
|
+
readonly ai: AiService;
|
|
845
|
+
/**
|
|
846
|
+
* Crea una nueva instancia del SDK
|
|
847
|
+
*
|
|
848
|
+
* @param config - Configuracion del SDK
|
|
849
|
+
*
|
|
850
|
+
* @example
|
|
851
|
+
* ```typescript
|
|
852
|
+
* const sdk = new UtiliaSDK({
|
|
853
|
+
* baseURL: 'https://os.utilia.ai/api',
|
|
854
|
+
* apiKey: 'tu-api-key',
|
|
855
|
+
* timeout: 30000, // opcional
|
|
856
|
+
* debug: true, // opcional, habilita logs
|
|
857
|
+
* });
|
|
858
|
+
*
|
|
859
|
+
* // Subir archivo y crear ticket con adjunto
|
|
860
|
+
* const file = await sdk.files.upload(inputFile);
|
|
861
|
+
* const ticket = await sdk.tickets.create({
|
|
862
|
+
* user: { externalId: 'user-123' },
|
|
863
|
+
* title: 'Problema con facturacion',
|
|
864
|
+
* description: 'No puedo ver mis facturas...',
|
|
865
|
+
* attachmentIds: [file.id],
|
|
866
|
+
* });
|
|
867
|
+
* ```
|
|
868
|
+
*/
|
|
869
|
+
constructor(config: UtiliaSDKConfig);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
export { type AddMessageInput, type AiJobStatus, type AiSuggestInput, type AiSuggestions, type CreateTicketInput, type CreateTicketUser, type CreatedMessage, type CreatedTicket, ErrorCode, type ExternalUser, type FileQuota, type GetSuggestionsOptions, type IdentifyUserInput, type MessageAuthor, type PaginatedResponse, type PaginationMeta, type RequestConfig, SDK_LIMITS, type TicketAttachment, type TicketCategory, type TicketContext, type TicketDetail, type TicketFilters, type TicketListItem, type TicketMessage, type TicketPriority, type TicketStatus, type UnreadCount, type UploadFileOptions, type UploadedFile, UtiliaSDK, type UtiliaSDKConfig, UtiliaSDKError };
|