@unboundcx/sdk 4.13.95 → 4.13.97
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/package.json +1 -1
- package/services/ai/assist.js +4 -4
- package/services/ai/models.js +18 -0
- package/services/ai.js +9 -2
- package/services/reportingAgents.js +9 -7
- package/services/taskRouter/CcBotsService.js +247 -0
- package/services/taskRouter/TaskRouterService.js +2 -0
- package/services/taskRouter/TaskService.js +65 -2
- package/services/webchat.js +94 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unboundcx/sdk",
|
|
3
|
-
"version": "4.13.
|
|
3
|
+
"version": "4.13.97",
|
|
4
4
|
"description": "Official JavaScript SDK for the Unbound API - A comprehensive toolkit for integrating with Unbound's communication, AI, and data management services",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
package/services/ai/assist.js
CHANGED
|
@@ -80,9 +80,9 @@ export class AssistService {
|
|
|
80
80
|
* @example
|
|
81
81
|
* const { suggestions } = await sdk.ai.assist.listSuggestions({ queueId: 'queue_123', limit: 50 });
|
|
82
82
|
*/
|
|
83
|
-
async listSuggestions({ queueId, limit } = {}) {
|
|
83
|
+
async listSuggestions({ queueId, limit, actorKind } = {}) {
|
|
84
84
|
const result = await internalRequest(this.sdk, '/ai/assist/suggestions', 'GET', {
|
|
85
|
-
query: { queueId, limit },
|
|
85
|
+
query: { queueId, limit, actorKind },
|
|
86
86
|
});
|
|
87
87
|
return result;
|
|
88
88
|
}
|
|
@@ -97,9 +97,9 @@ export class AssistService {
|
|
|
97
97
|
* @example
|
|
98
98
|
* const stats = await sdk.ai.assist.suggestionStats({ queueId: 'queue_123' });
|
|
99
99
|
*/
|
|
100
|
-
async suggestionStats({ queueId } = {}) {
|
|
100
|
+
async suggestionStats({ queueId, actorKind } = {}) {
|
|
101
101
|
const result = await internalRequest(this.sdk, '/ai/assist/suggestions/stats', 'GET', {
|
|
102
|
-
query: { queueId },
|
|
102
|
+
query: { queueId, actorKind },
|
|
103
103
|
});
|
|
104
104
|
return result;
|
|
105
105
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { internalRequest } from '../../base.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Platform model catalog — product names only (no vendor provider/model).
|
|
5
|
+
*/
|
|
6
|
+
export class ModelsService {
|
|
7
|
+
constructor(sdk) {
|
|
8
|
+
this.sdk = sdk;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* List platform models available to this account.
|
|
13
|
+
* @returns {Promise<Object>} { models, features, recommended }
|
|
14
|
+
*/
|
|
15
|
+
async list() {
|
|
16
|
+
return internalRequest(this.sdk, '/ai/models', 'GET');
|
|
17
|
+
}
|
|
18
|
+
}
|
package/services/ai.js
CHANGED
|
@@ -4,6 +4,7 @@ import { BattleCardsService } from './ai/battleCards.js';
|
|
|
4
4
|
import { AssistService } from './ai/assist.js';
|
|
5
5
|
import { VocabularyService } from './ai/vocabulary.js';
|
|
6
6
|
import { EmailService } from './ai/email.js';
|
|
7
|
+
import { ModelsService } from './ai/models.js';
|
|
7
8
|
import { translate as translateItems } from './ai/translate.js';
|
|
8
9
|
import {
|
|
9
10
|
getSettings as getAiSettings,
|
|
@@ -22,6 +23,7 @@ export class AIService {
|
|
|
22
23
|
this.assist = new AssistService(sdk);
|
|
23
24
|
this.vocabulary = new VocabularyService(sdk);
|
|
24
25
|
this.email = new EmailService(sdk);
|
|
26
|
+
this.models = new ModelsService(sdk);
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
/**
|
|
@@ -964,14 +966,16 @@ export class SpeechToTextService {
|
|
|
964
966
|
* @param {Object} message - Message data
|
|
965
967
|
* @param {string} message.text - Transcribed text
|
|
966
968
|
* @param {Object} [message.transcriptionJson] - Full transcription metadata
|
|
969
|
+
* @param {string} [message.transcriptionJson.source] - 'tts' for synthetic bot ingest
|
|
967
970
|
* @param {number} [message.duration] - Duration of this segment in seconds
|
|
968
|
-
* @param {number} [message.confidence] - Confidence score (0-1)
|
|
971
|
+
* @param {number} [message.confidence] - Confidence score (0-1). Omit for TTS.
|
|
969
972
|
* @param {string} [message.languageCode] - Language code for this segment
|
|
970
973
|
* @param {string} [message.userId] - User associated with this message
|
|
971
974
|
* @param {string} [message.role] - Speaker role
|
|
972
975
|
* @param {string} [message.sipCallId] - SIP call identifier
|
|
973
976
|
* @param {string} [message.side] - Stream side ('send' or 'recv')
|
|
974
977
|
* @param {string} [message.bridgeId] - bridge id
|
|
978
|
+
* @param {string} [message.taskId] - Task id (stamped on the transcription session)
|
|
975
979
|
* @param {Object} [message.sentiment] - Sentiment analysis data
|
|
976
980
|
* @param {number} [message.sentiment.score] - Overall sentiment score (-100 to +100)
|
|
977
981
|
* @param {number} [message.sentiment.previousScore] - Previous sentiment score (-100 to +100)
|
|
@@ -999,13 +1003,14 @@ export class SpeechToTextService {
|
|
|
999
1003
|
sipCallId,
|
|
1000
1004
|
side,
|
|
1001
1005
|
bridgeId,
|
|
1006
|
+
taskId,
|
|
1002
1007
|
sentiment,
|
|
1003
1008
|
videoRoomId,
|
|
1004
1009
|
videoParticipantId,
|
|
1005
1010
|
},
|
|
1006
1011
|
) {
|
|
1007
1012
|
this.sdk.validateParams(
|
|
1008
|
-
{ messageId, sessionId, text, bridgeId },
|
|
1013
|
+
{ messageId, sessionId, text, bridgeId, taskId },
|
|
1009
1014
|
{
|
|
1010
1015
|
sessionId: { type: 'string', required: true },
|
|
1011
1016
|
messageId: { type: 'string', required: false },
|
|
@@ -1020,6 +1025,7 @@ export class SpeechToTextService {
|
|
|
1020
1025
|
sipCallId: { type: 'string', required: false },
|
|
1021
1026
|
side: { type: 'string', required: false },
|
|
1022
1027
|
bridgeId: { type: 'string', required: false },
|
|
1028
|
+
taskId: { type: 'string', required: false },
|
|
1023
1029
|
sentiment: { type: 'object', required: false },
|
|
1024
1030
|
videoRoomId: { type: 'string', required: false },
|
|
1025
1031
|
videoParticipantId: { type: 'string', required: false },
|
|
@@ -1040,6 +1046,7 @@ export class SpeechToTextService {
|
|
|
1040
1046
|
sipCallId,
|
|
1041
1047
|
side,
|
|
1042
1048
|
bridgeId,
|
|
1049
|
+
taskId,
|
|
1043
1050
|
sentiment,
|
|
1044
1051
|
videoRoomId,
|
|
1045
1052
|
videoParticipantId,
|
|
@@ -19,19 +19,19 @@ export class ReportingAgentsService {
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Agent summary rows (§6 metrics), grouped by agent, queue, or team.
|
|
22
|
-
* @param {Object} params - { from, to, userIds, queueIds, teamIds, groupBy }
|
|
22
|
+
* @param {Object} params - { from, to, userIds, queueIds, teamIds, groupBy, agentKind }
|
|
23
23
|
* @returns {Promise<Object>} { columns, rows, definitions, meta }
|
|
24
24
|
* @example
|
|
25
25
|
* await sdk.reporting.agents.summary({ from, to, groupBy: 'team' });
|
|
26
26
|
*/
|
|
27
|
-
async summary({ from, to, userIds, queueIds, teamIds, groupBy } = {}) {
|
|
27
|
+
async summary({ from, to, userIds, queueIds, teamIds, groupBy, agentKind } = {}) {
|
|
28
28
|
this.sdk.validateParams(
|
|
29
29
|
{ from, to },
|
|
30
30
|
{ from: { type: 'string', required: true }, to: { type: 'string', required: true } },
|
|
31
31
|
);
|
|
32
32
|
return internalRequest(
|
|
33
33
|
this.sdk,
|
|
34
|
-
`/reporting/agents/summary${queryString({ from, to, userIds, queueIds, teamIds, groupBy })}`,
|
|
34
|
+
`/reporting/agents/summary${queryString({ from, to, userIds, queueIds, teamIds, groupBy, agentKind })}`,
|
|
35
35
|
'GET',
|
|
36
36
|
);
|
|
37
37
|
}
|
|
@@ -90,19 +90,19 @@ export class ReportingAgentsService {
|
|
|
90
90
|
/**
|
|
91
91
|
* Per-agent per-local-day timesheet rows (net paid hours), plus one
|
|
92
92
|
* additive-sum row per agent (`agents`) for grouped totals.
|
|
93
|
-
* @param {Object} params - { from, to, userIds, teamIds }
|
|
93
|
+
* @param {Object} params - { from, to, userIds, teamIds, agentKind }
|
|
94
94
|
* @returns {Promise<Object>} { columns, rows, agents }
|
|
95
95
|
* @example
|
|
96
96
|
* await sdk.reporting.agents.timesheet({ from, to, userIds: ['u1'] });
|
|
97
97
|
*/
|
|
98
|
-
async timesheet({ from, to, userIds, teamIds } = {}) {
|
|
98
|
+
async timesheet({ from, to, userIds, teamIds, agentKind } = {}) {
|
|
99
99
|
this.sdk.validateParams(
|
|
100
100
|
{ from, to },
|
|
101
101
|
{ from: { type: 'string', required: true }, to: { type: 'string', required: true } },
|
|
102
102
|
);
|
|
103
103
|
return internalRequest(
|
|
104
104
|
this.sdk,
|
|
105
|
-
`/reporting/agents/timesheet${queryString({ from, to, userIds, teamIds })}`,
|
|
105
|
+
`/reporting/agents/timesheet${queryString({ from, to, userIds, teamIds, agentKind })}`,
|
|
106
106
|
'GET',
|
|
107
107
|
);
|
|
108
108
|
}
|
|
@@ -111,7 +111,7 @@ export class ReportingAgentsService {
|
|
|
111
111
|
* CSV export of any of the four views above. For view: 'timesheet', pass
|
|
112
112
|
* `totals: true` to get one additive-sum row per agent instead of the
|
|
113
113
|
* flat per-agent-per-day rows.
|
|
114
|
-
* @param {Object} params - { view: 'summary'|'states'|'interactions'|'timesheet', from, to, userId, userIds, queueIds, teamIds, groupBy, totals }
|
|
114
|
+
* @param {Object} params - { view: 'summary'|'states'|'interactions'|'timesheet', from, to, userId, userIds, queueIds, teamIds, groupBy, agentKind, totals }
|
|
115
115
|
* @returns {Promise<Object>} raw CSV response (transport-dependent)
|
|
116
116
|
* @example
|
|
117
117
|
* await sdk.reporting.agents.export({ view: 'timesheet', from, to });
|
|
@@ -126,6 +126,7 @@ export class ReportingAgentsService {
|
|
|
126
126
|
queueIds,
|
|
127
127
|
teamIds,
|
|
128
128
|
groupBy,
|
|
129
|
+
agentKind,
|
|
129
130
|
totals,
|
|
130
131
|
} = {}) {
|
|
131
132
|
this.sdk.validateParams(
|
|
@@ -141,6 +142,7 @@ export class ReportingAgentsService {
|
|
|
141
142
|
queueIds,
|
|
142
143
|
teamIds,
|
|
143
144
|
groupBy,
|
|
145
|
+
agentKind,
|
|
144
146
|
totals: totals ? '1' : undefined,
|
|
145
147
|
format: 'csv',
|
|
146
148
|
});
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { internalRequest } from '../../base.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CC worker bots — Setup → Bots (K21). Not Graham /chat/bots.
|
|
5
|
+
*/
|
|
6
|
+
export class CcBotsService {
|
|
7
|
+
constructor(sdk) {
|
|
8
|
+
this.sdk = sdk;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Platform defaults for When to get help + model pickers.
|
|
13
|
+
* @returns {Promise<Object>}
|
|
14
|
+
*/
|
|
15
|
+
async defaults() {
|
|
16
|
+
return internalRequest(this.sdk, '/taskRouter/ccBots/defaults', 'GET');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* List CC worker bots for the account.
|
|
21
|
+
* @returns {Promise<Object>} { results }
|
|
22
|
+
*/
|
|
23
|
+
async list() {
|
|
24
|
+
return internalRequest(this.sdk, '/taskRouter/ccBots', 'GET');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a named CC worker bot (user + worker, capacity 1).
|
|
29
|
+
* @param {Object} params
|
|
30
|
+
* @param {string} params.name
|
|
31
|
+
* @param {string} params.slug
|
|
32
|
+
* @param {string} [params.soulMd]
|
|
33
|
+
* @param {string} [params.modelId] platform catalog id
|
|
34
|
+
* @param {string} [params.provider]
|
|
35
|
+
* @param {string} [params.model]
|
|
36
|
+
* @param {string} [params.queueId]
|
|
37
|
+
* @param {string} [params.mailboxId]
|
|
38
|
+
* @returns {Promise<Object>}
|
|
39
|
+
*/
|
|
40
|
+
async create({
|
|
41
|
+
name,
|
|
42
|
+
slug,
|
|
43
|
+
soulMd,
|
|
44
|
+
modelId,
|
|
45
|
+
provider,
|
|
46
|
+
model,
|
|
47
|
+
queueId,
|
|
48
|
+
mailboxId,
|
|
49
|
+
} = {}) {
|
|
50
|
+
this.sdk.validateParams(
|
|
51
|
+
{ name, slug },
|
|
52
|
+
{
|
|
53
|
+
name: { type: 'string', required: true },
|
|
54
|
+
slug: { type: 'string', required: true },
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
const body = { name, slug };
|
|
58
|
+
if (soulMd !== undefined) body.soulMd = soulMd;
|
|
59
|
+
if (modelId !== undefined) body.modelId = modelId;
|
|
60
|
+
if (provider !== undefined) body.provider = provider;
|
|
61
|
+
if (model !== undefined) body.model = model;
|
|
62
|
+
if (queueId !== undefined) body.queueId = queueId;
|
|
63
|
+
if (mailboxId !== undefined) body.mailboxId = mailboxId;
|
|
64
|
+
return internalRequest(this.sdk, '/taskRouter/ccBots', 'POST', { body });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get one CC worker bot.
|
|
69
|
+
* @param {string} id
|
|
70
|
+
* @returns {Promise<Object>}
|
|
71
|
+
*/
|
|
72
|
+
async get(id) {
|
|
73
|
+
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
74
|
+
return internalRequest(this.sdk, `/taskRouter/ccBots/${id}`, 'GET');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Patch name / soul / model / pause kill-switch.
|
|
79
|
+
* @param {string} id
|
|
80
|
+
* @param {Object} [params]
|
|
81
|
+
* @returns {Promise<Object>}
|
|
82
|
+
*/
|
|
83
|
+
async update(id, params = {}) {
|
|
84
|
+
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
85
|
+
const body = {};
|
|
86
|
+
for (const key of [
|
|
87
|
+
'name',
|
|
88
|
+
'soulMd',
|
|
89
|
+
'additionalDetails',
|
|
90
|
+
'provider',
|
|
91
|
+
'model',
|
|
92
|
+
'modelId',
|
|
93
|
+
'mediaProvider',
|
|
94
|
+
'mediaModel',
|
|
95
|
+
'voiceId',
|
|
96
|
+
'profilePhoto',
|
|
97
|
+
'paused',
|
|
98
|
+
'acceptChannels',
|
|
99
|
+
'useChannels',
|
|
100
|
+
'groupId',
|
|
101
|
+
'groupOverrides',
|
|
102
|
+
'inherit',
|
|
103
|
+
]) {
|
|
104
|
+
if (key in params) body[key] = params[key];
|
|
105
|
+
}
|
|
106
|
+
return internalRequest(this.sdk, `/taskRouter/ccBots/${id}`, 'PATCH', {
|
|
107
|
+
body,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Clone a CC worker bot (new user + worker, copied config).
|
|
113
|
+
* @param {string} id
|
|
114
|
+
* @param {Object} [params]
|
|
115
|
+
* @param {string} [params.name]
|
|
116
|
+
* @returns {Promise<Object>}
|
|
117
|
+
*/
|
|
118
|
+
async clone(id, { name } = {}) {
|
|
119
|
+
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
120
|
+
const body = {};
|
|
121
|
+
if (name !== undefined) body.name = name;
|
|
122
|
+
return internalRequest(this.sdk, `/taskRouter/ccBots/${id}/clone`, 'POST', {
|
|
123
|
+
body,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Enable or disable many CC bots.
|
|
129
|
+
* @param {Object} params
|
|
130
|
+
* @param {string[]} params.ids
|
|
131
|
+
* @param {boolean} params.paused
|
|
132
|
+
* @returns {Promise<Object>}
|
|
133
|
+
*/
|
|
134
|
+
async bulkPaused({ ids, paused } = {}) {
|
|
135
|
+
this.sdk.validateParams(
|
|
136
|
+
{ ids, paused },
|
|
137
|
+
{
|
|
138
|
+
ids: { type: 'object', required: true },
|
|
139
|
+
paused: { type: 'boolean', required: true },
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
return internalRequest(this.sdk, '/taskRouter/ccBots/bulkPaused', 'POST', {
|
|
143
|
+
body: { ids, paused },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* List bot groups.
|
|
149
|
+
* @returns {Promise<Object>}
|
|
150
|
+
*/
|
|
151
|
+
async listGroups() {
|
|
152
|
+
return internalRequest(this.sdk, '/taskRouter/ccBotGroups', 'GET');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Create a bot group.
|
|
157
|
+
* @param {Object} params
|
|
158
|
+
* @returns {Promise<Object>}
|
|
159
|
+
*/
|
|
160
|
+
async createGroup(params = {}) {
|
|
161
|
+
this.sdk.validateParams(
|
|
162
|
+
{ name: params.name },
|
|
163
|
+
{ name: { type: 'string', required: true } },
|
|
164
|
+
);
|
|
165
|
+
return internalRequest(this.sdk, '/taskRouter/ccBotGroups', 'POST', {
|
|
166
|
+
body: params,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Get one bot group.
|
|
172
|
+
* @param {string} id
|
|
173
|
+
* @returns {Promise<Object>}
|
|
174
|
+
*/
|
|
175
|
+
async getGroup(id) {
|
|
176
|
+
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
177
|
+
return internalRequest(this.sdk, `/taskRouter/ccBotGroups/${id}`, 'GET');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Patch a bot group (propagates inherited fields to member bots).
|
|
182
|
+
* @param {string} id
|
|
183
|
+
* @param {Object} [params]
|
|
184
|
+
* @returns {Promise<Object>}
|
|
185
|
+
*/
|
|
186
|
+
async updateGroup(id, params = {}) {
|
|
187
|
+
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
188
|
+
const body = {};
|
|
189
|
+
for (const key of [
|
|
190
|
+
'name',
|
|
191
|
+
'soulMd',
|
|
192
|
+
'provider',
|
|
193
|
+
'model',
|
|
194
|
+
'modelId',
|
|
195
|
+
'mediaProvider',
|
|
196
|
+
'mediaModel',
|
|
197
|
+
'voiceId',
|
|
198
|
+
'paused',
|
|
199
|
+
'acceptChannels',
|
|
200
|
+
'useChannels',
|
|
201
|
+
'queueIds',
|
|
202
|
+
'skillIds',
|
|
203
|
+
]) {
|
|
204
|
+
if (key in params) body[key] = params[key];
|
|
205
|
+
}
|
|
206
|
+
return internalRequest(this.sdk, `/taskRouter/ccBotGroups/${id}`, 'PATCH', {
|
|
207
|
+
body,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Soft-delete a bot group and detach members.
|
|
213
|
+
* @param {string} id
|
|
214
|
+
* @returns {Promise<Object>}
|
|
215
|
+
*/
|
|
216
|
+
async deleteGroup(id) {
|
|
217
|
+
this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
|
|
218
|
+
return internalRequest(
|
|
219
|
+
this.sdk,
|
|
220
|
+
`/taskRouter/ccBotGroups/${id}`,
|
|
221
|
+
'DELETE',
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Login a CC bot into a queue (queueUsers + worker addQueues).
|
|
227
|
+
* @param {string} id
|
|
228
|
+
* @param {Object} params
|
|
229
|
+
* @param {string} params.queueId
|
|
230
|
+
* @returns {Promise<Object>}
|
|
231
|
+
*/
|
|
232
|
+
async addToQueue(id, { queueId } = {}) {
|
|
233
|
+
this.sdk.validateParams(
|
|
234
|
+
{ id, queueId },
|
|
235
|
+
{
|
|
236
|
+
id: { type: 'string', required: true },
|
|
237
|
+
queueId: { type: 'string', required: true },
|
|
238
|
+
},
|
|
239
|
+
);
|
|
240
|
+
return internalRequest(
|
|
241
|
+
this.sdk,
|
|
242
|
+
`/taskRouter/ccBots/${id}/queues`,
|
|
243
|
+
'POST',
|
|
244
|
+
{ body: { queueId } },
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
@@ -4,6 +4,7 @@ import { MetricsService } from './MetricsService.js';
|
|
|
4
4
|
import { CCService } from './CCService.js';
|
|
5
5
|
import { OfferService } from './OfferService.js';
|
|
6
6
|
import { ParticipantService } from './ParticipantService.js';
|
|
7
|
+
import { CcBotsService } from './CcBotsService.js';
|
|
7
8
|
|
|
8
9
|
export class TaskRouterService {
|
|
9
10
|
constructor(sdk) {
|
|
@@ -14,5 +15,6 @@ export class TaskRouterService {
|
|
|
14
15
|
this.cc = new CCService(sdk);
|
|
15
16
|
this.offer = new OfferService(sdk);
|
|
16
17
|
this.participants = new ParticipantService(sdk);
|
|
18
|
+
this.ccBots = new CcBotsService(sdk);
|
|
17
19
|
}
|
|
18
20
|
}
|
|
@@ -409,6 +409,64 @@ export class TaskService {
|
|
|
409
409
|
return result;
|
|
410
410
|
}
|
|
411
411
|
|
|
412
|
+
/**
|
|
413
|
+
* Unassign a task back to pending (worker unlinked). Used by CC bot
|
|
414
|
+
* drain for short-lived connected tasks — not park.
|
|
415
|
+
*
|
|
416
|
+
* @param {Object} options
|
|
417
|
+
* @param {string} options.taskId
|
|
418
|
+
* @returns {Promise<Object>}
|
|
419
|
+
*/
|
|
420
|
+
async unassign(options = {}) {
|
|
421
|
+
const { taskId, userId } = options;
|
|
422
|
+
|
|
423
|
+
this.sdk.validateParams(
|
|
424
|
+
{ taskId, userId },
|
|
425
|
+
{
|
|
426
|
+
taskId: { type: 'string', required: true },
|
|
427
|
+
userId: { type: 'string', required: false },
|
|
428
|
+
},
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
const params = { body: { taskId } };
|
|
432
|
+
if (userId) params.body.userId = userId;
|
|
433
|
+
|
|
434
|
+
return internalRequest(
|
|
435
|
+
this.sdk,
|
|
436
|
+
'/taskRouter/tasks/unassign',
|
|
437
|
+
'PUT',
|
|
438
|
+
params,
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Staff-only internal note on a task (webchat/SMS/voice feed, or
|
|
444
|
+
* timeline). Never sent to the customer.
|
|
445
|
+
*
|
|
446
|
+
* @param {Object} options
|
|
447
|
+
* @param {string} options.taskId
|
|
448
|
+
* @param {string} options.message
|
|
449
|
+
* @returns {Promise<Object>}
|
|
450
|
+
*/
|
|
451
|
+
async note(options = {}) {
|
|
452
|
+
const { taskId, message } = options;
|
|
453
|
+
|
|
454
|
+
this.sdk.validateParams(
|
|
455
|
+
{ taskId, message },
|
|
456
|
+
{
|
|
457
|
+
taskId: { type: 'string', required: true },
|
|
458
|
+
message: { type: 'string', required: true },
|
|
459
|
+
},
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
return internalRequest(
|
|
463
|
+
this.sdk,
|
|
464
|
+
`/taskRouter/tasks/${taskId}/notes`,
|
|
465
|
+
'POST',
|
|
466
|
+
{ body: { message } },
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
|
|
412
470
|
/**
|
|
413
471
|
* Change task priority
|
|
414
472
|
* Modify the priority of a task to increase or decrease its routing priority.
|
|
@@ -730,12 +788,13 @@ export class TaskService {
|
|
|
730
788
|
* console.log(result.taskId); // "task456"
|
|
731
789
|
*/
|
|
732
790
|
async complete(options = {}) {
|
|
733
|
-
const { taskId } = options;
|
|
791
|
+
const { taskId, completedReason } = options;
|
|
734
792
|
|
|
735
793
|
this.sdk.validateParams(
|
|
736
|
-
{ taskId },
|
|
794
|
+
{ taskId, completedReason },
|
|
737
795
|
{
|
|
738
796
|
taskId: { type: 'string', required: true },
|
|
797
|
+
completedReason: { type: 'string', required: false },
|
|
739
798
|
},
|
|
740
799
|
);
|
|
741
800
|
|
|
@@ -745,6 +804,10 @@ export class TaskService {
|
|
|
745
804
|
},
|
|
746
805
|
};
|
|
747
806
|
|
|
807
|
+
if (completedReason) {
|
|
808
|
+
params.body.completedReason = completedReason;
|
|
809
|
+
}
|
|
810
|
+
|
|
748
811
|
const result = await internalRequest(this.sdk,
|
|
749
812
|
'/taskRouter/tasks/complete',
|
|
750
813
|
'PUT',
|
package/services/webchat.js
CHANGED
|
@@ -281,4 +281,98 @@ export class WebchatService {
|
|
|
281
281
|
// instance with just `{namespace}` and uses only this namespace.
|
|
282
282
|
this.visitor = new WebchatVisitorService(sdk);
|
|
283
283
|
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Send an agent webchat message on a task. The server resolves the
|
|
287
|
+
* widget + engagement from the task — callers must not UOQL
|
|
288
|
+
* webchatConversations for widgetId.
|
|
289
|
+
*
|
|
290
|
+
* @param {Object} options
|
|
291
|
+
* @param {string} options.taskId
|
|
292
|
+
* @param {string} [options.message]
|
|
293
|
+
* @param {Object} [options.media]
|
|
294
|
+
* @param {Object|Array} [options.card]
|
|
295
|
+
* @returns {Promise<Object>}
|
|
296
|
+
*/
|
|
297
|
+
async sendOnTask(options = {}) {
|
|
298
|
+
const { taskId, message, media, card } = options;
|
|
299
|
+
|
|
300
|
+
this.sdk.validateParams(
|
|
301
|
+
{ taskId, message, media, card },
|
|
302
|
+
{
|
|
303
|
+
taskId: { type: 'string', required: true },
|
|
304
|
+
message: { type: 'string', required: false },
|
|
305
|
+
media: { type: 'object', required: false },
|
|
306
|
+
card: { type: 'object', required: false },
|
|
307
|
+
},
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
const body = {};
|
|
311
|
+
if (message !== undefined) body.message = message;
|
|
312
|
+
if (media !== undefined) body.media = media;
|
|
313
|
+
if (card !== undefined) body.card = card;
|
|
314
|
+
|
|
315
|
+
return internalRequest(
|
|
316
|
+
this.sdk,
|
|
317
|
+
`/webchat/tasks/${taskId}/messages`,
|
|
318
|
+
'POST',
|
|
319
|
+
{ body },
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Agent/bot typing indicator on a task's webchat. Server resolves the
|
|
325
|
+
* engagement from the task — callers must not UOQL widgetId.
|
|
326
|
+
*
|
|
327
|
+
* @param {Object} options
|
|
328
|
+
* @param {string} options.taskId
|
|
329
|
+
* @param {boolean} options.isTyping
|
|
330
|
+
* @returns {Promise<Object>}
|
|
331
|
+
*/
|
|
332
|
+
async typingOnTask(options = {}) {
|
|
333
|
+
const { taskId, isTyping } = options;
|
|
334
|
+
|
|
335
|
+
this.sdk.validateParams(
|
|
336
|
+
{ taskId, isTyping },
|
|
337
|
+
{
|
|
338
|
+
taskId: { type: 'string', required: true },
|
|
339
|
+
isTyping: { type: 'boolean', required: true },
|
|
340
|
+
},
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
return internalRequest(
|
|
344
|
+
this.sdk,
|
|
345
|
+
`/webchat/tasks/${taskId}/typing`,
|
|
346
|
+
'POST',
|
|
347
|
+
{ body: { isTyping } },
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Staff-only system note on a task's webchat feed (visibility=internal).
|
|
353
|
+
* Not sent to the visitor. Server resolves engagement from the task.
|
|
354
|
+
*
|
|
355
|
+
* @param {Object} options
|
|
356
|
+
* @param {string} options.taskId
|
|
357
|
+
* @param {string} options.message
|
|
358
|
+
* @returns {Promise<Object>}
|
|
359
|
+
*/
|
|
360
|
+
async noteOnTask(options = {}) {
|
|
361
|
+
const { taskId, message } = options;
|
|
362
|
+
|
|
363
|
+
this.sdk.validateParams(
|
|
364
|
+
{ taskId, message },
|
|
365
|
+
{
|
|
366
|
+
taskId: { type: 'string', required: true },
|
|
367
|
+
message: { type: 'string', required: true },
|
|
368
|
+
},
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
return internalRequest(
|
|
372
|
+
this.sdk,
|
|
373
|
+
`/webchat/tasks/${taskId}/notes`,
|
|
374
|
+
'POST',
|
|
375
|
+
{ body: { message } },
|
|
376
|
+
);
|
|
377
|
+
}
|
|
284
378
|
}
|