@ikatec/digisac-api-sdk 4.5.1 → 4.6.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 +5 -3
- package/dist/apis/answers/AnswersApi.cjs +38 -0
- package/dist/apis/answers/AnswersApi.cjs.map +1 -1
- package/dist/apis/answers/AnswersApi.d.ts +33 -2
- package/dist/apis/answers/AnswersApi.d.ts.map +1 -1
- package/dist/apis/answers/AnswersApi.mjs +38 -0
- package/dist/apis/answers/AnswersApi.mjs.map +1 -1
- package/dist/apis/answers/types.d.ts +64 -1
- package/dist/apis/answers/types.d.ts.map +1 -1
- package/dist/apis/botSimulators/BotSimulatorsApi.cjs +42 -0
- package/dist/apis/botSimulators/BotSimulatorsApi.cjs.map +1 -0
- package/dist/apis/botSimulators/BotSimulatorsApi.d.ts +31 -0
- package/dist/apis/botSimulators/BotSimulatorsApi.d.ts.map +1 -0
- package/dist/apis/botSimulators/BotSimulatorsApi.mjs +41 -0
- package/dist/apis/botSimulators/BotSimulatorsApi.mjs.map +1 -0
- package/dist/apis/botSimulators/index.cjs +4 -0
- package/dist/apis/botSimulators/index.d.ts +3 -0
- package/dist/apis/botSimulators/index.d.ts.map +1 -0
- package/dist/apis/botSimulators/index.mjs +3 -0
- package/dist/apis/botSimulators/types.cjs +0 -0
- package/dist/apis/botSimulators/types.d.ts +73 -0
- package/dist/apis/botSimulators/types.d.ts.map +1 -0
- package/dist/apis/botSimulators/types.mjs +0 -0
- package/dist/apis/botVersions/BotVersionsApi.cjs +25 -0
- package/dist/apis/botVersions/BotVersionsApi.cjs.map +1 -1
- package/dist/apis/botVersions/BotVersionsApi.d.ts +18 -0
- package/dist/apis/botVersions/BotVersionsApi.d.ts.map +1 -1
- package/dist/apis/botVersions/BotVersionsApi.mjs +25 -0
- package/dist/apis/botVersions/BotVersionsApi.mjs.map +1 -1
- package/dist/apis/botVersions/types.d.ts +4 -0
- package/dist/apis/botVersions/types.d.ts.map +1 -1
- package/dist/apis/bots/BotsApi.cjs +99 -4
- package/dist/apis/bots/BotsApi.cjs.map +1 -1
- package/dist/apis/bots/BotsApi.d.ts +78 -5
- package/dist/apis/bots/BotsApi.d.ts.map +1 -1
- package/dist/apis/bots/BotsApi.mjs +99 -4
- package/dist/apis/bots/BotsApi.mjs.map +1 -1
- package/dist/apis/bots/types.d.ts +266 -16
- package/dist/apis/bots/types.d.ts.map +1 -1
- package/dist/apis/index.cjs +3 -0
- package/dist/apis/index.d.ts +1 -0
- package/dist/apis/index.d.ts.map +1 -1
- package/dist/apis/index.mjs +3 -1
- package/dist/apis/questions/QuestionsApi.cjs +15 -0
- package/dist/apis/questions/QuestionsApi.cjs.map +1 -1
- package/dist/apis/questions/QuestionsApi.d.ts +15 -1
- package/dist/apis/questions/QuestionsApi.d.ts.map +1 -1
- package/dist/apis/questions/QuestionsApi.mjs +15 -0
- package/dist/apis/questions/QuestionsApi.mjs.map +1 -1
- package/dist/apis/questions/types.d.ts +25 -5
- package/dist/apis/questions/types.d.ts.map +1 -1
- package/dist/apis/quickReplies/QuickRepliesApi.cjs +16 -0
- package/dist/apis/quickReplies/QuickRepliesApi.cjs.map +1 -1
- package/dist/apis/quickReplies/QuickRepliesApi.d.ts +15 -2
- package/dist/apis/quickReplies/QuickRepliesApi.d.ts.map +1 -1
- package/dist/apis/quickReplies/QuickRepliesApi.mjs +16 -0
- package/dist/apis/quickReplies/QuickRepliesApi.mjs.map +1 -1
- package/dist/apis/quickReplies/types.d.ts +30 -2
- package/dist/apis/quickReplies/types.d.ts.map +1 -1
- package/dist/apis/schedule/ScheduleApi.cjs +37 -2
- package/dist/apis/schedule/ScheduleApi.cjs.map +1 -1
- package/dist/apis/schedule/ScheduleApi.d.ts +30 -3
- package/dist/apis/schedule/ScheduleApi.d.ts.map +1 -1
- package/dist/apis/schedule/ScheduleApi.mjs +37 -2
- package/dist/apis/schedule/ScheduleApi.mjs.map +1 -1
- package/dist/apis/schedule/types.d.ts +58 -11
- package/dist/apis/schedule/types.d.ts.map +1 -1
- package/dist/apis/ticketTopics/TicketTopicsApi.cjs +25 -2
- package/dist/apis/ticketTopics/TicketTopicsApi.cjs.map +1 -1
- package/dist/apis/ticketTopics/TicketTopicsApi.d.ts +18 -4
- package/dist/apis/ticketTopics/TicketTopicsApi.d.ts.map +1 -1
- package/dist/apis/ticketTopics/TicketTopicsApi.mjs +25 -2
- package/dist/apis/ticketTopics/TicketTopicsApi.mjs.map +1 -1
- package/dist/apis/ticketTopics/types.d.ts +22 -1
- package/dist/apis/ticketTopics/types.d.ts.map +1 -1
- package/dist/core/BaseCrudApi.cjs +5 -2
- package/dist/core/BaseCrudApi.cjs.map +1 -1
- package/dist/core/BaseCrudApi.d.ts +7 -4
- package/dist/core/BaseCrudApi.d.ts.map +1 -1
- package/dist/core/BaseCrudApi.mjs +5 -2
- package/dist/core/BaseCrudApi.mjs.map +1 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/incommingWebhooks/index.d.ts +7 -7
- package/dist/incommingWebhooks/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/apis/answers/AnswersApi.test.ts +67 -0
- package/src/apis/answers/AnswersApi.ts +66 -2
- package/src/apis/answers/types.ts +64 -2
- package/src/apis/botSimulators/BotSimulatorsApi.test.ts +58 -0
- package/src/apis/botSimulators/BotSimulatorsApi.ts +57 -0
- package/src/apis/botSimulators/index.ts +2 -0
- package/src/apis/botSimulators/types.ts +72 -0
- package/src/apis/botVersions/BotVersionsApi.test.ts +51 -0
- package/src/apis/botVersions/BotVersionsApi.ts +41 -0
- package/src/apis/botVersions/types.ts +4 -0
- package/src/apis/bots/BotsApi.test.ts +177 -0
- package/src/apis/bots/BotsApi.ts +162 -6
- package/src/apis/bots/types.ts +267 -15
- package/src/apis/index.ts +1 -0
- package/src/apis/payloads.test-d.ts +148 -0
- package/src/apis/questions/QuestionsApi.test.ts +49 -0
- package/src/apis/questions/QuestionsApi.ts +20 -1
- package/src/apis/questions/types.ts +25 -6
- package/src/apis/quickReplies/QuickRepliesApi.test.ts +69 -0
- package/src/apis/quickReplies/QuickRepliesApi.ts +35 -2
- package/src/apis/quickReplies/types.ts +34 -2
- package/src/apis/schedule/ScheduleApi.test.ts +80 -0
- package/src/apis/schedule/ScheduleApi.ts +59 -6
- package/src/apis/schedule/types.ts +66 -11
- package/src/apis/ticketTopics/TicketTopicsApi.test.ts +40 -0
- package/src/apis/ticketTopics/TicketTopicsApi.ts +35 -4
- package/src/apis/ticketTopics/types.ts +26 -1
- package/src/core/BaseCrudApi.ts +9 -5
- package/src/core/types.ts +2 -1
- package/src/incommingWebhooks/index.test-d.ts +9 -0
- package/src/incommingWebhooks/index.ts +7 -7
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import type { ApiClient } from '../../core/ApiClient'
|
|
3
|
+
import { BotVersionsApi } from './BotVersionsApi'
|
|
4
|
+
|
|
5
|
+
// ── Mock client factory ──────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
function createMockClient(): ApiClient {
|
|
8
|
+
return {
|
|
9
|
+
setAccessToken: vi.fn().mockReturnThis(),
|
|
10
|
+
request: vi.fn(),
|
|
11
|
+
get: vi.fn(),
|
|
12
|
+
post: vi.fn(),
|
|
13
|
+
put: vi.fn(),
|
|
14
|
+
patch: vi.fn(),
|
|
15
|
+
delete: vi.fn(),
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
describe('BotVersionsApi', () => {
|
|
22
|
+
let client: ReturnType<typeof createMockClient>
|
|
23
|
+
let api: BotVersionsApi
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
client = createMockClient()
|
|
27
|
+
api = new BotVersionsApi(client)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('getMany lists the versions of a bot', async () => {
|
|
31
|
+
const query = { where: { botId: 'b1' }, paginate: false } as const
|
|
32
|
+
vi.mocked(client.get).mockResolvedValue([{ id: 'v1' }])
|
|
33
|
+
expect(await api.getMany(query)).toEqual([{ id: 'v1' }])
|
|
34
|
+
expect(client.get).toHaveBeenCalledWith(
|
|
35
|
+
`/bot-versions?query=${encodeURIComponent(JSON.stringify(query))}`,
|
|
36
|
+
undefined,
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('getOne filters by id, the replacement of the deprecated getById', async () => {
|
|
41
|
+
vi.mocked(client.get).mockResolvedValue([{ id: 'v1' }])
|
|
42
|
+
expect(await api.getOne({ where: { id: 'v1' } })).toEqual({ id: 'v1' })
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('keeps the deprecated write methods calling their routes', async () => {
|
|
46
|
+
await api.create({ botId: 'b1' })
|
|
47
|
+
expect(client.post).toHaveBeenCalledWith('/bot-versions', { botId: 'b1' }, undefined)
|
|
48
|
+
await api.deleteById('v1')
|
|
49
|
+
expect(client.delete).toHaveBeenCalledWith('/bot-versions/v1', undefined)
|
|
50
|
+
})
|
|
51
|
+
})
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { ApiClient } from '../../core/ApiClient'
|
|
2
2
|
import { BaseCrudApi } from '../../core/BaseCrudApi'
|
|
3
|
+
import type { GetByIdQuery } from '../../core/types'
|
|
3
4
|
import type { BotVersion, CreateBotVersionPayload, UpdateBotVersionPayload } from './types'
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Versions of the bots, with the contexts in the stored map form. The backend only serves the
|
|
8
|
+
* list (`getMany`/`getOne`, filter by `where.botId`; `paginate: false` is honored), under the
|
|
9
|
+
* `bots.view` permission: the versions are created and published by `BotsApi.create`/`updateById`.
|
|
10
|
+
* `include` is dropped (empty whitelist), so the relationships never come.
|
|
11
|
+
*/
|
|
5
12
|
export class BotVersionsApi extends BaseCrudApi<
|
|
6
13
|
BotVersion,
|
|
7
14
|
CreateBotVersionPayload,
|
|
@@ -10,4 +17,38 @@ export class BotVersionsApi extends BaseCrudApi<
|
|
|
10
17
|
constructor(client: ApiClient) {
|
|
11
18
|
super(client, '/bot-versions')
|
|
12
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @deprecated Not served: the backend only serves GET /bot-versions (list): this route answers
|
|
23
|
+
* 404. Use `getOne({ where: { id } })`.
|
|
24
|
+
*/
|
|
25
|
+
override getById(
|
|
26
|
+
id: string,
|
|
27
|
+
query?: GetByIdQuery<BotVersion>,
|
|
28
|
+
headers?: Record<string, string>,
|
|
29
|
+
): Promise<BotVersion> {
|
|
30
|
+
return super.getById(id, query, headers)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** @deprecated Not served: the backend only serves GET /bot-versions (list): this route answers 404. Save the bot through `BotsApi`. */
|
|
34
|
+
override create(
|
|
35
|
+
body: CreateBotVersionPayload,
|
|
36
|
+
headers?: Record<string, string>,
|
|
37
|
+
): Promise<BotVersion> {
|
|
38
|
+
return super.create(body, headers)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** @deprecated Not served: the backend only serves GET /bot-versions (list): this route answers 404. Save the bot through `BotsApi`. */
|
|
42
|
+
override updateById(
|
|
43
|
+
id: string,
|
|
44
|
+
body: UpdateBotVersionPayload,
|
|
45
|
+
headers?: Record<string, string>,
|
|
46
|
+
): Promise<BotVersion> {
|
|
47
|
+
return super.updateById(id, body, headers)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @deprecated Not served: the backend only serves GET /bot-versions (list): this route answers 404. */
|
|
51
|
+
override deleteById(id: string, headers?: Record<string, string>): Promise<BotVersion> {
|
|
52
|
+
return super.deleteById(id, headers)
|
|
53
|
+
}
|
|
13
54
|
}
|
|
@@ -19,11 +19,15 @@ export type BotVersion = {
|
|
|
19
19
|
updatedAt: string
|
|
20
20
|
deletedAt: string | null
|
|
21
21
|
// relationships
|
|
22
|
+
/** @deprecated Never comes: the route drops every `include` (empty whitelist). */
|
|
22
23
|
bot?: Bot
|
|
24
|
+
/** @deprecated Never comes: the route drops every `include` (empty whitelist). */
|
|
23
25
|
createdBy?: User | null
|
|
26
|
+
/** @deprecated Never comes: the route drops every `include` (empty whitelist). */
|
|
24
27
|
publishedBy?: User | null
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
/** @deprecated The route drops every `include` (empty whitelist). */
|
|
27
31
|
export type BotVersionRelationships = 'bot' | 'createdBy' | 'publishedBy'
|
|
28
32
|
|
|
29
33
|
export type CreateBotVersionPayload = {
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import type { ApiClient } from '../../core/ApiClient'
|
|
3
|
+
import { BotsApi } from './BotsApi'
|
|
4
|
+
import type { BotContextInput } from './types'
|
|
5
|
+
|
|
6
|
+
// ── Mock client factory ──────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
function createMockClient(): ApiClient {
|
|
9
|
+
return {
|
|
10
|
+
setAccessToken: vi.fn().mockReturnThis(),
|
|
11
|
+
request: vi.fn(),
|
|
12
|
+
get: vi.fn(),
|
|
13
|
+
post: vi.fn(),
|
|
14
|
+
put: vi.fn(),
|
|
15
|
+
patch: vi.fn(),
|
|
16
|
+
delete: vi.fn(),
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const headers = { 'X-Custom': 'value' }
|
|
21
|
+
|
|
22
|
+
const contexts: BotContextInput[] = [
|
|
23
|
+
{
|
|
24
|
+
id: '@INIT',
|
|
25
|
+
name: 'Contexto inicial',
|
|
26
|
+
triggers: [
|
|
27
|
+
{
|
|
28
|
+
trigger: { type: 'TICKET_OPENED' },
|
|
29
|
+
rules: [
|
|
30
|
+
{
|
|
31
|
+
title: 'abertura',
|
|
32
|
+
conditions: [],
|
|
33
|
+
actions: [{ type: { value: 'SEND_MESSAGE' }, data: { text: 'Olá' } }],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
// ── Tests ────────────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
describe('BotsApi', () => {
|
|
44
|
+
let client: ReturnType<typeof createMockClient>
|
|
45
|
+
let api: BotsApi
|
|
46
|
+
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
client = createMockClient()
|
|
49
|
+
api = new BotsApi(client)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
describe('getMany', () => {
|
|
53
|
+
it('calls client.get with /bots and the query', async () => {
|
|
54
|
+
await api.getMany({ where: { name: 'x' } }, headers)
|
|
55
|
+
expect(client.get).toHaveBeenCalledWith(
|
|
56
|
+
`/bots?query=${encodeURIComponent(JSON.stringify({ where: { name: 'x' } }))}`,
|
|
57
|
+
headers,
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
describe('getOne', () => {
|
|
63
|
+
it('reads the first item of a one-item page', async () => {
|
|
64
|
+
vi.mocked(client.get).mockResolvedValue({ data: [{ id: 'b1' }], total: 1 })
|
|
65
|
+
const result = await api.getOne({ where: { name: 'x' } })
|
|
66
|
+
expect(client.get).toHaveBeenCalledWith(
|
|
67
|
+
`/bots?query=${encodeURIComponent(
|
|
68
|
+
JSON.stringify({ where: { name: 'x' }, perPage: 1, page: 1 }),
|
|
69
|
+
)}`,
|
|
70
|
+
undefined,
|
|
71
|
+
)
|
|
72
|
+
expect(result).toEqual({ id: 'b1' })
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('resolves null on an empty page', async () => {
|
|
76
|
+
vi.mocked(client.get).mockResolvedValue({ data: [], total: 0 })
|
|
77
|
+
expect(await api.getOne()).toBeNull()
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
describe('CRUD', () => {
|
|
82
|
+
it('getById calls client.get with /bots/:id', async () => {
|
|
83
|
+
await api.getById('b1', { include: ['currentBotVersion'] }, headers)
|
|
84
|
+
expect(client.get).toHaveBeenCalledWith(
|
|
85
|
+
`/bots/b1?query=${encodeURIComponent(JSON.stringify({ include: ['currentBotVersion'] }))}`,
|
|
86
|
+
headers,
|
|
87
|
+
)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('create calls client.post with /bots and the contexts list', async () => {
|
|
91
|
+
const body = { name: 'Robô', contexts, isDraft: true }
|
|
92
|
+
await api.create(body, headers)
|
|
93
|
+
expect(client.post).toHaveBeenCalledWith('/bots', body, headers)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('updateById saves the flow or only renames', async () => {
|
|
97
|
+
await api.updateById('b1', { name: 'Robô', contexts })
|
|
98
|
+
expect(client.put).toHaveBeenCalledWith('/bots/b1', { name: 'Robô', contexts }, undefined)
|
|
99
|
+
await api.updateById('b1', { name: 'Novo', onlyUpdateBotName: true })
|
|
100
|
+
expect(client.put).toHaveBeenCalledWith(
|
|
101
|
+
'/bots/b1',
|
|
102
|
+
{ name: 'Novo', onlyUpdateBotName: true },
|
|
103
|
+
undefined,
|
|
104
|
+
)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('deleteById calls client.delete with /bots/:id', async () => {
|
|
108
|
+
vi.mocked(client.delete).mockResolvedValue(false)
|
|
109
|
+
expect(await api.deleteById('b1', headers)).toBe(false)
|
|
110
|
+
expect(client.delete).toHaveBeenCalledWith('/bots/b1', headers)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it("deleteById passes the 'OK' of a fixed backend through", async () => {
|
|
114
|
+
vi.mocked(client.delete).mockResolvedValue('OK')
|
|
115
|
+
expect(await api.deleteById('b1')).toBe('OK')
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
describe('getErrors', () => {
|
|
120
|
+
it('calls client.get with /bots/:id/errors and the filters', async () => {
|
|
121
|
+
const query = { page: 2, perPage: 10, errorCode: 'TIMEOUT', sort: 'serviceName' }
|
|
122
|
+
await api.getErrors('b1', query, headers)
|
|
123
|
+
expect(client.get).toHaveBeenCalledWith(
|
|
124
|
+
`/bots/b1/errors?query=${encodeURIComponent(JSON.stringify(query))}`,
|
|
125
|
+
headers,
|
|
126
|
+
)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('sends no query string without filters', async () => {
|
|
130
|
+
await api.getErrors('b1')
|
|
131
|
+
expect(client.get).toHaveBeenCalledWith('/bots/b1/errors', undefined)
|
|
132
|
+
})
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
describe('triggerSignal', () => {
|
|
136
|
+
it('sends the flag in the body', async () => {
|
|
137
|
+
await api.triggerSignal('b1', 'c1', 'vip', headers)
|
|
138
|
+
expect(client.post).toHaveBeenCalledWith(
|
|
139
|
+
'/bots/b1/trigger-signal/c1',
|
|
140
|
+
{ flag: 'vip' },
|
|
141
|
+
headers,
|
|
142
|
+
)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('sends no body without a flag', async () => {
|
|
146
|
+
await api.triggerSignal('b1', 'c1')
|
|
147
|
+
expect(client.post).toHaveBeenCalledWith('/bots/b1/trigger-signal/c1', undefined, undefined)
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
describe('requestCallback', () => {
|
|
152
|
+
it('posts the response data to /bots/:id/request-callback/:pendingRequestId', async () => {
|
|
153
|
+
await api.requestCallback('b1', 'h1', { status: 'paid' }, headers)
|
|
154
|
+
expect(client.post).toHaveBeenCalledWith(
|
|
155
|
+
'/bots/b1/request-callback/h1',
|
|
156
|
+
{ status: 'paid' },
|
|
157
|
+
headers,
|
|
158
|
+
)
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
describe('suggestAgentPrompt', () => {
|
|
163
|
+
it('posts the agent config to /bots/suggest-agent-prompt', async () => {
|
|
164
|
+
vi.mocked(client.post).mockResolvedValue('Você é um agente...')
|
|
165
|
+
const body = {
|
|
166
|
+
voiceTone: 'formal',
|
|
167
|
+
languageType: 'simple',
|
|
168
|
+
function: 'support',
|
|
169
|
+
companySegment: 'Varejo',
|
|
170
|
+
companySubject: 'Loja',
|
|
171
|
+
companyServices: 'Vendas',
|
|
172
|
+
} as const
|
|
173
|
+
expect(await api.suggestAgentPrompt(body)).toBe('Você é um agente...')
|
|
174
|
+
expect(client.post).toHaveBeenCalledWith('/bots/suggest-agent-prompt', body, undefined)
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
})
|
package/src/apis/bots/BotsApi.ts
CHANGED
|
@@ -1,9 +1,165 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { BaseApi } from '../../core/BaseApi'
|
|
2
|
+
import type {
|
|
3
|
+
GetByIdQuery,
|
|
4
|
+
HasCreate,
|
|
5
|
+
HasDeleteById,
|
|
6
|
+
HasGetById,
|
|
7
|
+
HasUpdateById,
|
|
8
|
+
ListQuery,
|
|
9
|
+
Paginated,
|
|
10
|
+
} from '../../core/types'
|
|
11
|
+
import type {
|
|
12
|
+
Bot,
|
|
13
|
+
BotErrorsQuery,
|
|
14
|
+
BotHistory,
|
|
15
|
+
CreateBotPayload,
|
|
16
|
+
SuggestAgentPromptPayload,
|
|
17
|
+
UpdateBotPayload,
|
|
18
|
+
} from './types'
|
|
4
19
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Bots. The list route always paginates (`paginate: false` is ignored), so this class does not
|
|
22
|
+
* extend `BaseCrudApi`. The contexts travel as a list (`BotContextInput` / `BotParsedContext`),
|
|
23
|
+
* not as the stored map that `BotVersionsApi` serves.
|
|
24
|
+
*
|
|
25
|
+
* `GET /bots/:id/errors/export` is not exposed: it answers a binary xlsx, and `ApiClient` only
|
|
26
|
+
* handles JSON/text bodies.
|
|
27
|
+
*/
|
|
28
|
+
export class BotsApi
|
|
29
|
+
extends BaseApi
|
|
30
|
+
implements
|
|
31
|
+
HasGetById<Bot>,
|
|
32
|
+
HasCreate<Bot, CreateBotPayload>,
|
|
33
|
+
HasUpdateById<Bot, UpdateBotPayload>,
|
|
34
|
+
HasDeleteById<'OK' | false>
|
|
35
|
+
{
|
|
36
|
+
public readonly basePath = '/bots'
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Lists the bots of the account. Always paginated, even with `paginate: false`.
|
|
40
|
+
* @permissions bots.view
|
|
41
|
+
*/
|
|
42
|
+
getMany(query?: ListQuery<Bot>, headers?: Record<string, string>): Promise<Paginated<Bot>> {
|
|
43
|
+
return this.client.get<Paginated<Bot>>(`${this.basePath}${this.toQueryString(query)}`, headers)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns the first bot matching the query, or `null` when none match.
|
|
48
|
+
* @permissions bots.view
|
|
49
|
+
*/
|
|
50
|
+
async getOne(query?: ListQuery<Bot>, headers?: Record<string, string>): Promise<Bot | null> {
|
|
51
|
+
const page = await this.getMany({ ...query, perPage: 1, page: 1 }, headers)
|
|
52
|
+
return page?.data?.[0] ?? null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns a bot by ID, with `defaultContexts` (the stored map, as a JSON string). An unknown id
|
|
57
|
+
* answers 500, not an empty body.
|
|
58
|
+
* @permissions bots.view
|
|
59
|
+
*/
|
|
60
|
+
getById(id: string, query?: GetByIdQuery<Bot>, headers?: Record<string, string>): Promise<Bot> {
|
|
61
|
+
return this.client.get<Bot>(`${this.basePath}/${id}${this.toQueryString(query)}`, headers)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Creates a bot and its first version (published, or a draft with `isDraft`). A duplicate name
|
|
66
|
+
* answers 409, unless the account allows duplicate names. Send `flowJson` with `edges`, or the
|
|
67
|
+
* bot never sends a message (SD-2323).
|
|
68
|
+
* @permissions bots.create
|
|
69
|
+
*/
|
|
70
|
+
create(body: CreateBotPayload, headers?: Record<string, string>): Promise<Bot> {
|
|
71
|
+
return this.client.post<Bot, CreateBotPayload>(this.basePath, body, headers)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Saves the flow (publishing a version, or into the draft with `isDraft`), or only renames the
|
|
76
|
+
* bot with `onlyUpdateBotName`. Resolves to the bot with `defaultContexts` as an object.
|
|
77
|
+
* @permissions bots.view OR bots.update
|
|
78
|
+
*/
|
|
79
|
+
updateById(id: string, body: UpdateBotPayload, headers?: Record<string, string>): Promise<Bot> {
|
|
80
|
+
return this.client.put<Bot, UpdateBotPayload>(`${this.basePath}/${id}`, body, headers)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Deletes a bot and its versions (hard delete). Today resolves to `false` even when the bot was
|
|
85
|
+
* deleted (the backend destroy returns nothing); it becomes `'OK'` once the destroy returns the
|
|
86
|
+
* bot, as in the other routes. Do not read the result as success or failure. An unknown id
|
|
87
|
+
* answers 500.
|
|
88
|
+
* @permissions bots.view OR bots.destroy
|
|
89
|
+
*/
|
|
90
|
+
deleteById(id: string, headers?: Record<string, string>): Promise<'OK' | false> {
|
|
91
|
+
return this.client.delete<'OK' | false>(`${this.basePath}/${id}`, headers)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Lists the failed steps of the bot runs, newest first by default. An unknown bot answers an
|
|
96
|
+
* empty page.
|
|
97
|
+
* @permissions bots.view
|
|
98
|
+
*/
|
|
99
|
+
getErrors(
|
|
100
|
+
id: string,
|
|
101
|
+
query?: BotErrorsQuery,
|
|
102
|
+
headers?: Record<string, string>,
|
|
103
|
+
): Promise<Paginated<BotHistory>> {
|
|
104
|
+
return this.client.get<Paginated<BotHistory>>(
|
|
105
|
+
`${this.basePath}/${id}/errors${this.toQueryString(query)}`,
|
|
106
|
+
headers,
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Fires the `API_SIGNAL` trigger of the bot for the contact, with an optional `flag` (read by
|
|
112
|
+
* the `api_signal_flag` condition). Asynchronous: always resolves with no content, and the
|
|
113
|
+
* worker only runs it when the contact has an open ticket.
|
|
114
|
+
* @permissions bots.view
|
|
115
|
+
*/
|
|
116
|
+
triggerSignal(
|
|
117
|
+
botId: string,
|
|
118
|
+
contactId: string,
|
|
119
|
+
flag?: string,
|
|
120
|
+
headers?: Record<string, string>,
|
|
121
|
+
): Promise<void> {
|
|
122
|
+
return this.client.post<void, { flag: string } | undefined>(
|
|
123
|
+
`${this.basePath}/${botId}/trigger-signal/${contactId}`,
|
|
124
|
+
flag === undefined ? undefined : { flag },
|
|
125
|
+
headers,
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Answers a pending asynchronous `HTTP_REQUEST` action: `body` becomes the response the bot
|
|
131
|
+
* reads. Resolves with no content. An unknown history answers 404; a history that is not
|
|
132
|
+
* `PENDING`, or of another bot, answers 400. JSON bodies only (the route also takes text, XML
|
|
133
|
+
* and CSV), up to 250 KB.
|
|
134
|
+
* @permissions bots.view
|
|
135
|
+
*/
|
|
136
|
+
requestCallback(
|
|
137
|
+
id: string,
|
|
138
|
+
pendingRequestId: string,
|
|
139
|
+
body: unknown,
|
|
140
|
+
headers?: Record<string, string>,
|
|
141
|
+
): Promise<void> {
|
|
142
|
+
return this.client.post<void, unknown>(
|
|
143
|
+
`${this.basePath}/${id}/request-callback/${pendingRequestId}`,
|
|
144
|
+
body,
|
|
145
|
+
headers,
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Generates a prompt for an AI agent of the bot. COSTS one AI agent credit of the account and
|
|
151
|
+
* calls OpenAI. No permission check: any authenticated user. A missing field answers 400; an
|
|
152
|
+
* option outside the lists, or the AI agent limit of the account reached
|
|
153
|
+
* (`Agent limit reached`), answers 500.
|
|
154
|
+
*/
|
|
155
|
+
suggestAgentPrompt(
|
|
156
|
+
body: SuggestAgentPromptPayload,
|
|
157
|
+
headers?: Record<string, string>,
|
|
158
|
+
): Promise<string> {
|
|
159
|
+
return this.client.post<string, SuggestAgentPromptPayload>(
|
|
160
|
+
`${this.basePath}/suggest-agent-prompt`,
|
|
161
|
+
body,
|
|
162
|
+
headers,
|
|
163
|
+
)
|
|
8
164
|
}
|
|
9
165
|
}
|