@whitewall/blip-sdk 0.0.173 → 0.0.175

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.
Files changed (131) hide show
  1. package/README.md +13 -6
  2. package/dist/cjs/client.js +3 -0
  3. package/dist/cjs/client.js.map +1 -1
  4. package/dist/cjs/index.js +3 -0
  5. package/dist/cjs/index.js.map +1 -1
  6. package/dist/cjs/namespaces/account.js +23 -11
  7. package/dist/cjs/namespaces/account.js.map +1 -1
  8. package/dist/cjs/namespaces/analytics.js +54 -0
  9. package/dist/cjs/namespaces/analytics.js.map +1 -1
  10. package/dist/cjs/namespaces/desk.js +264 -45
  11. package/dist/cjs/namespaces/desk.js.map +1 -1
  12. package/dist/cjs/namespaces/plugins.js +1 -0
  13. package/dist/cjs/namespaces/plugins.js.map +1 -1
  14. package/dist/cjs/namespaces/portal.js +45 -0
  15. package/dist/cjs/namespaces/portal.js.map +1 -1
  16. package/dist/cjs/namespaces/tunnel.js +46 -0
  17. package/dist/cjs/namespaces/tunnel.js.map +1 -0
  18. package/dist/cjs/namespaces/whatsapp.js +2 -23
  19. package/dist/cjs/namespaces/whatsapp.js.map +1 -1
  20. package/dist/cjs/sender/multi/multisender.js +28 -9
  21. package/dist/cjs/sender/multi/multisender.js.map +1 -1
  22. package/dist/cjs/sender/sessionnegotiator.js +1 -1
  23. package/dist/cjs/sender/sessionnegotiator.js.map +1 -1
  24. package/dist/cjs/sender/tcp/tcpsender.js +35 -2
  25. package/dist/cjs/sender/tcp/tcpsender.js.map +1 -1
  26. package/dist/cjs/sender/websocket/websocketsender.js +1 -1
  27. package/dist/cjs/sender/websocket/websocketsender.js.map +1 -1
  28. package/dist/cjs/types/desk.js.map +1 -1
  29. package/dist/cjs/types/flow.js +344 -0
  30. package/dist/cjs/types/flow.js.map +1 -1
  31. package/dist/cjs/utils/desk.js +65 -0
  32. package/dist/cjs/utils/desk.js.map +1 -0
  33. package/dist/cjs/utils/thread.js +84 -0
  34. package/dist/cjs/utils/thread.js.map +1 -0
  35. package/dist/cjs/utils/whatsapp.js +268 -0
  36. package/dist/cjs/utils/whatsapp.js.map +1 -0
  37. package/dist/esm/client.js +3 -0
  38. package/dist/esm/client.js.map +1 -1
  39. package/dist/esm/index.js +3 -0
  40. package/dist/esm/index.js.map +1 -1
  41. package/dist/esm/namespaces/account.js +19 -10
  42. package/dist/esm/namespaces/account.js.map +1 -1
  43. package/dist/esm/namespaces/analytics.js +54 -0
  44. package/dist/esm/namespaces/analytics.js.map +1 -1
  45. package/dist/esm/namespaces/desk.js +264 -45
  46. package/dist/esm/namespaces/desk.js.map +1 -1
  47. package/dist/esm/namespaces/plugins.js +1 -0
  48. package/dist/esm/namespaces/plugins.js.map +1 -1
  49. package/dist/esm/namespaces/portal.js +45 -0
  50. package/dist/esm/namespaces/portal.js.map +1 -1
  51. package/dist/esm/namespaces/tunnel.js +42 -0
  52. package/dist/esm/namespaces/tunnel.js.map +1 -0
  53. package/dist/esm/namespaces/whatsapp.js +2 -23
  54. package/dist/esm/namespaces/whatsapp.js.map +1 -1
  55. package/dist/esm/sender/multi/multisender.js +28 -9
  56. package/dist/esm/sender/multi/multisender.js.map +1 -1
  57. package/dist/esm/sender/sessionnegotiator.js +1 -1
  58. package/dist/esm/sender/sessionnegotiator.js.map +1 -1
  59. package/dist/esm/sender/tcp/tcpsender.js +1 -1
  60. package/dist/esm/sender/tcp/tcpsender.js.map +1 -1
  61. package/dist/esm/sender/websocket/websocketsender.js +1 -1
  62. package/dist/esm/sender/websocket/websocketsender.js.map +1 -1
  63. package/dist/esm/types/desk.js.map +1 -1
  64. package/dist/esm/types/flow.js +343 -1
  65. package/dist/esm/types/flow.js.map +1 -1
  66. package/dist/esm/utils/desk.js +59 -0
  67. package/dist/esm/utils/desk.js.map +1 -0
  68. package/dist/esm/utils/thread.js +80 -0
  69. package/dist/esm/utils/thread.js.map +1 -0
  70. package/dist/esm/utils/whatsapp.js +263 -0
  71. package/dist/esm/utils/whatsapp.js.map +1 -0
  72. package/dist/types/client.d.ts +2 -0
  73. package/dist/types/client.d.ts.map +1 -1
  74. package/dist/types/index.d.ts +3 -0
  75. package/dist/types/index.d.ts.map +1 -1
  76. package/dist/types/namespaces/account.d.ts +1791 -3
  77. package/dist/types/namespaces/account.d.ts.map +1 -1
  78. package/dist/types/namespaces/analytics.d.ts +60 -0
  79. package/dist/types/namespaces/analytics.d.ts.map +1 -1
  80. package/dist/types/namespaces/desk.d.ts +124 -4
  81. package/dist/types/namespaces/desk.d.ts.map +1 -1
  82. package/dist/types/namespaces/plugins.d.ts +1 -0
  83. package/dist/types/namespaces/plugins.d.ts.map +1 -1
  84. package/dist/types/namespaces/portal.d.ts +45 -0
  85. package/dist/types/namespaces/portal.d.ts.map +1 -1
  86. package/dist/types/namespaces/tunnel.d.ts +28 -0
  87. package/dist/types/namespaces/tunnel.d.ts.map +1 -0
  88. package/dist/types/namespaces/whatsapp.d.ts +3 -2
  89. package/dist/types/namespaces/whatsapp.d.ts.map +1 -1
  90. package/dist/types/schemas/webhook.d.ts +2 -2
  91. package/dist/types/sender/gateway/customgatewaysender.d.ts +1 -1
  92. package/dist/types/sender/http/httpsender.d.ts +1 -1
  93. package/dist/types/sender/multi/multisender.d.ts +1 -0
  94. package/dist/types/sender/multi/multisender.d.ts.map +1 -1
  95. package/dist/types/sender/sender.d.ts +1 -1
  96. package/dist/types/sender/tcp/tcpsender.d.ts +1 -1
  97. package/dist/types/sender/websocket/websocketsender.d.ts +1 -1
  98. package/dist/types/types/desk.d.ts +57 -1
  99. package/dist/types/types/desk.d.ts.map +1 -1
  100. package/dist/types/types/flow.d.ts +3269 -142
  101. package/dist/types/types/flow.d.ts.map +1 -1
  102. package/dist/types/types/message.d.ts +1 -1
  103. package/dist/types/types/whatsapp.d.ts +10 -2
  104. package/dist/types/types/whatsapp.d.ts.map +1 -1
  105. package/dist/types/utils/desk.d.ts +6 -0
  106. package/dist/types/utils/desk.d.ts.map +1 -0
  107. package/dist/types/utils/thread.d.ts +4 -0
  108. package/dist/types/utils/thread.d.ts.map +1 -0
  109. package/dist/types/utils/whatsapp.d.ts +103 -0
  110. package/dist/types/utils/whatsapp.d.ts.map +1 -0
  111. package/package.json +8 -11
  112. package/src/client.ts +3 -0
  113. package/src/index.ts +3 -0
  114. package/src/namespaces/account.ts +27 -13
  115. package/src/namespaces/analytics.ts +154 -0
  116. package/src/namespaces/desk.ts +428 -77
  117. package/src/namespaces/plugins.ts +2 -0
  118. package/src/namespaces/portal.ts +110 -0
  119. package/src/namespaces/tunnel.ts +58 -0
  120. package/src/namespaces/whatsapp.ts +4 -39
  121. package/src/sender/multi/multisender.ts +38 -14
  122. package/src/sender/sessionnegotiator.ts +1 -1
  123. package/src/sender/tcp/tcpsender.ts +1 -1
  124. package/src/sender/websocket/websocketsender.ts +1 -1
  125. package/src/types/desk.ts +66 -1
  126. package/src/types/flow.ts +387 -246
  127. package/src/types/message.ts +1 -1
  128. package/src/types/whatsapp.ts +11 -2
  129. package/src/utils/desk.ts +78 -0
  130. package/src/utils/thread.ts +119 -0
  131. package/src/utils/whatsapp.ts +530 -0
@@ -2,6 +2,9 @@ import type { BlipClient } from '../client.ts'
2
2
  import { BlipError } from '../sender/bliperror.ts'
3
3
  import {
4
4
  type AttendanceHour,
5
+ type DeskAttendanceQueue,
6
+ type DeskPriorityRule,
7
+ type DeskRule,
5
8
  type DetailedAttendanceHour,
6
9
  type Identity,
7
10
  Node,
@@ -10,6 +13,10 @@ import {
10
13
  type TicketStatus,
11
14
  } from '../types/index.ts'
12
15
  import type { WhatsAppTemplateLanguage } from '../types/whatsapp.ts'
16
+ import {
17
+ isOnAttendanceTime as isDetailedAttendanceHourOnAttendanceTime,
18
+ matchesAttendanceHourQueue,
19
+ } from '../utils/desk.ts'
13
20
  import type { ODataFilter } from '../utils/odata.ts'
14
21
  import { uri } from '../utils/uri.ts'
15
22
  import { type ConsumeOptions, Namespace, type SendCommandOptions } from './namespace.ts'
@@ -69,23 +76,31 @@ export class DeskNamespace extends Namespace {
69
76
  .filter((item) => !ticket.closeDate || new Date(item.date) <= new Date(ticket.closeDate))
70
77
  }
71
78
 
72
- public async getTicketsMetrics(opts?: ConsumeOptions): Promise<{
73
- maxQueueTime: string
74
- maxFirstResponseTime: string
75
- avgQueueTime: string
76
- avgFirstResponseTime: string
77
- avgWaitTime: string
78
- avgResponseTime: string
79
- avgAttendanceTime: string
80
- ticketsPerAttendant: number
81
- }> {
82
- return await this.sendCommand(
79
+ public async getTicketsMetrics(opts?: ConsumeOptions) {
80
+ const metrics = await this.sendCommand<
81
+ 'get',
82
+ {
83
+ maxQueueTime: string
84
+ maxFirstResponseTime: string
85
+ avgQueueTime: string
86
+ avgFirstResponseTime: string
87
+ avgWaitTime: string
88
+ avgResponseTime: string
89
+ avgAttendanceTime: string
90
+ ticketsPerAttendant: number
91
+ }
92
+ >(
83
93
  {
84
94
  method: 'get',
85
95
  uri: uri`/monitoring/ticket-metrics?${{ version: 2 }}`,
86
96
  },
87
97
  opts,
88
98
  )
99
+
100
+ return {
101
+ ...metrics,
102
+ ticketsPerAttendant: Number(metrics.ticketsPerAttendant),
103
+ }
89
104
  }
90
105
 
91
106
  public async getWaitingTicketsMetrics(
@@ -126,6 +141,318 @@ export class DeskNamespace extends Namespace {
126
141
  )
127
142
  }
128
143
 
144
+ /** @param filters.filter - Optional OData filter applied by the Desk backend when listing queues. */
145
+ public async getQueues(
146
+ filters?: {
147
+ filter?: ODataFilter<DeskAttendanceQueue>
148
+ },
149
+ opts?: ConsumeOptions,
150
+ ): Promise<Array<DeskAttendanceQueue>> {
151
+ return await this.sendCommand(
152
+ {
153
+ method: 'get',
154
+ uri: uri`/attendance-queues?${{
155
+ $filter: filters?.filter?.toString(),
156
+ }}`,
157
+ },
158
+ {
159
+ collection: true,
160
+ ...opts,
161
+ },
162
+ )
163
+ }
164
+
165
+ public async getQueue(queueId: string, opts?: ConsumeOptions): Promise<DeskAttendanceQueue> {
166
+ return await this.sendCommand(
167
+ {
168
+ method: 'get',
169
+ uri: uri`/attendance-queues/${queueId}`,
170
+ },
171
+ opts,
172
+ )
173
+ }
174
+
175
+ public async getQueueByName(queueName: string, opts?: ConsumeOptions): Promise<DeskAttendanceQueue> {
176
+ return await this.sendCommand(
177
+ {
178
+ method: 'get',
179
+ uri: uri`/attendance-queues/name/${queueName}`,
180
+ },
181
+ opts,
182
+ )
183
+ }
184
+
185
+ /**
186
+ * @param queue.id - Optional queue id. If omitted, Iris generates one from `uniqueId`.
187
+ * @param queue.ownerIdentity - Optional owner identity. Iris usually infers it from the command context.
188
+ * @param queue.name - Queue display name.
189
+ * @param queue.isActive - Whether the queue should accept new tickets.
190
+ * @param queue.storageDate - Optional original creation date for updates.
191
+ * @param queue.Priority - Optional queue ordering priority.
192
+ * @param queue.uniqueId - Optional queue unique id. Iris generates one when missing.
193
+ * @param queue.attendanceHourId - Optional attendance hour id linked to this queue.
194
+ */
195
+ public async setQueue(queue: DeskAttendanceQueue, opts?: ConsumeOptions): Promise<DeskAttendanceQueue> {
196
+ return await this.sendCommand(
197
+ {
198
+ method: 'set',
199
+ uri: uri`/attendance-queues`,
200
+ type: 'application/vnd.iris.desk.attendancequeue+json',
201
+ resource: queue,
202
+ },
203
+ opts,
204
+ )
205
+ }
206
+
207
+ public async deleteQueue(queueId: string, opts?: ConsumeOptions): Promise<void> {
208
+ return await this.sendCommand(
209
+ {
210
+ method: 'delete',
211
+ uri: uri`/attendance-queues/${queueId}`,
212
+ },
213
+ opts,
214
+ )
215
+ }
216
+
217
+ /** @param filters.filter - Optional OData filter applied to the stored rules. */
218
+ public async getRules(
219
+ filters?: {
220
+ filter?: ODataFilter<DeskRule>
221
+ },
222
+ opts?: ConsumeOptions,
223
+ ): Promise<Array<DeskRule>> {
224
+ return await this.sendCommand(
225
+ {
226
+ method: 'get',
227
+ uri: uri`/rules?${{
228
+ $filter: filters?.filter?.toString(),
229
+ }}`,
230
+ },
231
+ {
232
+ collection: true,
233
+ ...opts,
234
+ },
235
+ )
236
+ }
237
+
238
+ public async getRule(ruleId: string, opts?: ConsumeOptions): Promise<DeskRule> {
239
+ return await this.sendCommand(
240
+ {
241
+ method: 'get',
242
+ uri: uri`/rules/${ruleId}`,
243
+ },
244
+ opts,
245
+ )
246
+ }
247
+
248
+ /**
249
+ * @param queue - Queue selector used by `/rules/queue/{queue}`. Iris matches this value against the rule `team` field.
250
+ * @param filters.filter - Optional OData filter applied after the queue selector.
251
+ */
252
+ public async getRulesByQueue(
253
+ queue: string,
254
+ filters?: {
255
+ filter?: ODataFilter<DeskRule>
256
+ },
257
+ opts?: ConsumeOptions,
258
+ ): Promise<Array<DeskRule>> {
259
+ return await this.sendCommand(
260
+ {
261
+ method: 'get',
262
+ uri: uri`/rules/queue/${queue}?${{
263
+ $filter: filters?.filter?.toString(),
264
+ }}`,
265
+ },
266
+ {
267
+ collection: true,
268
+ ...opts,
269
+ },
270
+ )
271
+ }
272
+
273
+ /**
274
+ * @param rule.id - Optional existing rule id.
275
+ * @param rule.ownerIdentity - Optional owner identity override.
276
+ * @param rule.title - Rule display name.
277
+ * @param rule.team - Queue name that receives matching tickets.
278
+ * @param rule.property - Legacy single-condition property. Prefer `conditions`.
279
+ * @param rule.relation - Legacy single-condition relation. Prefer `conditions`.
280
+ * @param rule.isActive - Whether the rule can be applied to new tickets.
281
+ * @param rule.values - Legacy single-condition values. Prefer `conditions`.
282
+ * @param rule.conditions - Preferred list of rule conditions evaluated by Iris.
283
+ * @param rule.operator - Logical operator used between `conditions`.
284
+ * @param rule.priority - Optional explicit processing order.
285
+ * @param rule.storageDate - Optional original creation date for updates.
286
+ * @param rule.queueId - Optional queue unique id. When omitted, Iris resolves it from `team`.
287
+ */
288
+ public async setRule(rule: DeskRule, opts?: ConsumeOptions): Promise<void> {
289
+ return await this.sendCommand(
290
+ {
291
+ method: 'set',
292
+ uri: uri`/rules`,
293
+ type: 'application/vnd.iris.desk.rule+json',
294
+ resource: rule,
295
+ },
296
+ opts,
297
+ )
298
+ }
299
+
300
+ public async deleteRule(ruleId: string, opts?: ConsumeOptions): Promise<void> {
301
+ return await this.sendCommand(
302
+ {
303
+ method: 'delete',
304
+ uri: uri`/rules/${ruleId}`,
305
+ },
306
+ opts,
307
+ )
308
+ }
309
+
310
+ public async getPriorityRules(opts?: ConsumeOptions): Promise<Array<DeskPriorityRule>> {
311
+ return await this.sendCommand(
312
+ {
313
+ method: 'get',
314
+ uri: uri`/priority-rules`,
315
+ },
316
+ {
317
+ collection: true,
318
+ ...opts,
319
+ },
320
+ )
321
+ }
322
+
323
+ public async getPriorityRule(ruleId: string, opts?: ConsumeOptions): Promise<DeskPriorityRule> {
324
+ return await this.sendCommand(
325
+ {
326
+ method: 'get',
327
+ uri: uri`/priority-rules/${ruleId}`,
328
+ },
329
+ opts,
330
+ )
331
+ }
332
+
333
+ /**
334
+ * @param queueId - Queue unique id used by the priority rule engine.
335
+ * @param filters.filter - Optional OData filter applied after the queue selector.
336
+ */
337
+ public async getPriorityRulesByQueue(
338
+ queueId: string,
339
+ filters?: {
340
+ filter?: ODataFilter<DeskPriorityRule>
341
+ },
342
+ opts?: ConsumeOptions,
343
+ ): Promise<Array<DeskPriorityRule>> {
344
+ return await this.sendCommand(
345
+ {
346
+ method: 'get',
347
+ uri: uri`/priority-rules/queue/${queueId}?${{
348
+ $filter: filters?.filter?.toString(),
349
+ }}`,
350
+ },
351
+ {
352
+ collection: true,
353
+ ...opts,
354
+ },
355
+ )
356
+ }
357
+
358
+ /**
359
+ * @param rule.id - Optional existing rule id. Iris generates one when missing.
360
+ * @param rule.ownerIdentity - Optional owner identity override.
361
+ * @param rule.title - Rule display name.
362
+ * @param rule.queueId - Queue unique id that receives the urgency.
363
+ * @param rule.isActive - Whether the rule can be applied to new tickets.
364
+ * @param rule.conditions - Conditions evaluated when `applyConditions` is true.
365
+ * @param rule.operator - Logical operator used between `conditions`.
366
+ * @param rule.priority - Optional explicit processing order.
367
+ * @param rule.urgency - Priority boost applied to matching tickets.
368
+ * @param rule.applyConditions - When false, Iris applies the rule without evaluating `conditions`.
369
+ * @param rule.storageDate - Optional original creation date for updates.
370
+ */
371
+ public async setPriorityRule(rule: DeskPriorityRule, opts?: ConsumeOptions): Promise<void> {
372
+ return await this.sendCommand(
373
+ {
374
+ method: 'set',
375
+ uri: uri`/priority-rules`,
376
+ type: 'application/vnd.iris.desk.priority-rules+json',
377
+ resource: rule,
378
+ },
379
+ opts,
380
+ )
381
+ }
382
+
383
+ public async deletePriorityRule(ruleId: string, opts?: ConsumeOptions): Promise<void> {
384
+ return await this.sendCommand(
385
+ {
386
+ method: 'delete',
387
+ uri: uri`/priority-rules/${ruleId}`,
388
+ },
389
+ opts,
390
+ )
391
+ }
392
+
393
+ /** @param filters.filter - Optional OData filter applied to the attendance-hour summary list. */
394
+ public async getAttendanceHours(
395
+ filters?: {
396
+ filter?: ODataFilter<AttendanceHour>
397
+ },
398
+ opts?: ConsumeOptions,
399
+ ): Promise<Array<AttendanceHour>> {
400
+ return await this.sendCommand(
401
+ {
402
+ method: 'get',
403
+ uri: uri`/attendance-hour?${{
404
+ $filter: filters?.filter?.toString(),
405
+ }}`,
406
+ },
407
+ {
408
+ collection: true,
409
+ ...opts,
410
+ },
411
+ )
412
+ }
413
+
414
+ public async getAttendanceHourContainer(
415
+ attendanceHourId: string,
416
+ opts?: ConsumeOptions,
417
+ ): Promise<DetailedAttendanceHour> {
418
+ return await this.sendCommand(
419
+ {
420
+ method: 'get',
421
+ uri: uri`/attendance-hour-container/${attendanceHourId}`,
422
+ },
423
+ opts,
424
+ )
425
+ }
426
+
427
+ /**
428
+ * @param attendanceHour.attendanceHour - Summary fields for the attendance hour itself.
429
+ * @param attendanceHour.attendanceHourScheduleItems - Required weekly schedules for the attendance hour.
430
+ * @param attendanceHour.attendanceHourOffItems - Optional date ranges where attendance is suspended.
431
+ * @param attendanceHour.queues - Queue ids linked to this attendance hour.
432
+ * @param attendanceHour.attendants - Agent identities linked to this attendance hour.
433
+ */
434
+ public async setAttendanceHour(attendanceHour: DetailedAttendanceHour, opts?: ConsumeOptions): Promise<void> {
435
+ return await this.sendCommand(
436
+ {
437
+ method: 'set',
438
+ uri: uri`/attendance-hour`,
439
+ type: 'application/vnd.iris.desk.attendance-hour-container+json',
440
+ resource: attendanceHour,
441
+ },
442
+ opts,
443
+ )
444
+ }
445
+
446
+ public async deleteAttendanceHour(attendanceHourId: string, opts?: ConsumeOptions): Promise<void> {
447
+ return await this.sendCommand(
448
+ {
449
+ method: 'delete',
450
+ uri: uri`/attendance-hour/${attendanceHourId}`,
451
+ },
452
+ opts,
453
+ )
454
+ }
455
+
129
456
  public async getTickets(filter?: ODataFilter<Ticket>, opts?: ConsumeOptions): Promise<Array<Ticket>> {
130
457
  return await this.sendCommand(
131
458
  {
@@ -139,6 +466,68 @@ export class DeskNamespace extends Namespace {
139
466
  )
140
467
  }
141
468
 
469
+ /**
470
+ * @param filters.beginDate - Required. Start of the `storageDate` range, applied inclusively.
471
+ * @param filters.endDate - Required. End of the `storageDate` range. Exact-second timestamps are treated as exclusive,
472
+ * while timestamps with a non-zero seconds component are treated as inclusive.
473
+ * @param filters.teams - Filters by ticket team. Values are combined as alternatives.
474
+ * @param filters.agentIdentities - Filters by ticket agent identity. Values are combined as alternatives.
475
+ * @param filters.customerIdentities - Filters by ticket customer identity. Values are combined as alternatives.
476
+ * @param filters.tags - Matches tickets that contain at least one of the provided tags.
477
+ * @param filters.ticketIds - Filters by the Desk sequential ticket id, not the ticket UUID `id`.
478
+ * @param filters.includeIdentitiesNames - Makes the backend try to resolve `agentName` and `customerName`.
479
+ */
480
+ public async getTicketsHistory(
481
+ filters: {
482
+ beginDate: string | Date
483
+ endDate: string | Date
484
+ teams?: Array<string>
485
+ agentIdentities?: Array<Identity>
486
+ customerIdentities?: Array<Identity>
487
+ tags?: Array<string>
488
+ ticketIds?: Array<string | number>
489
+ includeIdentitiesNames?: boolean
490
+ },
491
+ opts?: ConsumeOptions,
492
+ ): Promise<
493
+ Array<{
494
+ id: string
495
+ sequentialId: number
496
+ customerIdentity: Identity
497
+ customerName?: string
498
+ agentIdentity?: Identity
499
+ agentName?: string
500
+ status: TicketStatus
501
+ team?: string
502
+ waitingTimeInSeconds?: number
503
+ firstResponseTimeInSeconds?: number
504
+ attendanceTimeInSeconds?: number
505
+ hasWaitingTimeSlaExceeded: boolean
506
+ hasFirstResponseTimeSlaExceeded: boolean
507
+ hasAttendanceTimeSlaExceeded: boolean
508
+ }>
509
+ > {
510
+ return await this.sendCommand(
511
+ {
512
+ method: 'get',
513
+ uri: uri`/tickets/history/v2?${{
514
+ beginDate: filters.beginDate,
515
+ endDate: filters.endDate,
516
+ teams: filters.teams?.join(','),
517
+ agentIdentities: filters.agentIdentities?.join(','),
518
+ customerIdentities: filters.customerIdentities?.join(','),
519
+ tags: filters.tags?.join(','),
520
+ ticketIds: filters.ticketIds?.join(','),
521
+ includeIdentitiesNames: filters.includeIdentitiesNames,
522
+ }}`,
523
+ },
524
+ {
525
+ collection: true,
526
+ ...opts,
527
+ },
528
+ )
529
+ }
530
+
142
531
  public async getContactTickets(contact: Identity, opts?: ConsumeOptions): Promise<Array<Ticket>> {
143
532
  return await this.sendCommand(
144
533
  {
@@ -203,69 +592,26 @@ export class DeskNamespace extends Namespace {
203
592
  }
204
593
 
205
594
  public async isOnAttendanceTime(queueIdOrName = 'Default', timezone = -3): Promise<boolean> {
206
- const attendanceHours: Array<AttendanceHour> = await this.sendCommand(
207
- {
208
- method: 'get',
209
- uri: uri`/attendance-hour`,
210
- },
211
- { collection: true },
212
- )
595
+ const attendanceHours = await this.getAttendanceHours()
213
596
 
214
597
  const orderedAttendanceHours = attendanceHours
215
598
  // Prioritize non-main attendance hours
216
599
  .sort((a, b) => Number(a.isMain) - Number(b.isMain))
217
600
 
218
601
  for (const attendanceHour of orderedAttendanceHours) {
219
- const detailedAttendanceHour: DetailedAttendanceHour = await this.sendCommand({
220
- method: 'get',
221
- uri: uri`/attendance-hour-container/${attendanceHour.id}`,
222
- })
223
-
224
- if (
225
- detailedAttendanceHour.queues.every(
226
- (queue) => queue.id !== queueIdOrName && queue.description !== queueIdOrName,
227
- ) &&
228
- !detailedAttendanceHour.attendanceHour.isMain
229
- ) {
230
- // Should keep trying other attendance hours to match the queue
231
- continue
232
- }
233
-
602
+ const detailedAttendanceHour = await this.getAttendanceHourContainer(attendanceHour.id)
234
603
  const now = new Date(Date.now() + timezone * 60 * 60 * 1000)
235
604
 
236
- const isInsideOffTime = detailedAttendanceHour.attendanceHourOffItems.some((offItem) => {
237
- const startDate = new Date(offItem.startDate)
238
- const endDate = new Date(offItem.endDate)
239
-
240
- return now.getTime() >= startDate.getTime() && now.getTime() <= endDate.getTime()
241
- })
242
- if (isInsideOffTime) {
243
- return false
244
- }
245
-
246
- const nowDayOfWeek = now.getDay()
247
- const daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
248
- const todaySchedule = detailedAttendanceHour.attendanceHourScheduleItems.find(
249
- (schedule) => schedule.dayOfWeek === daysOfWeek[nowDayOfWeek],
250
- )
251
- if (!todaySchedule) {
252
- return false
605
+ if (!matchesAttendanceHourQueue(detailedAttendanceHour, queueIdOrName)) {
606
+ // Should keep trying other attendance hours to match the queue
607
+ continue
253
608
  }
254
609
 
255
- const startTime = new Date(now)
256
- const endTime = new Date(now)
257
-
258
- const [startHours, startMinutes] = todaySchedule.startTime.split(':')
259
- startTime.setHours(Number(startHours))
260
- startTime.setMinutes(Number(startMinutes))
261
-
262
- const [endHours, endMinutes] = todaySchedule.endTime.split(':')
263
- endTime.setHours(Number(endHours))
264
- endTime.setMinutes(Number(endMinutes))
265
-
266
- if (now.getTime() >= startTime.getTime() && now.getTime() <= endTime.getTime()) {
610
+ if (isDetailedAttendanceHourOnAttendanceTime(detailedAttendanceHour, now)) {
267
611
  return true
268
612
  }
613
+
614
+ return false
269
615
  }
270
616
 
271
617
  return false
@@ -406,7 +752,6 @@ export class DeskNamespace extends Namespace {
406
752
  isEnabled: boolean
407
753
  status: 'Offline' | 'Pause' | 'Online' | 'Invisible'
408
754
  teams: Array<string>
409
- lastServiceDate: string
410
755
  }>
411
756
  > {
412
757
  try {
@@ -478,18 +823,24 @@ export class DeskNamespace extends Namespace {
478
823
  )
479
824
  }
480
825
 
481
- public async getTags(team: string, opts?: ConsumeOptions): Promise<Array<string>> {
482
- const result = await this.sendCommand<'get', Array<{ tag: string }>>(
483
- {
484
- method: 'get',
485
- uri: uri`/attendance-queues/name/${team}/tags`,
486
- },
487
- {
488
- collection: true,
489
- ...opts,
490
- },
491
- )
492
- return result.map((tag) => tag.tag)
826
+ public async getTags(team?: string, opts?: ConsumeOptions): Promise<Array<string>> {
827
+ if (team && team !== 'DIRECT_TRANSFER') {
828
+ const result = await this.sendCommand<'get', Array<{ tag: string }>>(
829
+ {
830
+ method: 'get',
831
+ uri: uri`/attendance-queues/name/${team}/tags`,
832
+ },
833
+ {
834
+ collection: true,
835
+ ...opts,
836
+ },
837
+ )
838
+ return result.map((tag) => tag.tag)
839
+ } else {
840
+ const bucketTags = await this.blipClient.account.getBucket('blip:desk:tags')
841
+ const { tags } = JSON.parse(bucketTags ?? '{}')
842
+ return tags?.map((tag: { text: string }) => tag.text) ?? []
843
+ }
493
844
  }
494
845
 
495
846
  public async getSummary(
@@ -528,7 +879,7 @@ export class DeskNamespace extends Namespace {
528
879
  ...opts,
529
880
  ownerIdentity: this.identity,
530
881
  })
531
- if (!configurations || !configurations.DefaultProvider) {
882
+ if (!configurations?.DefaultProvider) {
532
883
  throw new Error('No default provider found, Blip Desk is not enabled')
533
884
  }
534
885
 
@@ -554,7 +905,7 @@ export class DeskNamespace extends Namespace {
554
905
  ownerIdentity: this.identity,
555
906
  })
556
907
 
557
- if (!configurations || !configurations.DefaultProvider) {
908
+ if (!configurations?.DefaultProvider) {
558
909
  throw new Error('No default provider found')
559
910
  }
560
911
 
@@ -370,6 +370,7 @@ export class PluginsNamespace extends Namespace {
370
370
  plugin: Partial<
371
371
  Pick<DetailedPlugin, 'name' | 'overview' | 'description' | 'icon' | 'documentation' | 'price'> & {
372
372
  url: string
373
+ isPublished: boolean
373
374
  }
374
375
  >,
375
376
  opts?: ConsumeOptions,
@@ -388,6 +389,7 @@ export class PluginsNamespace extends Namespace {
388
389
  url: plugin.url,
389
390
  price: plugin.price,
390
391
  isPaid: plugin.price !== undefined && plugin.price > 0,
392
+ isPublished: plugin.isPublished,
391
393
  },
392
394
  },
393
395
  opts,