@whitewall/blip-sdk 0.0.164 → 0.0.166
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/cjs/namespaces/account.js +24 -9
- package/dist/cjs/namespaces/account.js.map +1 -1
- package/dist/cjs/namespaces/namespace.js +1 -1
- package/dist/cjs/namespaces/namespace.js.map +1 -1
- package/dist/cjs/namespaces/plugins.js +113 -14
- package/dist/cjs/namespaces/plugins.js.map +1 -1
- package/dist/cjs/types/message.js +22 -1
- package/dist/cjs/types/message.js.map +1 -1
- package/dist/esm/namespaces/account.js +24 -9
- package/dist/esm/namespaces/account.js.map +1 -1
- package/dist/esm/namespaces/namespace.js +1 -1
- package/dist/esm/namespaces/namespace.js.map +1 -1
- package/dist/esm/namespaces/plugins.js +113 -14
- package/dist/esm/namespaces/plugins.js.map +1 -1
- package/dist/esm/types/message.js +19 -0
- package/dist/esm/types/message.js.map +1 -1
- package/dist/types/namespaces/account.d.ts +1 -0
- package/dist/types/namespaces/account.d.ts.map +1 -1
- package/dist/types/namespaces/plugins.d.ts +48 -6
- package/dist/types/namespaces/plugins.d.ts.map +1 -1
- package/dist/types/types/message.d.ts +5 -0
- package/dist/types/types/message.d.ts.map +1 -1
- package/dist/types/types/plugins.d.ts +2 -1
- package/dist/types/types/plugins.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/namespaces/account.ts +29 -9
- package/src/namespaces/namespace.ts +1 -1
- package/src/namespaces/plugins.ts +175 -20
- package/src/types/message.ts +24 -0
- package/src/types/plugins.ts +2 -1
|
@@ -48,6 +48,7 @@ export class AccountNamespace extends Namespace {
|
|
|
48
48
|
)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/** If you are initializing a chatbot, it usually is status 'available' with routingRule 'identity' */
|
|
51
52
|
public async setPresence(presence: Omit<Presence, 'lastSeen' | 'instances'>, opts?: ConsumeOptions): Promise<void> {
|
|
52
53
|
return await this.sendCommand(
|
|
53
54
|
{
|
|
@@ -221,6 +222,7 @@ export class AccountNamespace extends Namespace {
|
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
public async *streamContacts(filter?: ODataFilter<Contact>, opts?: ConsumeOptions): AsyncIterable<Contact> {
|
|
225
|
+
const take = opts?.take ?? 100
|
|
224
226
|
const items = this.sendCommand<'get', Array<Contact>>(
|
|
225
227
|
{
|
|
226
228
|
method: 'get',
|
|
@@ -230,13 +232,22 @@ export class AccountNamespace extends Namespace {
|
|
|
230
232
|
collection: true,
|
|
231
233
|
stream: true,
|
|
232
234
|
...opts,
|
|
235
|
+
take,
|
|
233
236
|
},
|
|
234
237
|
)
|
|
235
238
|
|
|
236
|
-
const seenIdentities = new
|
|
239
|
+
const seenIdentities = new Map<string, true>()
|
|
240
|
+
// best-effort to deduplicate without growing memory indefinitely
|
|
241
|
+
const maxIdentityCacheSize = take * 5
|
|
242
|
+
|
|
237
243
|
for await (const contact of items) {
|
|
238
244
|
if (!seenIdentities.has(contact.identity)) {
|
|
239
|
-
seenIdentities.
|
|
245
|
+
seenIdentities.set(contact.identity, true)
|
|
246
|
+
|
|
247
|
+
if (seenIdentities.size > maxIdentityCacheSize) {
|
|
248
|
+
seenIdentities.delete(seenIdentities.keys().next().value!)
|
|
249
|
+
}
|
|
250
|
+
|
|
240
251
|
yield contact
|
|
241
252
|
}
|
|
242
253
|
}
|
|
@@ -252,7 +263,10 @@ export class AccountNamespace extends Namespace {
|
|
|
252
263
|
const end = new Date(endDate)
|
|
253
264
|
if (start > end) return
|
|
254
265
|
|
|
255
|
-
const seenNames = new
|
|
266
|
+
const seenNames = new Map<string, true>()
|
|
267
|
+
// best-effort to deduplicate without growing memory indefinitely
|
|
268
|
+
const maxNameCacheSize = take * 5
|
|
269
|
+
let yieldedCount = 0
|
|
256
270
|
let cursorTime = end.getTime()
|
|
257
271
|
const startTime = start.getTime()
|
|
258
272
|
|
|
@@ -282,17 +296,23 @@ export class AccountNamespace extends Namespace {
|
|
|
282
296
|
|
|
283
297
|
const name = Node.from(contact.identity).name
|
|
284
298
|
if (!seenNames.has(name)) {
|
|
285
|
-
seenNames.
|
|
299
|
+
seenNames.set(name, true)
|
|
300
|
+
|
|
301
|
+
if (seenNames.size > maxNameCacheSize) {
|
|
302
|
+
seenNames.delete(seenNames.keys().next().value!)
|
|
303
|
+
}
|
|
304
|
+
|
|
286
305
|
yield contact
|
|
306
|
+
yieldedCount++
|
|
287
307
|
|
|
288
|
-
if (opts.max &&
|
|
308
|
+
if (opts.max && yieldedCount >= opts.max) {
|
|
289
309
|
return
|
|
290
310
|
}
|
|
291
311
|
}
|
|
292
312
|
}
|
|
293
313
|
}
|
|
294
314
|
|
|
295
|
-
const reachedMax = opts.max &&
|
|
315
|
+
const reachedMax = opts.max && yieldedCount >= opts.max
|
|
296
316
|
const hasMore = !reachedMax && count === take && cursorTime !== oldestTime - 1
|
|
297
317
|
if (!hasMore || !opts.fetchall) break
|
|
298
318
|
|
|
@@ -560,7 +580,7 @@ export class AccountNamespace extends Namespace {
|
|
|
560
580
|
},
|
|
561
581
|
opts?: Omit<ConsumeOptions, 'skip'>,
|
|
562
582
|
): Promise<Array<ThreadItem>> {
|
|
563
|
-
|
|
583
|
+
const thread: Array<ThreadItem> = []
|
|
564
584
|
let lastMessage = query?.messageId
|
|
565
585
|
let lastStorageDate = query?.referenceDate ? new Date(query.referenceDate).toISOString() : undefined
|
|
566
586
|
let hasMore = true
|
|
@@ -593,14 +613,14 @@ export class AccountNamespace extends Namespace {
|
|
|
593
613
|
fetchall: false,
|
|
594
614
|
},
|
|
595
615
|
)
|
|
596
|
-
thread
|
|
616
|
+
thread.push(...threadItems)
|
|
597
617
|
|
|
598
618
|
hasMore = threadItems.length === take && lastMessage !== threadItems.at(-1)?.id
|
|
599
619
|
lastMessage = threadItems.at(-1)?.id
|
|
600
620
|
lastStorageDate = threadItems.at(-1)?.date
|
|
601
621
|
} while (hasMore && opts?.fetchall)
|
|
602
622
|
|
|
603
|
-
return thread.
|
|
623
|
+
return thread.sort((a, b) => b.date.localeCompare(a.date))
|
|
604
624
|
}
|
|
605
625
|
|
|
606
626
|
public async getNotifications(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BlipClient } from '../client.ts'
|
|
2
2
|
import type { BlipLanguage } from '../types/account.ts'
|
|
3
3
|
import type { Identity } from '../types/node.ts'
|
|
4
|
-
import type { DetailedPlugin, Plugin, PluginSubscription } from '../types/plugins.ts'
|
|
4
|
+
import type { DetailedPlugin, Plugin, PluginBilling, PluginSubscription } from '../types/plugins.ts'
|
|
5
5
|
import type { Application } from '../types/portal.ts'
|
|
6
6
|
import { uri } from '../utils/uri.ts'
|
|
7
7
|
import { type ConsumeOptions, Namespace, type SendCommandOptions } from './namespace.ts'
|
|
@@ -221,11 +221,156 @@ export class PluginsNamespace extends Namespace {
|
|
|
221
221
|
)
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
/** This route can only be called by an admin user of blip.ai */
|
|
225
|
+
public deletePluginMedia(mediaId: string, opts?: ConsumeOptions) {
|
|
226
|
+
return this.sendCommand(
|
|
227
|
+
{
|
|
228
|
+
method: 'delete',
|
|
229
|
+
uri: uri`/images/${mediaId}`,
|
|
230
|
+
},
|
|
231
|
+
opts,
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** This route can only be called by an admin user of blip.ai */
|
|
236
|
+
public addPluginMedia(pluginId: string, type: 'image' | 'video', url: string, opts?: ConsumeOptions) {
|
|
237
|
+
return this.sendCommand(
|
|
238
|
+
{
|
|
239
|
+
method: 'set',
|
|
240
|
+
type: 'application/vnd.iris.plugins.image-create+json',
|
|
241
|
+
uri: uri`/images`,
|
|
242
|
+
resource: {
|
|
243
|
+
uri: url,
|
|
244
|
+
pluginId,
|
|
245
|
+
imageType: type === 'image' ? 3 : 1,
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
opts,
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** This route can only be called by an admin user of blip.ai */
|
|
253
|
+
public addPlugin(
|
|
254
|
+
plugin: {
|
|
255
|
+
documentation: DetailedPlugin['documentation']
|
|
256
|
+
url: string
|
|
257
|
+
icon: DetailedPlugin['icon']
|
|
258
|
+
price?: DetailedPlugin['price']
|
|
259
|
+
authorId: number
|
|
260
|
+
media: Array<{ uri: string; type: 'image' | 'video' }>
|
|
261
|
+
tags: Array<number>
|
|
262
|
+
languages: {
|
|
263
|
+
pt: {
|
|
264
|
+
name: string
|
|
265
|
+
overview: string
|
|
266
|
+
description: string
|
|
267
|
+
}
|
|
268
|
+
en: {
|
|
269
|
+
name: string
|
|
270
|
+
overview: string
|
|
271
|
+
description: string
|
|
272
|
+
}
|
|
273
|
+
es: {
|
|
274
|
+
name: string
|
|
275
|
+
overview: string
|
|
276
|
+
description: string
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
prices?: Array<
|
|
280
|
+
Omit<PluginBilling, 'billingId' | 'currency' | 'language' | 'isActive' | 'featuresIncluded'> & {
|
|
281
|
+
featuresIncluded: Array<{
|
|
282
|
+
icon: string
|
|
283
|
+
description: string
|
|
284
|
+
}>
|
|
285
|
+
}
|
|
286
|
+
>
|
|
287
|
+
},
|
|
288
|
+
opts?: ConsumeOptions,
|
|
289
|
+
) {
|
|
290
|
+
const price = plugin.prices?.[0]?.price ?? plugin.price
|
|
291
|
+
return this.sendCommand(
|
|
292
|
+
{
|
|
293
|
+
method: 'set',
|
|
294
|
+
type: 'application/vnd.lime.collection+json',
|
|
295
|
+
uri: uri`/plugins`,
|
|
296
|
+
resource: {
|
|
297
|
+
itemType: 'application/vnd.iris.plugin.resource+json',
|
|
298
|
+
items: [
|
|
299
|
+
{
|
|
300
|
+
name: plugin.languages.pt.name,
|
|
301
|
+
website: plugin.documentation,
|
|
302
|
+
url: plugin.url,
|
|
303
|
+
overview: plugin.languages.pt.overview,
|
|
304
|
+
description: plugin.languages.pt.description,
|
|
305
|
+
version: '1.0.0',
|
|
306
|
+
icon: plugin.icon,
|
|
307
|
+
isPaid: price !== undefined && price > 0,
|
|
308
|
+
price,
|
|
309
|
+
authorId: plugin.authorId,
|
|
310
|
+
installationType: 0,
|
|
311
|
+
configurationLink: '/application/detail/{botId}/plugin/{pluginId}',
|
|
312
|
+
pluginType: 'Frontend',
|
|
313
|
+
images: plugin.media.map((m) => ({
|
|
314
|
+
language: 'pt',
|
|
315
|
+
uri: m.uri,
|
|
316
|
+
imageType: m.type === 'image' ? 3 : 1,
|
|
317
|
+
})),
|
|
318
|
+
chargeType: plugin.prices && plugin.prices.length > 1 ? 3 : 1,
|
|
319
|
+
tags: plugin.tags.map((t) => ({ tagValue: t })),
|
|
320
|
+
languages: [
|
|
321
|
+
{
|
|
322
|
+
language: 0,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
language: 1,
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
language: 2,
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
translations: [
|
|
332
|
+
{
|
|
333
|
+
name: plugin.languages.en.name,
|
|
334
|
+
overview: plugin.languages.en.overview,
|
|
335
|
+
description: plugin.languages.en.description,
|
|
336
|
+
language: 'en',
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
name: plugin.languages.es.name,
|
|
340
|
+
overview: plugin.languages.es.overview,
|
|
341
|
+
description: plugin.languages.es.description,
|
|
342
|
+
language: 'es',
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
billings: plugin.prices?.map((p) => ({
|
|
346
|
+
name: p.name,
|
|
347
|
+
description: p.description,
|
|
348
|
+
price: p.price,
|
|
349
|
+
// TODO: I don't know exactly what it means yet
|
|
350
|
+
language: 'pt',
|
|
351
|
+
// TODO: This one too
|
|
352
|
+
currency: 1,
|
|
353
|
+
chargeType: 1,
|
|
354
|
+
isRecommended: p.isRecommended,
|
|
355
|
+
featuresIncluded: JSON.stringify(p.featuresIncluded),
|
|
356
|
+
additionalDescription: p.additionalDescription,
|
|
357
|
+
isActive: true,
|
|
358
|
+
})),
|
|
359
|
+
},
|
|
360
|
+
],
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
opts,
|
|
364
|
+
)
|
|
365
|
+
}
|
|
366
|
+
|
|
224
367
|
/** This route can only be called by an admin user of blip.ai */
|
|
225
368
|
public updatePlugin(
|
|
226
369
|
pluginId: string,
|
|
227
370
|
plugin: Partial<
|
|
228
|
-
Pick<DetailedPlugin, 'name' | 'overview' | 'description' | 'icon' | 'documentation'> & {
|
|
371
|
+
Pick<DetailedPlugin, 'name' | 'overview' | 'description' | 'icon' | 'documentation' | 'price'> & {
|
|
372
|
+
url: string
|
|
373
|
+
}
|
|
229
374
|
>,
|
|
230
375
|
opts?: ConsumeOptions,
|
|
231
376
|
): Promise<void> {
|
|
@@ -241,34 +386,44 @@ export class PluginsNamespace extends Namespace {
|
|
|
241
386
|
icon: plugin.icon,
|
|
242
387
|
website: plugin.documentation,
|
|
243
388
|
url: plugin.url,
|
|
389
|
+
price: plugin.price,
|
|
390
|
+
isPaid: plugin.price !== undefined && plugin.price > 0,
|
|
244
391
|
},
|
|
245
392
|
},
|
|
246
393
|
opts,
|
|
247
394
|
)
|
|
248
395
|
}
|
|
249
396
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
/** This route can only be called by an admin user of blip.ai */
|
|
262
|
-
public addPluginMedia(pluginId: string, type: 'image' | 'video', url: string, opts?: ConsumeOptions) {
|
|
397
|
+
public setPluginBilling(
|
|
398
|
+
pluginId: string,
|
|
399
|
+
billingId: string,
|
|
400
|
+
billing: Omit<PluginBilling, 'billingId' | 'currency' | 'language' | 'featuresIncluded'> & {
|
|
401
|
+
featuresIncluded: Array<{
|
|
402
|
+
icon: string
|
|
403
|
+
description: string
|
|
404
|
+
}>
|
|
405
|
+
},
|
|
406
|
+
opts?: ConsumeOptions,
|
|
407
|
+
) {
|
|
263
408
|
return this.sendCommand(
|
|
264
409
|
{
|
|
265
410
|
method: 'set',
|
|
266
|
-
type: 'application/vnd.iris.plugins.
|
|
267
|
-
uri: uri`/
|
|
411
|
+
type: 'application/vnd.iris.plugins.billing-update+json',
|
|
412
|
+
uri: uri`/billings/${billingId}`,
|
|
268
413
|
resource: {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
414
|
+
blipPluginId: pluginId,
|
|
415
|
+
name: billing.name,
|
|
416
|
+
description: billing.description,
|
|
417
|
+
featuresIncluded: billing.featuresIncluded ? JSON.stringify(billing.featuresIncluded) : undefined,
|
|
418
|
+
isRecommended: billing.isRecommended,
|
|
419
|
+
price: billing.price,
|
|
420
|
+
additionalDescription: billing.additionalDescription,
|
|
421
|
+
// TODO: add params to this
|
|
422
|
+
language: 'pt',
|
|
423
|
+
// TODO: This one too
|
|
424
|
+
currency: 1,
|
|
425
|
+
chargeType: 3,
|
|
426
|
+
isActive: true,
|
|
272
427
|
},
|
|
273
428
|
},
|
|
274
429
|
opts,
|
package/src/types/message.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ThreadItem } from './account.ts'
|
|
1
2
|
import type { JsonObject } from './commons.ts'
|
|
2
3
|
import type { TicketStatus } from './desk.ts'
|
|
3
4
|
import type { Envelope } from './envelope.ts'
|
|
@@ -115,3 +116,26 @@ export const messageToDocument = <Type extends MessageTypes>(
|
|
|
115
116
|
type: message.type,
|
|
116
117
|
value: message.content,
|
|
117
118
|
})
|
|
119
|
+
|
|
120
|
+
/** @description Best effort to figure out the date the message was created */
|
|
121
|
+
export const messageDate = (message: UnknownMessage): Date | undefined => {
|
|
122
|
+
return message.metadata?.['#envelope.storageDate']
|
|
123
|
+
? new Date(message.metadata['#envelope.storageDate'])
|
|
124
|
+
: message.metadata?.date_created
|
|
125
|
+
? new Date(Number(message.metadata.date_created))
|
|
126
|
+
: message.metadata?.['#date_processed']
|
|
127
|
+
? new Date(Number(message.metadata['#date_processed']))
|
|
128
|
+
: undefined
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** @returns Best effort to figure out the actual unique ID, since `message.id` can have collisions */
|
|
132
|
+
export const messageUniqueId = (message: UnknownMessage | ThreadItem) => {
|
|
133
|
+
// Blip doesn't have a standard unique identifier, we need to try multiple sources that may not be present
|
|
134
|
+
return (
|
|
135
|
+
message.metadata?.['#uniqueId'] ??
|
|
136
|
+
message.metadata?.$internalId ??
|
|
137
|
+
message.metadata?.['#messageId'] ??
|
|
138
|
+
message.metadata?.['#envelope.storageDate'] ??
|
|
139
|
+
message.id
|
|
140
|
+
)
|
|
141
|
+
}
|
package/src/types/plugins.ts
CHANGED
|
@@ -33,10 +33,11 @@ export type PluginBilling = {
|
|
|
33
33
|
currency: string
|
|
34
34
|
description: string
|
|
35
35
|
featuresIncluded: string
|
|
36
|
-
isRecommended
|
|
36
|
+
isRecommended?: boolean
|
|
37
37
|
language: string
|
|
38
38
|
name: string
|
|
39
39
|
price: number
|
|
40
|
+
additionalDescription?: string
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
export type PluginSubscription = DetailedPlugin & {
|