@whitewall/blip-sdk 0.0.174 → 0.0.176
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 +14 -7
- package/dist/cjs/client.js +3 -0
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/namespaces/account.js +21 -10
- package/dist/cjs/namespaces/account.js.map +1 -1
- package/dist/cjs/namespaces/analytics.js +54 -0
- package/dist/cjs/namespaces/analytics.js.map +1 -1
- package/dist/cjs/namespaces/desk.js +264 -45
- package/dist/cjs/namespaces/desk.js.map +1 -1
- package/dist/cjs/namespaces/plugins.js +1 -0
- package/dist/cjs/namespaces/plugins.js.map +1 -1
- package/dist/cjs/namespaces/portal.js +45 -0
- package/dist/cjs/namespaces/portal.js.map +1 -1
- package/dist/cjs/namespaces/tunnel.js +46 -0
- package/dist/cjs/namespaces/tunnel.js.map +1 -0
- package/dist/cjs/namespaces/whatsapp.js +2 -23
- package/dist/cjs/namespaces/whatsapp.js.map +1 -1
- package/dist/cjs/sender/http/httpsender.js +14 -5
- package/dist/cjs/sender/http/httpsender.js.map +1 -1
- package/dist/cjs/sender/multi/multisender.js +28 -9
- package/dist/cjs/sender/multi/multisender.js.map +1 -1
- package/dist/cjs/sender/sessionnegotiator.js +1 -1
- package/dist/cjs/sender/sessionnegotiator.js.map +1 -1
- package/dist/cjs/sender/tcp/tcpsender.js +35 -2
- package/dist/cjs/sender/tcp/tcpsender.js.map +1 -1
- package/dist/cjs/sender/websocket/websocketsender.js +1 -1
- package/dist/cjs/sender/websocket/websocketsender.js.map +1 -1
- package/dist/cjs/types/desk.js.map +1 -1
- package/dist/cjs/types/flow.js +344 -0
- package/dist/cjs/types/flow.js.map +1 -1
- package/dist/cjs/utils/desk.js +65 -0
- package/dist/cjs/utils/desk.js.map +1 -0
- package/dist/cjs/utils/thread.js +84 -0
- package/dist/cjs/utils/thread.js.map +1 -0
- package/dist/cjs/utils/whatsapp.js +268 -0
- package/dist/cjs/utils/whatsapp.js.map +1 -0
- package/dist/esm/client.js +3 -0
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/namespaces/account.js +17 -9
- package/dist/esm/namespaces/account.js.map +1 -1
- package/dist/esm/namespaces/analytics.js +54 -0
- package/dist/esm/namespaces/analytics.js.map +1 -1
- package/dist/esm/namespaces/desk.js +264 -45
- package/dist/esm/namespaces/desk.js.map +1 -1
- package/dist/esm/namespaces/plugins.js +1 -0
- package/dist/esm/namespaces/plugins.js.map +1 -1
- package/dist/esm/namespaces/portal.js +45 -0
- package/dist/esm/namespaces/portal.js.map +1 -1
- package/dist/esm/namespaces/tunnel.js +42 -0
- package/dist/esm/namespaces/tunnel.js.map +1 -0
- package/dist/esm/namespaces/whatsapp.js +2 -23
- package/dist/esm/namespaces/whatsapp.js.map +1 -1
- package/dist/esm/sender/http/httpsender.js +14 -5
- package/dist/esm/sender/http/httpsender.js.map +1 -1
- package/dist/esm/sender/multi/multisender.js +28 -9
- package/dist/esm/sender/multi/multisender.js.map +1 -1
- package/dist/esm/sender/sessionnegotiator.js +1 -1
- package/dist/esm/sender/sessionnegotiator.js.map +1 -1
- package/dist/esm/sender/tcp/tcpsender.js +1 -1
- package/dist/esm/sender/tcp/tcpsender.js.map +1 -1
- package/dist/esm/sender/websocket/websocketsender.js +1 -1
- package/dist/esm/sender/websocket/websocketsender.js.map +1 -1
- package/dist/esm/types/desk.js.map +1 -1
- package/dist/esm/types/flow.js +343 -1
- package/dist/esm/types/flow.js.map +1 -1
- package/dist/esm/utils/desk.js +59 -0
- package/dist/esm/utils/desk.js.map +1 -0
- package/dist/esm/utils/thread.js +80 -0
- package/dist/esm/utils/thread.js.map +1 -0
- package/dist/esm/utils/whatsapp.js +263 -0
- package/dist/esm/utils/whatsapp.js.map +1 -0
- package/dist/types/client.d.ts +2 -0
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/namespaces/account.d.ts +1790 -2
- package/dist/types/namespaces/account.d.ts.map +1 -1
- package/dist/types/namespaces/analytics.d.ts +60 -0
- package/dist/types/namespaces/analytics.d.ts.map +1 -1
- package/dist/types/namespaces/desk.d.ts +124 -4
- package/dist/types/namespaces/desk.d.ts.map +1 -1
- package/dist/types/namespaces/plugins.d.ts +1 -0
- package/dist/types/namespaces/plugins.d.ts.map +1 -1
- package/dist/types/namespaces/portal.d.ts +45 -0
- package/dist/types/namespaces/portal.d.ts.map +1 -1
- package/dist/types/namespaces/tunnel.d.ts +28 -0
- package/dist/types/namespaces/tunnel.d.ts.map +1 -0
- package/dist/types/namespaces/whatsapp.d.ts +3 -2
- package/dist/types/namespaces/whatsapp.d.ts.map +1 -1
- package/dist/types/schemas/webhook.d.ts +2 -2
- package/dist/types/sender/gateway/customgatewaysender.d.ts +1 -1
- package/dist/types/sender/http/httpsender.d.ts +3 -3
- package/dist/types/sender/http/httpsender.d.ts.map +1 -1
- package/dist/types/sender/multi/multisender.d.ts +1 -0
- package/dist/types/sender/multi/multisender.d.ts.map +1 -1
- package/dist/types/sender/sender.d.ts +1 -1
- package/dist/types/sender/tcp/tcpsender.d.ts +1 -1
- package/dist/types/sender/websocket/websocketsender.d.ts +1 -1
- package/dist/types/types/desk.d.ts +57 -1
- package/dist/types/types/desk.d.ts.map +1 -1
- package/dist/types/types/flow.d.ts +3269 -142
- package/dist/types/types/flow.d.ts.map +1 -1
- package/dist/types/types/message.d.ts +1 -1
- package/dist/types/types/whatsapp.d.ts +10 -2
- package/dist/types/types/whatsapp.d.ts.map +1 -1
- package/dist/types/utils/desk.d.ts +6 -0
- package/dist/types/utils/desk.d.ts.map +1 -0
- package/dist/types/utils/thread.d.ts +4 -0
- package/dist/types/utils/thread.d.ts.map +1 -0
- package/dist/types/utils/whatsapp.d.ts +103 -0
- package/dist/types/utils/whatsapp.d.ts.map +1 -0
- package/package.json +8 -11
- package/src/client.ts +3 -0
- package/src/index.ts +3 -0
- package/src/namespaces/account.ts +20 -12
- package/src/namespaces/analytics.ts +154 -0
- package/src/namespaces/desk.ts +428 -77
- package/src/namespaces/plugins.ts +2 -0
- package/src/namespaces/portal.ts +110 -0
- package/src/namespaces/tunnel.ts +58 -0
- package/src/namespaces/whatsapp.ts +4 -39
- package/src/sender/http/httpsender.ts +20 -6
- package/src/sender/multi/multisender.ts +38 -14
- package/src/sender/sessionnegotiator.ts +1 -1
- package/src/sender/tcp/tcpsender.ts +1 -1
- package/src/sender/websocket/websocketsender.ts +1 -1
- package/src/types/desk.ts +66 -1
- package/src/types/flow.ts +387 -246
- package/src/types/message.ts +1 -1
- package/src/types/whatsapp.ts +11 -2
- package/src/utils/desk.ts +78 -0
- package/src/utils/thread.ts +119 -0
- package/src/utils/whatsapp.ts +530 -0
package/src/namespaces/portal.ts
CHANGED
|
@@ -192,6 +192,116 @@ export class PortalNamespace extends Namespace {
|
|
|
192
192
|
})
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
public async getTenantActiveMessagesMetrics(
|
|
196
|
+
tenantId: string,
|
|
197
|
+
interval: 'D' | 'M' | 'NI',
|
|
198
|
+
filters?: {
|
|
199
|
+
applicationIdentity?: Identity
|
|
200
|
+
startDate?: Date | string
|
|
201
|
+
endDate?: Date | string
|
|
202
|
+
},
|
|
203
|
+
opts?: ConsumeOptions,
|
|
204
|
+
): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
|
|
205
|
+
return await this.sendCommand(
|
|
206
|
+
{
|
|
207
|
+
method: 'get',
|
|
208
|
+
uri: uri`/metrics/${tenantId}/active-messages/${interval}?${filters}`,
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
collection: true,
|
|
212
|
+
...opts,
|
|
213
|
+
},
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
public async getTenantReceivedMessagesMetrics(
|
|
218
|
+
tenantId: string,
|
|
219
|
+
interval: 'D' | 'M' | 'NI',
|
|
220
|
+
filters?: {
|
|
221
|
+
applicationIdentity?: Identity
|
|
222
|
+
startDate?: Date | string
|
|
223
|
+
endDate?: Date | string
|
|
224
|
+
},
|
|
225
|
+
opts?: ConsumeOptions,
|
|
226
|
+
): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
|
|
227
|
+
return await this.sendCommand(
|
|
228
|
+
{
|
|
229
|
+
method: 'get',
|
|
230
|
+
uri: uri`/metrics/${tenantId}/received-messages/${interval}?${filters}`,
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
collection: true,
|
|
234
|
+
...opts,
|
|
235
|
+
},
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
public async getTenantSentMessagesMetrics(
|
|
240
|
+
tenantId: string,
|
|
241
|
+
interval: 'D' | 'M' | 'NI',
|
|
242
|
+
filters?: {
|
|
243
|
+
applicationIdentity?: Identity
|
|
244
|
+
startDate?: Date | string
|
|
245
|
+
endDate?: Date | string
|
|
246
|
+
},
|
|
247
|
+
opts?: ConsumeOptions,
|
|
248
|
+
): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
|
|
249
|
+
return await this.sendCommand(
|
|
250
|
+
{
|
|
251
|
+
method: 'get',
|
|
252
|
+
uri: uri`/metrics/${tenantId}/sent-messages/${interval}?${filters}`,
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
collection: true,
|
|
256
|
+
...opts,
|
|
257
|
+
},
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
public async getTenantActiveUsersMetrics(
|
|
262
|
+
tenantId: string,
|
|
263
|
+
interval: 'D' | 'M' | 'NI',
|
|
264
|
+
filters?: {
|
|
265
|
+
applicationIdentity?: Identity
|
|
266
|
+
startDate?: Date | string
|
|
267
|
+
endDate?: Date | string
|
|
268
|
+
},
|
|
269
|
+
opts?: ConsumeOptions,
|
|
270
|
+
): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
|
|
271
|
+
return await this.sendCommand(
|
|
272
|
+
{
|
|
273
|
+
method: 'get',
|
|
274
|
+
uri: uri`/metrics/${tenantId}/active-users/${interval}?${filters}`,
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
collection: true,
|
|
278
|
+
...opts,
|
|
279
|
+
},
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
public async getTenantEngagedUsersMetrics(
|
|
284
|
+
tenantId: string,
|
|
285
|
+
interval: 'D' | 'M' | 'NI',
|
|
286
|
+
filters?: {
|
|
287
|
+
applicationIdentity?: Identity
|
|
288
|
+
startDate?: Date | string
|
|
289
|
+
endDate?: Date | string
|
|
290
|
+
},
|
|
291
|
+
opts?: ConsumeOptions,
|
|
292
|
+
): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
|
|
293
|
+
return await this.sendCommand(
|
|
294
|
+
{
|
|
295
|
+
method: 'get',
|
|
296
|
+
uri: uri`/metrics/${tenantId}/engaged-users/${interval}?${filters}`,
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
collection: true,
|
|
300
|
+
...opts,
|
|
301
|
+
},
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
|
|
195
305
|
public async tenantExists(tenantId: string): Promise<boolean> {
|
|
196
306
|
try {
|
|
197
307
|
await this.sendCommand({
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { BlipClient } from '../client.ts'
|
|
2
|
+
import { type Identity, Node } from '../types/index.ts'
|
|
3
|
+
import { uri } from '../utils/uri.ts'
|
|
4
|
+
import { type ConsumeOptions, Namespace, type SendCommandOptions } from './namespace.ts'
|
|
5
|
+
|
|
6
|
+
export class TunnelNamespace extends Namespace {
|
|
7
|
+
constructor(blipClient: BlipClient, defaultOptions?: SendCommandOptions) {
|
|
8
|
+
super(blipClient, 'tunnel', defaultOptions)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Retrieves metadata information about the tunnel origin and destination
|
|
13
|
+
* This must only be called by a subbot
|
|
14
|
+
* @returns An object containing:
|
|
15
|
+
* - `owner` - The identity of the subbot owner (router)
|
|
16
|
+
* - `originator` - The identity of the originator on the router (user)
|
|
17
|
+
* - `destination` - The identity of the destination child (subbot)
|
|
18
|
+
*/
|
|
19
|
+
public getTunnel(
|
|
20
|
+
tunnelIdentityOrName: Identity | string,
|
|
21
|
+
opts?: ConsumeOptions,
|
|
22
|
+
): Promise<{
|
|
23
|
+
owner: Identity
|
|
24
|
+
originator: Identity
|
|
25
|
+
destination: Identity
|
|
26
|
+
}> {
|
|
27
|
+
const node =
|
|
28
|
+
typeof tunnelIdentityOrName === 'string'
|
|
29
|
+
? new Node(tunnelIdentityOrName, 'tunnel.msging.net')
|
|
30
|
+
: Node.from(tunnelIdentityOrName)
|
|
31
|
+
|
|
32
|
+
if (node.getSource() !== 'Tunnel') {
|
|
33
|
+
throw new Error('Invalid tunnel identity or name')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return this.sendCommand(
|
|
37
|
+
{
|
|
38
|
+
method: 'get',
|
|
39
|
+
uri: uri`/tunnels/${node.name}`,
|
|
40
|
+
},
|
|
41
|
+
opts,
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Retrieves the tunnel ID for a given originator and destination
|
|
47
|
+
* Must only be called by a router
|
|
48
|
+
* @param originator - The identity of the originator on the router (user)
|
|
49
|
+
* @param destination - The identity of the destination child (subbot)
|
|
50
|
+
* @returns The tunnel ID
|
|
51
|
+
*/
|
|
52
|
+
public getTunnelId(originator: Identity, destination: Identity) {
|
|
53
|
+
return this.sendCommand({
|
|
54
|
+
method: 'get',
|
|
55
|
+
uri: uri`/tunnels/${originator}/${destination}`,
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import type { BlipClient } from '../client.ts'
|
|
2
2
|
import type { Identity } from '../types/index.ts'
|
|
3
|
-
import type {
|
|
4
|
-
BodyComponent,
|
|
5
|
-
ButtonComponent,
|
|
6
|
-
HandleFormats,
|
|
7
|
-
HeaderComponent,
|
|
8
|
-
MessageTemplate,
|
|
9
|
-
MessageTemplateVariable,
|
|
10
|
-
WhatsAppTemplateLanguage,
|
|
11
|
-
WhatsappFlow,
|
|
12
|
-
} from '../types/whatsapp.ts'
|
|
3
|
+
import type { MessageTemplate, WhatsAppTemplateLanguage, WhatsappFlow } from '../types/whatsapp.ts'
|
|
13
4
|
import { uri } from '../utils/uri.ts'
|
|
5
|
+
import { getMessageTemplateVariables } from '../utils/whatsapp.ts'
|
|
14
6
|
import { type ConsumeOptions, Namespace, type SendCommandOptions } from './namespace.ts'
|
|
15
7
|
|
|
16
8
|
export class WhatsAppNamespace extends Namespace {
|
|
@@ -69,7 +61,7 @@ export class WhatsAppNamespace extends Namespace {
|
|
|
69
61
|
templateName: string,
|
|
70
62
|
language?: WhatsAppTemplateLanguage,
|
|
71
63
|
opts?: ConsumeOptions,
|
|
72
|
-
): Promise<(MessageTemplate & { variables:
|
|
64
|
+
): Promise<(MessageTemplate & { variables: ReturnType<typeof getMessageTemplateVariables> }) | undefined> {
|
|
73
65
|
let templates = await this.getMessageTemplates({ name: templateName }, opts)
|
|
74
66
|
if (language) {
|
|
75
67
|
templates = templates.filter((template) => template.language === language)
|
|
@@ -79,36 +71,9 @@ export class WhatsAppNamespace extends Namespace {
|
|
|
79
71
|
return
|
|
80
72
|
}
|
|
81
73
|
|
|
82
|
-
const variables: Array<MessageTemplateVariable> = []
|
|
83
|
-
|
|
84
|
-
const handleHeader = template.components.find(
|
|
85
|
-
(c): c is HeaderComponent<HandleFormats> =>
|
|
86
|
-
c.type === 'HEADER' && ['IMAGE', 'VIDEO', 'DOCUMENT'].includes(c.format),
|
|
87
|
-
)
|
|
88
|
-
if (handleHeader) {
|
|
89
|
-
variables.push({ type: 'MEDIA', example: handleHeader.example.header_handle?.[0] })
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const body = template.components.find((c): c is BodyComponent => c.type === 'BODY')
|
|
93
|
-
if (body?.example?.body_text) {
|
|
94
|
-
variables.push(...body.example.body_text[0].map((text) => ({ type: 'BODY' as const, example: text })))
|
|
95
|
-
} else if (body) {
|
|
96
|
-
variables.push(...(body.text.match(/{{(\d)}}/g)?.map(() => ({ type: 'BODY' as const })) ?? []))
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const button = template.components.find((c): c is ButtonComponent => c.type === 'BUTTONS')
|
|
100
|
-
if (button) {
|
|
101
|
-
const urlButton = button.buttons.find((b) => b.type === 'URL')
|
|
102
|
-
if (urlButton?.example?.length) {
|
|
103
|
-
variables.push(...urlButton.example.map((example: string) => ({ type: 'BUTTON', example })))
|
|
104
|
-
} else if (urlButton) {
|
|
105
|
-
variables.push(...(urlButton.url.match(/{{(\d)}}/g)?.map(() => ({ type: 'BUTTON' })) ?? []))
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
74
|
return {
|
|
110
75
|
...template,
|
|
111
|
-
variables,
|
|
76
|
+
variables: getMessageTemplateVariables(template.components),
|
|
112
77
|
}
|
|
113
78
|
}
|
|
114
79
|
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
type Command,
|
|
3
|
+
type CommandMethods,
|
|
4
|
+
type Message,
|
|
5
|
+
type MessageTypes,
|
|
6
|
+
Node,
|
|
7
|
+
type UnknownCommandResponse,
|
|
8
|
+
} from '../../types/index.ts'
|
|
2
9
|
import { BlipError } from '../bliperror.ts'
|
|
3
10
|
import { RetryableError } from '../retryableerror.ts'
|
|
4
11
|
import { ConnectionSender, type ConnectionSenderConstructor, type Sender } from '../sender.ts'
|
|
@@ -6,7 +13,7 @@ import { EnvelopeThrottler } from '../throttler.ts'
|
|
|
6
13
|
|
|
7
14
|
export class HttpSender extends ConnectionSender implements Sender {
|
|
8
15
|
private readonly baseurl: string
|
|
9
|
-
private readonly
|
|
16
|
+
private readonly authHeaders: Record<string, string>
|
|
10
17
|
private readonly throttler = new EnvelopeThrottler()
|
|
11
18
|
|
|
12
19
|
constructor(options: ConstructorParameters<ConnectionSenderConstructor>[0]) {
|
|
@@ -16,11 +23,18 @@ export class HttpSender extends ConnectionSender implements Sender {
|
|
|
16
23
|
this.baseurl = `https://${prefix}http.${this.domain}`
|
|
17
24
|
|
|
18
25
|
if (options.authentication.scheme === 'key') {
|
|
19
|
-
|
|
26
|
+
const token = HttpSender.createToken(options.node, options.authentication.key)
|
|
27
|
+
this.authHeaders = { Authorization: `Key ${token}` }
|
|
20
28
|
} else if (options.authentication.scheme === 'token') {
|
|
21
|
-
this.
|
|
29
|
+
this.authHeaders = { Authorization: `Key ${options.authentication.token}` }
|
|
30
|
+
} else if (options.authentication.scheme === 'external') {
|
|
31
|
+
this.authHeaders = {
|
|
32
|
+
Authorization: `Bearer ${options.authentication.token}`,
|
|
33
|
+
'http-session-authentication-external-issuer': options.authentication.issuer,
|
|
34
|
+
'http-session-identity': Node.from(options.node).toIdentity(),
|
|
35
|
+
}
|
|
22
36
|
} else {
|
|
23
|
-
throw new Error('HttpSender only supports key or
|
|
37
|
+
throw new Error('HttpSender only supports key, token, or external authentication')
|
|
24
38
|
}
|
|
25
39
|
}
|
|
26
40
|
|
|
@@ -62,7 +76,7 @@ export class HttpSender extends ConnectionSender implements Sender {
|
|
|
62
76
|
method: 'POST',
|
|
63
77
|
headers: {
|
|
64
78
|
'Content-Type': 'application/json',
|
|
65
|
-
|
|
79
|
+
...this.authHeaders,
|
|
66
80
|
},
|
|
67
81
|
body,
|
|
68
82
|
})
|
|
@@ -4,12 +4,17 @@ import type { Sender } from '../sender.ts'
|
|
|
4
4
|
|
|
5
5
|
export type SenderFactory = () => MaybePromise<Sender>
|
|
6
6
|
|
|
7
|
+
const isSenderFactory = (value: Sender | SenderFactory): value is SenderFactory => value instanceof Function
|
|
8
|
+
|
|
9
|
+
type SenderEntry = {
|
|
10
|
+
filter: (envelope: Envelope) => boolean | undefined
|
|
11
|
+
factory: () => Promise<Sender>
|
|
12
|
+
resolved?: Sender
|
|
13
|
+
resolving?: Promise<Sender>
|
|
14
|
+
}
|
|
15
|
+
|
|
7
16
|
export class MultiSender implements Sender, Closable {
|
|
8
|
-
private senders: Array<
|
|
9
|
-
filter: (envelope: Envelope) => boolean | undefined
|
|
10
|
-
sender: Sender | SenderFactory
|
|
11
|
-
resolved?: Sender
|
|
12
|
-
}>
|
|
17
|
+
private senders: Array<SenderEntry>
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
20
|
* @param initializers Array of objects containing a filter function and a sender or a factory function that returns a sender.
|
|
@@ -23,11 +28,14 @@ export class MultiSender implements Sender, Closable {
|
|
|
23
28
|
sender: Sender | SenderFactory
|
|
24
29
|
}>,
|
|
25
30
|
) {
|
|
26
|
-
this.senders = initializers.map(({ filter, sender }) =>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
this.senders = initializers.map(({ filter, sender }) => {
|
|
32
|
+
const isFactory = isSenderFactory(sender)
|
|
33
|
+
return {
|
|
34
|
+
filter: filter ?? (() => true),
|
|
35
|
+
factory: isFactory ? () => Promise.resolve(sender()) : () => Promise.resolve(sender),
|
|
36
|
+
resolved: isFactory ? undefined : sender,
|
|
37
|
+
}
|
|
38
|
+
})
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
async sendMessage<Type extends MessageTypes>(message: Message<Type>): Promise<void> {
|
|
@@ -57,14 +65,30 @@ export class MultiSender implements Sender, Closable {
|
|
|
57
65
|
return matched.resolved! as InstanceType<TProto>
|
|
58
66
|
}
|
|
59
67
|
|
|
60
|
-
private
|
|
68
|
+
private getSender(envelope: Envelope): Promise<Sender> {
|
|
61
69
|
const matched = this.senders.find(({ filter }) => filter(envelope))
|
|
62
70
|
if (!matched) throw new Error('No sender matched for envelope')
|
|
63
71
|
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
return this.resolveSender(matched)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private resolveSender(entry: SenderEntry): Promise<Sender> {
|
|
76
|
+
if (entry.resolved) return Promise.resolve(entry.resolved)
|
|
77
|
+
|
|
78
|
+
if (!entry.resolving) {
|
|
79
|
+
entry.resolving = entry
|
|
80
|
+
.factory()
|
|
81
|
+
.then((sender) => {
|
|
82
|
+
entry.resolved = sender
|
|
83
|
+
entry.resolving = undefined
|
|
84
|
+
return sender
|
|
85
|
+
})
|
|
86
|
+
.catch((error) => {
|
|
87
|
+
entry.resolving = undefined
|
|
88
|
+
throw error
|
|
89
|
+
})
|
|
66
90
|
}
|
|
67
91
|
|
|
68
|
-
return
|
|
92
|
+
return entry.resolving
|
|
69
93
|
}
|
|
70
94
|
}
|
|
@@ -144,7 +144,7 @@ class TCPHandle<T> {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
public async close() {
|
|
147
|
-
if (!this.closing && this.currentSocketPromise) {
|
|
147
|
+
if (!this.closing && this.currentSocketPromise !== null) {
|
|
148
148
|
this.closing = true
|
|
149
149
|
const current = await this.currentSocketPromise
|
|
150
150
|
current.end().removeAllListeners().destroySoon()
|
|
@@ -138,7 +138,7 @@ class WebSocketHandle<T> {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
public async close() {
|
|
141
|
-
if (!this.closing && this.currentWebSocketPromise) {
|
|
141
|
+
if (!this.closing && this.currentWebSocketPromise !== null) {
|
|
142
142
|
this.closing = true
|
|
143
143
|
const current = await this.currentWebSocketPromise
|
|
144
144
|
current.close()
|
package/src/types/desk.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Identity } from './node.ts'
|
|
2
|
+
|
|
1
3
|
export type TicketStatus =
|
|
2
4
|
| 'Waiting'
|
|
3
5
|
| 'Open'
|
|
@@ -12,6 +14,8 @@ export type AttendanceHour = {
|
|
|
12
14
|
title: string
|
|
13
15
|
description: string
|
|
14
16
|
isMain: boolean
|
|
17
|
+
storageDate?: string
|
|
18
|
+
timeZoneId?: string
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
export enum DayOfWeek {
|
|
@@ -38,14 +42,75 @@ export type AttendanceHourOffItem = {
|
|
|
38
42
|
endDate: string
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
export type
|
|
45
|
+
export type DescriptionDocument = {
|
|
42
46
|
id: string
|
|
43
47
|
description: string
|
|
44
48
|
}
|
|
45
49
|
|
|
50
|
+
export type Queue = DescriptionDocument
|
|
51
|
+
|
|
46
52
|
export type DetailedAttendanceHour = {
|
|
47
53
|
attendanceHour: AttendanceHour
|
|
48
54
|
attendanceHourScheduleItems: Array<AttendanceHourScheduleItem>
|
|
49
55
|
attendanceHourOffItems: Array<AttendanceHourOffItem>
|
|
50
56
|
queues: Array<Queue>
|
|
57
|
+
attendants: Array<DescriptionDocument>
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type DeskAttendanceQueue = {
|
|
61
|
+
id?: string
|
|
62
|
+
ownerIdentity?: Identity
|
|
63
|
+
name: string
|
|
64
|
+
isActive: boolean
|
|
65
|
+
storageDate?: string
|
|
66
|
+
priority?: number
|
|
67
|
+
uniqueId?: string
|
|
68
|
+
attendanceHourId?: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type DeskAttendanceQueueTag = {
|
|
72
|
+
id?: string
|
|
73
|
+
attendanceQueueId?: string
|
|
74
|
+
ownerIdentity?: Identity
|
|
75
|
+
tag: string
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type DeskRuleRelation = 'Contains' | 'NotContains' | 'Equals' | 'NotEquals'
|
|
79
|
+
|
|
80
|
+
export type DeskRuleOperator = 'Or' | 'And'
|
|
81
|
+
|
|
82
|
+
export type DeskRuleCondition = {
|
|
83
|
+
property: string
|
|
84
|
+
relation: DeskRuleRelation
|
|
85
|
+
values: Array<string>
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type DeskRule = {
|
|
89
|
+
id?: string
|
|
90
|
+
ownerIdentity?: Identity
|
|
91
|
+
title: string
|
|
92
|
+
team: string
|
|
93
|
+
property?: string
|
|
94
|
+
relation?: DeskRuleRelation
|
|
95
|
+
isActive?: boolean
|
|
96
|
+
values?: Array<string>
|
|
97
|
+
conditions?: Array<DeskRuleCondition>
|
|
98
|
+
operator?: DeskRuleOperator
|
|
99
|
+
priority?: number
|
|
100
|
+
storageDate?: string
|
|
101
|
+
queueId?: string
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export type DeskPriorityRule = {
|
|
105
|
+
id?: string
|
|
106
|
+
ownerIdentity?: Identity
|
|
107
|
+
title: string
|
|
108
|
+
queueId: string
|
|
109
|
+
isActive?: boolean
|
|
110
|
+
conditions?: Array<DeskRuleCondition>
|
|
111
|
+
operator?: DeskRuleOperator
|
|
112
|
+
priority?: number
|
|
113
|
+
urgency: number
|
|
114
|
+
applyConditions: boolean
|
|
115
|
+
storageDate?: string
|
|
51
116
|
}
|