@lpextend/node-sdk 1.1.2
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/index.d.mts +2989 -0
- package/dist/index.d.ts +2989 -0
- package/dist/index.js +2162 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2120 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +50 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2120 @@
|
|
|
1
|
+
// src/types/index.ts
|
|
2
|
+
var LPExtendSDKError = class extends Error {
|
|
3
|
+
constructor(message, code, status, details) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.status = status;
|
|
7
|
+
this.details = details;
|
|
8
|
+
this.name = "LPExtendSDKError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var ErrorCodes = {
|
|
12
|
+
/** Not running inside shell iframe */
|
|
13
|
+
NOT_IN_SHELL: "NOT_IN_SHELL",
|
|
14
|
+
/** SDK initialization failed */
|
|
15
|
+
INIT_FAILED: "INIT_FAILED",
|
|
16
|
+
/** App not registered or disabled */
|
|
17
|
+
APP_NOT_REGISTERED: "APP_NOT_REGISTERED",
|
|
18
|
+
/** Authentication failed */
|
|
19
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
20
|
+
/** Scope not granted - update app registration */
|
|
21
|
+
SCOPE_DENIED: "SCOPE_DENIED",
|
|
22
|
+
/** Resource not found */
|
|
23
|
+
NOT_FOUND: "NOT_FOUND",
|
|
24
|
+
/** API call failed */
|
|
25
|
+
API_ERROR: "API_ERROR",
|
|
26
|
+
/** Request timeout */
|
|
27
|
+
TIMEOUT: "TIMEOUT",
|
|
28
|
+
/** Invalid configuration */
|
|
29
|
+
INVALID_CONFIG: "INVALID_CONFIG",
|
|
30
|
+
/** Revision conflict - resource was modified */
|
|
31
|
+
REVISION_CONFLICT: "REVISION_CONFLICT",
|
|
32
|
+
/** Rate limit exceeded */
|
|
33
|
+
RATE_LIMITED: "RATE_LIMITED"
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// src/domains.ts
|
|
37
|
+
var ZONE_MAP = {
|
|
38
|
+
va: "z1",
|
|
39
|
+
// US
|
|
40
|
+
lo: "z2",
|
|
41
|
+
// EU
|
|
42
|
+
sy: "z3"
|
|
43
|
+
// AU/APAC
|
|
44
|
+
};
|
|
45
|
+
var GEO_MAP = {
|
|
46
|
+
z1: "p-us",
|
|
47
|
+
z2: "p-eu",
|
|
48
|
+
z3: "p-au"
|
|
49
|
+
};
|
|
50
|
+
var domainCache = /* @__PURE__ */ new Map();
|
|
51
|
+
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
52
|
+
var DomainResolver = class {
|
|
53
|
+
constructor(accountId) {
|
|
54
|
+
this.region = null;
|
|
55
|
+
this.zone = null;
|
|
56
|
+
this.geo = null;
|
|
57
|
+
this.accountId = accountId;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get domain for a specific LP service
|
|
61
|
+
*/
|
|
62
|
+
async getDomain(service) {
|
|
63
|
+
const domains = await this.getDomains();
|
|
64
|
+
const domain = domains.find((d) => d.service === service);
|
|
65
|
+
return domain?.baseURI || null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get all domains for the account
|
|
69
|
+
*/
|
|
70
|
+
async getDomains() {
|
|
71
|
+
const cached = domainCache.get(this.accountId);
|
|
72
|
+
if (cached && cached.expires > Date.now()) {
|
|
73
|
+
return cached.domains;
|
|
74
|
+
}
|
|
75
|
+
const response = await fetch(
|
|
76
|
+
`https://api.liveperson.net/api/account/${this.accountId}/service/baseURI.json?version=1.0`,
|
|
77
|
+
{
|
|
78
|
+
headers: {
|
|
79
|
+
"Content-Type": "application/json"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new Error(`Failed to fetch domains: ${response.status} ${response.statusText}`);
|
|
85
|
+
}
|
|
86
|
+
const data = await response.json();
|
|
87
|
+
const domains = data.baseURIs || [];
|
|
88
|
+
const asyncMessagingEnt = domains.find((d) => d.service === "asyncMessagingEnt");
|
|
89
|
+
if (asyncMessagingEnt) {
|
|
90
|
+
this.region = asyncMessagingEnt.baseURI.split(".")[0];
|
|
91
|
+
this.zone = ZONE_MAP[this.region] || null;
|
|
92
|
+
this.geo = this.zone ? GEO_MAP[this.zone] : null;
|
|
93
|
+
if (this.zone && this.region && this.geo) {
|
|
94
|
+
const additionalDomains = this.getAdditionalDomains();
|
|
95
|
+
for (const additional of additionalDomains) {
|
|
96
|
+
if (!domains.find((d) => d.service === additional.service)) {
|
|
97
|
+
domains.push(additional);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
domainCache.set(this.accountId, {
|
|
103
|
+
domains,
|
|
104
|
+
expires: Date.now() + CACHE_TTL_MS
|
|
105
|
+
});
|
|
106
|
+
return domains;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get additional domains not in CSDS
|
|
110
|
+
*/
|
|
111
|
+
getAdditionalDomains() {
|
|
112
|
+
if (!this.zone || !this.region || !this.geo) {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
return [
|
|
116
|
+
{
|
|
117
|
+
account: this.accountId,
|
|
118
|
+
service: "aiStudioPlatformService",
|
|
119
|
+
baseURI: `aistudio-${this.geo}.liveperson.net`
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
account: this.accountId,
|
|
123
|
+
service: "proactive",
|
|
124
|
+
baseURI: `proactive-messaging.${this.zone}.fs.liveperson.com`
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
account: this.accountId,
|
|
128
|
+
service: "botlogs",
|
|
129
|
+
baseURI: `${this.region}.bc-bot.liveperson.net`
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
account: this.accountId,
|
|
133
|
+
service: "bot",
|
|
134
|
+
baseURI: `${this.region}.bc-bot.liveperson.net`
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
account: this.accountId,
|
|
138
|
+
service: "botPlatform",
|
|
139
|
+
baseURI: `${this.region}.bc-platform.liveperson.net`
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
account: this.accountId,
|
|
143
|
+
service: "kb",
|
|
144
|
+
baseURI: `${this.region}.bc-kb.liveperson.net`
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
account: this.accountId,
|
|
148
|
+
service: "context",
|
|
149
|
+
baseURI: `${this.region}.context.liveperson.net`
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
account: this.accountId,
|
|
153
|
+
service: "recommendation",
|
|
154
|
+
baseURI: `${this.zone}.askmaven.liveperson.net`
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
account: this.accountId,
|
|
158
|
+
service: "proactiveHandoff",
|
|
159
|
+
baseURI: `${this.region}.handoff.liveperson.net`
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
account: this.accountId,
|
|
163
|
+
service: "convBuild",
|
|
164
|
+
baseURI: `${this.region}.bc-sso.liveperson.net`
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
account: this.accountId,
|
|
168
|
+
service: "bcmgmt",
|
|
169
|
+
baseURI: `${this.region}.bc-mgmt.liveperson.net`
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
account: this.accountId,
|
|
173
|
+
service: "bcintg",
|
|
174
|
+
baseURI: `${this.region}.bc-intg.liveperson.net`
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
account: this.accountId,
|
|
178
|
+
service: "bcnlu",
|
|
179
|
+
baseURI: `${this.region}.bc-nlu.liveperson.net`
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
account: this.accountId,
|
|
183
|
+
service: "promptlibrary",
|
|
184
|
+
baseURI: `${this.geo}.promptlibrary.liveperson.net`
|
|
185
|
+
}
|
|
186
|
+
];
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Clear cached domains for this account
|
|
190
|
+
*/
|
|
191
|
+
clearCache() {
|
|
192
|
+
domainCache.delete(this.accountId);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// src/http.ts
|
|
197
|
+
var SCOPE_CONFIG = {
|
|
198
|
+
// Account Configuration APIs (Bearer auth)
|
|
199
|
+
skills: { service: "accountConfigReadOnly", pathPrefix: "/le-users/skills", urlPattern: "accountConfig" },
|
|
200
|
+
users: { service: "accountConfigReadOnly", pathPrefix: "/le-users/users", urlPattern: "accountConfig" },
|
|
201
|
+
agentGroups: { service: "accountConfigReadOnly", pathPrefix: "/le-users/agentGroups", urlPattern: "accountConfig" },
|
|
202
|
+
profiles: { service: "accountConfigReadOnly", pathPrefix: "/le-users/profiles", urlPattern: "accountConfig" },
|
|
203
|
+
lobs: { service: "accountConfigReadOnly", pathPrefix: "/le-users/lobs", urlPattern: "accountConfig" },
|
|
204
|
+
predefinedContent: { service: "accountConfigReadOnly", pathPrefix: "/le-predefined-content/predefinedContent", urlPattern: "accountConfig" },
|
|
205
|
+
automaticMessages: { service: "accountConfigReadOnly", pathPrefix: "/le-campaigns/automatic-messages", urlPattern: "accountConfig" },
|
|
206
|
+
workingHours: { service: "accountConfigReadOnly", pathPrefix: "/le-users/working-hours", urlPattern: "accountConfig" },
|
|
207
|
+
specialOccasions: { service: "accountConfigReadOnly", pathPrefix: "/le-users/special-occasions", urlPattern: "accountConfig" },
|
|
208
|
+
campaigns: { service: "accountConfigReadOnly", pathPrefix: "/le-campaigns/campaigns", urlPattern: "accountConfig" },
|
|
209
|
+
engagements: { service: "accountConfigReadOnly", pathPrefix: "/le-campaigns/campaigns", urlPattern: "accountConfig" },
|
|
210
|
+
// AI Studio APIs (CC-Bearer auth)
|
|
211
|
+
aiStudio: { service: "aiStudioPlatformService", pathPrefix: "", authType: "cc-bearer", urlPattern: "aiStudio" },
|
|
212
|
+
promptLibrary: { service: "aiStudioPlatformService", pathPrefix: "", authType: "cc-bearer", urlPattern: "aiStudio" },
|
|
213
|
+
// Messaging APIs
|
|
214
|
+
messagingHistory: { service: "msgHist", pathPrefix: "/messaging_history/api/account", urlPattern: "messaging" },
|
|
215
|
+
messagingOperations: { service: "asyncMessagingEnt", pathPrefix: "/api/account", urlPattern: "messaging" },
|
|
216
|
+
connectToMessaging: { service: "asyncMessagingEnt", pathPrefix: "/api/account", urlPattern: "messaging" },
|
|
217
|
+
agentMetrics: { service: "leDataReporting", pathPrefix: "/operations/api/account", urlPattern: "messaging" },
|
|
218
|
+
agentActivity: { service: "leDataReporting", pathPrefix: "/operations/api/account", urlPattern: "messaging" },
|
|
219
|
+
outboundReporting: { service: "leDataReporting", pathPrefix: "/operations/api/account", urlPattern: "messaging" },
|
|
220
|
+
// Other LP APIs
|
|
221
|
+
conversationOrchestrator: { service: "maven", pathPrefix: "/v1/account", urlPattern: "messaging" },
|
|
222
|
+
faas: { service: "faasUI", pathPrefix: "/api/account", urlPattern: "messaging" },
|
|
223
|
+
proactiveMessaging: { service: "proactive", pathPrefix: "/api", urlPattern: "custom" },
|
|
224
|
+
// LP Prompt Library (separate from AI Studio Prompt Library)
|
|
225
|
+
prompts: { service: "promptlibrary", pathPrefix: "/v2", urlPattern: "prompts" }
|
|
226
|
+
};
|
|
227
|
+
var WRITE_SERVICE = "accountConfigReadWrite";
|
|
228
|
+
var HTTPClient = class {
|
|
229
|
+
constructor(accountId, accessToken, defaultTimeout, debug) {
|
|
230
|
+
this.accountId = accountId;
|
|
231
|
+
this.accessToken = accessToken;
|
|
232
|
+
this.defaultTimeout = defaultTimeout;
|
|
233
|
+
this.debug = debug;
|
|
234
|
+
this.domainResolver = new DomainResolver(accountId);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Make a GET request
|
|
238
|
+
*/
|
|
239
|
+
async get(path, options) {
|
|
240
|
+
return this.request("GET", path, options);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Make a POST request
|
|
244
|
+
*/
|
|
245
|
+
async post(path, body, options) {
|
|
246
|
+
return this.request("POST", path, { ...options, body });
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Make a PUT request
|
|
250
|
+
*/
|
|
251
|
+
async put(path, body, options) {
|
|
252
|
+
return this.request("PUT", path, { ...options, body });
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Make a DELETE request
|
|
256
|
+
*/
|
|
257
|
+
async delete(path, options) {
|
|
258
|
+
return this.request("DELETE", path, options);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Make a PATCH request
|
|
262
|
+
*/
|
|
263
|
+
async patch(path, body, options) {
|
|
264
|
+
return this.request("PATCH", path, { ...options, body });
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Create a scoped client for a specific API domain
|
|
268
|
+
* This allows setting default options like authMode for all requests
|
|
269
|
+
*/
|
|
270
|
+
withDefaults(defaults) {
|
|
271
|
+
return new ScopedHTTPClient(this, defaults);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Build the full URL for an LP API endpoint
|
|
275
|
+
*/
|
|
276
|
+
async buildUrl(path, scopeConfig, isWrite) {
|
|
277
|
+
const serviceName = isWrite && scopeConfig.service.startsWith("accountConfig") ? WRITE_SERVICE : scopeConfig.service;
|
|
278
|
+
const domain = await this.domainResolver.getDomain(serviceName);
|
|
279
|
+
if (!domain) {
|
|
280
|
+
throw new LPExtendSDKError(
|
|
281
|
+
`Could not resolve domain for service: ${serviceName}`,
|
|
282
|
+
ErrorCodes.API_ERROR
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
let url;
|
|
286
|
+
switch (scopeConfig.urlPattern) {
|
|
287
|
+
case "accountConfig":
|
|
288
|
+
url = `https://${domain}/api/account/${this.accountId}/configuration${scopeConfig.pathPrefix}`;
|
|
289
|
+
break;
|
|
290
|
+
case "messaging":
|
|
291
|
+
url = `https://${domain}${scopeConfig.pathPrefix}/${this.accountId}`;
|
|
292
|
+
break;
|
|
293
|
+
case "aiStudio":
|
|
294
|
+
url = `https://${domain}/api/v2`;
|
|
295
|
+
break;
|
|
296
|
+
case "prompts":
|
|
297
|
+
url = `https://${domain}${scopeConfig.pathPrefix}`;
|
|
298
|
+
if (path.startsWith("/system")) {
|
|
299
|
+
url += `/system/prompts${path.substring("/system".length)}`;
|
|
300
|
+
return url;
|
|
301
|
+
} else if (path.startsWith("/account")) {
|
|
302
|
+
url += `/accounts/${this.accountId}/prompts${path.substring("/account".length)}`;
|
|
303
|
+
return url;
|
|
304
|
+
} else if (path.startsWith("/llm-providers")) {
|
|
305
|
+
url += `/accounts/${this.accountId}/configurations/llm-providers${path.substring("/llm-providers".length)}`;
|
|
306
|
+
return url;
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
case "custom":
|
|
310
|
+
default:
|
|
311
|
+
url = `https://${domain}${scopeConfig.pathPrefix}`;
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
if (path) {
|
|
315
|
+
url += path.startsWith("/") ? path : `/${path}`;
|
|
316
|
+
}
|
|
317
|
+
return url;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Determine scope from path
|
|
321
|
+
*/
|
|
322
|
+
getScopeFromPath(path) {
|
|
323
|
+
const normalizedPath = path.startsWith("/") ? path.substring(1) : path;
|
|
324
|
+
const firstSegment = normalizedPath.split("/")[0];
|
|
325
|
+
if (firstSegment === "prompts") {
|
|
326
|
+
return "prompts";
|
|
327
|
+
}
|
|
328
|
+
if (firstSegment === "ai-studio" || normalizedPath.startsWith("ai-studio")) {
|
|
329
|
+
return "aiStudio";
|
|
330
|
+
}
|
|
331
|
+
if (firstSegment === "messaging") {
|
|
332
|
+
const secondSegment = normalizedPath.split("/")[1];
|
|
333
|
+
if (secondSegment === "history") return "messagingHistory";
|
|
334
|
+
if (secondSegment === "agent-metrics") return "agentMetrics";
|
|
335
|
+
if (secondSegment === "agent-activity") return "agentActivity";
|
|
336
|
+
if (secondSegment === "operations") return "messagingOperations";
|
|
337
|
+
if (secondSegment === "connect") return "connectToMessaging";
|
|
338
|
+
if (secondSegment === "outbound") return "outboundReporting";
|
|
339
|
+
return "messagingHistory";
|
|
340
|
+
}
|
|
341
|
+
const scopeMap = {
|
|
342
|
+
skills: "skills",
|
|
343
|
+
users: "users",
|
|
344
|
+
"agent-groups": "agentGroups",
|
|
345
|
+
profiles: "profiles",
|
|
346
|
+
lobs: "lobs",
|
|
347
|
+
campaigns: "campaigns",
|
|
348
|
+
engagements: "engagements",
|
|
349
|
+
"predefined-content": "predefinedContent",
|
|
350
|
+
"automatic-messages": "automaticMessages",
|
|
351
|
+
"working-hours": "workingHours",
|
|
352
|
+
"special-occasions": "specialOccasions"
|
|
353
|
+
};
|
|
354
|
+
return scopeMap[firstSegment] || firstSegment;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Make HTTP request to LP API
|
|
358
|
+
*/
|
|
359
|
+
async request(method, path, options) {
|
|
360
|
+
const scope = this.getScopeFromPath(path);
|
|
361
|
+
const scopeConfig = SCOPE_CONFIG[scope];
|
|
362
|
+
if (!scopeConfig) {
|
|
363
|
+
throw new LPExtendSDKError(
|
|
364
|
+
`Unknown scope: ${scope}. Path: ${path}`,
|
|
365
|
+
ErrorCodes.SCOPE_DENIED
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
const isWrite = method !== "GET";
|
|
369
|
+
const pathWithoutScope = this.stripScopeFromPath(path, scope);
|
|
370
|
+
const url = await this.buildUrl(pathWithoutScope, scopeConfig, isWrite);
|
|
371
|
+
let fullUrl = url;
|
|
372
|
+
if (options?.params) {
|
|
373
|
+
const searchParams = new URLSearchParams();
|
|
374
|
+
Object.entries(options.params).forEach(([key, value]) => {
|
|
375
|
+
if (value !== void 0) {
|
|
376
|
+
searchParams.set(key, String(value));
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
const paramString = searchParams.toString();
|
|
380
|
+
if (paramString) {
|
|
381
|
+
fullUrl += (fullUrl.includes("?") ? "&" : "?") + paramString;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
const authMode = options?.authMode || scopeConfig.authType || "bearer";
|
|
385
|
+
const authHeader = authMode === "cc-bearer" ? `CC-Bearer ${this.accessToken}` : `Bearer ${this.accessToken}`;
|
|
386
|
+
const headers = {
|
|
387
|
+
"Content-Type": "application/json",
|
|
388
|
+
Accept: "application/json",
|
|
389
|
+
Authorization: authHeader,
|
|
390
|
+
...options?.headers
|
|
391
|
+
};
|
|
392
|
+
if (options?.revision) {
|
|
393
|
+
headers["If-Match"] = options.revision;
|
|
394
|
+
}
|
|
395
|
+
this.log(`${method} ${fullUrl}`, { scope, authMode });
|
|
396
|
+
const timeout = options?.timeout || this.defaultTimeout;
|
|
397
|
+
const controller = new AbortController();
|
|
398
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
399
|
+
try {
|
|
400
|
+
const response = await fetch(fullUrl, {
|
|
401
|
+
method,
|
|
402
|
+
headers,
|
|
403
|
+
body: options?.body ? JSON.stringify(options.body) : void 0,
|
|
404
|
+
signal: controller.signal
|
|
405
|
+
});
|
|
406
|
+
clearTimeout(timeoutId);
|
|
407
|
+
if (!response.ok) {
|
|
408
|
+
await this.handleError(response);
|
|
409
|
+
}
|
|
410
|
+
const contentType = response.headers.get("content-type");
|
|
411
|
+
const hasJsonBody = contentType?.includes("application/json");
|
|
412
|
+
let responseData;
|
|
413
|
+
if (hasJsonBody && response.status !== 204) {
|
|
414
|
+
responseData = await response.json();
|
|
415
|
+
}
|
|
416
|
+
const revision = response.headers.get("ac-revision") || response.headers.get("etag") || response.headers.get("x-revision") || void 0;
|
|
417
|
+
return {
|
|
418
|
+
data: responseData,
|
|
419
|
+
revision: revision || void 0
|
|
420
|
+
};
|
|
421
|
+
} catch (error) {
|
|
422
|
+
clearTimeout(timeoutId);
|
|
423
|
+
if (error.name === "AbortError") {
|
|
424
|
+
throw new LPExtendSDKError("Request timeout", ErrorCodes.TIMEOUT);
|
|
425
|
+
}
|
|
426
|
+
if (error instanceof LPExtendSDKError) {
|
|
427
|
+
throw error;
|
|
428
|
+
}
|
|
429
|
+
throw new LPExtendSDKError(error.message, ErrorCodes.API_ERROR);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Strip the scope prefix from the path
|
|
434
|
+
*/
|
|
435
|
+
stripScopeFromPath(path, scope) {
|
|
436
|
+
const normalizedPath = path.startsWith("/") ? path.substring(1) : path;
|
|
437
|
+
const prefixMap = {
|
|
438
|
+
skills: ["skills"],
|
|
439
|
+
users: ["users"],
|
|
440
|
+
agentGroups: ["agent-groups"],
|
|
441
|
+
profiles: ["profiles"],
|
|
442
|
+
lobs: ["lobs"],
|
|
443
|
+
campaigns: ["campaigns"],
|
|
444
|
+
engagements: ["engagements"],
|
|
445
|
+
predefinedContent: ["predefined-content"],
|
|
446
|
+
automaticMessages: ["automatic-messages"],
|
|
447
|
+
workingHours: ["working-hours"],
|
|
448
|
+
specialOccasions: ["special-occasions"],
|
|
449
|
+
aiStudio: ["ai-studio"],
|
|
450
|
+
messagingHistory: ["messaging/history"],
|
|
451
|
+
agentMetrics: ["messaging/agent-metrics"],
|
|
452
|
+
agentActivity: ["messaging/agent-activity"],
|
|
453
|
+
messagingOperations: ["messaging/operations"],
|
|
454
|
+
connectToMessaging: ["messaging/connect"],
|
|
455
|
+
outboundReporting: ["messaging/outbound"],
|
|
456
|
+
prompts: ["prompts"]
|
|
457
|
+
};
|
|
458
|
+
const prefixes = prefixMap[scope] || [];
|
|
459
|
+
for (const prefix of prefixes) {
|
|
460
|
+
if (normalizedPath.startsWith(prefix)) {
|
|
461
|
+
const remaining = normalizedPath.substring(prefix.length);
|
|
462
|
+
return remaining.startsWith("/") ? remaining : `/${remaining}`;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return path;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Handle HTTP error responses
|
|
469
|
+
*/
|
|
470
|
+
async handleError(response) {
|
|
471
|
+
const errorBody = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
472
|
+
switch (response.status) {
|
|
473
|
+
case 401:
|
|
474
|
+
throw new LPExtendSDKError(
|
|
475
|
+
"Authentication failed",
|
|
476
|
+
ErrorCodes.UNAUTHORIZED,
|
|
477
|
+
response.status,
|
|
478
|
+
errorBody
|
|
479
|
+
);
|
|
480
|
+
case 403:
|
|
481
|
+
throw new LPExtendSDKError(
|
|
482
|
+
errorBody.message || "Access denied",
|
|
483
|
+
ErrorCodes.SCOPE_DENIED,
|
|
484
|
+
response.status,
|
|
485
|
+
errorBody
|
|
486
|
+
);
|
|
487
|
+
case 404:
|
|
488
|
+
throw new LPExtendSDKError(
|
|
489
|
+
errorBody.message || "Resource not found",
|
|
490
|
+
ErrorCodes.NOT_FOUND,
|
|
491
|
+
response.status,
|
|
492
|
+
errorBody
|
|
493
|
+
);
|
|
494
|
+
case 409:
|
|
495
|
+
throw new LPExtendSDKError(
|
|
496
|
+
errorBody.message || "Revision conflict - resource was modified",
|
|
497
|
+
ErrorCodes.REVISION_CONFLICT,
|
|
498
|
+
response.status,
|
|
499
|
+
errorBody
|
|
500
|
+
);
|
|
501
|
+
case 429:
|
|
502
|
+
throw new LPExtendSDKError(
|
|
503
|
+
errorBody.message || "Rate limit exceeded",
|
|
504
|
+
ErrorCodes.RATE_LIMITED,
|
|
505
|
+
response.status,
|
|
506
|
+
errorBody
|
|
507
|
+
);
|
|
508
|
+
default:
|
|
509
|
+
throw new LPExtendSDKError(
|
|
510
|
+
`API Error: ${response.status} - ${errorBody.message || response.statusText}`,
|
|
511
|
+
ErrorCodes.API_ERROR,
|
|
512
|
+
response.status,
|
|
513
|
+
errorBody
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Debug logging
|
|
519
|
+
*/
|
|
520
|
+
log(...args) {
|
|
521
|
+
if (this.debug) {
|
|
522
|
+
console.log("[LP-Extend-SDK]", ...args);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
var ScopedHTTPClient = class {
|
|
527
|
+
constructor(client, defaults) {
|
|
528
|
+
this.client = client;
|
|
529
|
+
this.defaults = defaults;
|
|
530
|
+
}
|
|
531
|
+
async get(path, options) {
|
|
532
|
+
return this.client.get(path, this.mergeOptions(options));
|
|
533
|
+
}
|
|
534
|
+
async post(path, body, options) {
|
|
535
|
+
return this.client.post(path, body, this.mergeOptions(options));
|
|
536
|
+
}
|
|
537
|
+
async put(path, body, options) {
|
|
538
|
+
return this.client.put(path, body, this.mergeOptions(options));
|
|
539
|
+
}
|
|
540
|
+
async delete(path, options) {
|
|
541
|
+
return this.client.delete(path, this.mergeOptions(options));
|
|
542
|
+
}
|
|
543
|
+
async patch(path, body, options) {
|
|
544
|
+
return this.client.patch(path, body, this.mergeOptions(options));
|
|
545
|
+
}
|
|
546
|
+
mergeOptions(options) {
|
|
547
|
+
return {
|
|
548
|
+
...this.defaults,
|
|
549
|
+
...options,
|
|
550
|
+
headers: {
|
|
551
|
+
...this.defaults.headers,
|
|
552
|
+
...options?.headers
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
// src/api/account-config.api.ts
|
|
559
|
+
var SkillsAPI = class {
|
|
560
|
+
constructor(http) {
|
|
561
|
+
this.http = http;
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Get all skills
|
|
565
|
+
*/
|
|
566
|
+
async getAll() {
|
|
567
|
+
return this.http.get("/skills");
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Get a skill by ID
|
|
571
|
+
*/
|
|
572
|
+
async getById(skillId) {
|
|
573
|
+
return this.http.get(`/skills/${skillId}`);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Create a new skill
|
|
577
|
+
*/
|
|
578
|
+
async create(skill) {
|
|
579
|
+
return this.http.post("/skills", skill);
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Update a skill
|
|
583
|
+
* @param skillId - The skill ID
|
|
584
|
+
* @param skill - Updated skill data
|
|
585
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
586
|
+
*/
|
|
587
|
+
async update(skillId, skill, revision) {
|
|
588
|
+
const rev = revision || (await this.getAll()).revision;
|
|
589
|
+
return this.http.put(`/skills/${skillId}`, skill, { revision: rev });
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Delete a skill
|
|
593
|
+
* @param skillId - The skill ID
|
|
594
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
595
|
+
*/
|
|
596
|
+
async delete(skillId, revision) {
|
|
597
|
+
const rev = revision || (await this.getAll()).revision;
|
|
598
|
+
return this.http.delete(`/skills/${skillId}`, { revision: rev });
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
var UsersAPI = class {
|
|
602
|
+
constructor(http) {
|
|
603
|
+
this.http = http;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Get all users
|
|
607
|
+
*/
|
|
608
|
+
async getAll() {
|
|
609
|
+
return this.http.get("/users");
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Get a user by ID
|
|
613
|
+
*/
|
|
614
|
+
async getById(userId) {
|
|
615
|
+
return this.http.get(`/users/${userId}`);
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Create a new user
|
|
619
|
+
*/
|
|
620
|
+
async create(user) {
|
|
621
|
+
return this.http.post("/users", user);
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Update a user
|
|
625
|
+
* @param userId - The user ID
|
|
626
|
+
* @param user - Updated user data
|
|
627
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
628
|
+
*/
|
|
629
|
+
async update(userId, user, revision) {
|
|
630
|
+
const rev = revision || (await this.getAll()).revision;
|
|
631
|
+
return this.http.put(`/users/${userId}`, user, { revision: rev });
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Delete a user
|
|
635
|
+
* @param userId - The user ID
|
|
636
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
637
|
+
*/
|
|
638
|
+
async delete(userId, revision) {
|
|
639
|
+
const rev = revision || (await this.getAll()).revision;
|
|
640
|
+
return this.http.delete(`/users/${userId}`, { revision: rev });
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Get the current authenticated user
|
|
644
|
+
*/
|
|
645
|
+
async getSelf() {
|
|
646
|
+
return this.http.get("/users/self");
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
var AgentGroupsAPI = class {
|
|
650
|
+
constructor(http) {
|
|
651
|
+
this.http = http;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Get all agent groups
|
|
655
|
+
*/
|
|
656
|
+
async getAll() {
|
|
657
|
+
return this.http.get("/agent-groups");
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Get an agent group by ID
|
|
661
|
+
*/
|
|
662
|
+
async getById(groupId) {
|
|
663
|
+
return this.http.get(`/agent-groups/${groupId}`);
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Create a new agent group
|
|
667
|
+
*/
|
|
668
|
+
async create(group) {
|
|
669
|
+
return this.http.post("/agent-groups", group);
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Update an agent group
|
|
673
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
674
|
+
*/
|
|
675
|
+
async update(groupId, group, revision) {
|
|
676
|
+
const rev = revision || (await this.getAll()).revision;
|
|
677
|
+
return this.http.put(`/agent-groups/${groupId}`, group, { revision: rev });
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Delete an agent group
|
|
681
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
682
|
+
*/
|
|
683
|
+
async delete(groupId, revision) {
|
|
684
|
+
const rev = revision || (await this.getAll()).revision;
|
|
685
|
+
return this.http.delete(`/agent-groups/${groupId}`, { revision: rev });
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
var ProfilesAPI = class {
|
|
689
|
+
constructor(http) {
|
|
690
|
+
this.http = http;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Get all profiles
|
|
694
|
+
*/
|
|
695
|
+
async getAll() {
|
|
696
|
+
return this.http.get("/profiles");
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Get a profile by ID
|
|
700
|
+
*/
|
|
701
|
+
async getById(profileId) {
|
|
702
|
+
return this.http.get(`/profiles/${profileId}`);
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Create a new profile
|
|
706
|
+
*/
|
|
707
|
+
async create(profile) {
|
|
708
|
+
return this.http.post("/profiles", profile);
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Update a profile
|
|
712
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
713
|
+
*/
|
|
714
|
+
async update(profileId, profile, revision) {
|
|
715
|
+
const rev = revision || (await this.getAll()).revision;
|
|
716
|
+
return this.http.put(`/profiles/${profileId}`, profile, { revision: rev });
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Delete a profile
|
|
720
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
721
|
+
*/
|
|
722
|
+
async delete(profileId, revision) {
|
|
723
|
+
const rev = revision || (await this.getAll()).revision;
|
|
724
|
+
return this.http.delete(`/profiles/${profileId}`, { revision: rev });
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
var LOBsAPI = class {
|
|
728
|
+
constructor(http) {
|
|
729
|
+
this.http = http;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Get all LOBs
|
|
733
|
+
*/
|
|
734
|
+
async getAll() {
|
|
735
|
+
return this.http.get("/lobs");
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Get a LOB by ID
|
|
739
|
+
*/
|
|
740
|
+
async getById(lobId) {
|
|
741
|
+
return this.http.get(`/lobs/${lobId}`);
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Create a new LOB
|
|
745
|
+
*/
|
|
746
|
+
async create(lob) {
|
|
747
|
+
return this.http.post("/lobs", lob);
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Update a LOB
|
|
751
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
752
|
+
*/
|
|
753
|
+
async update(lobId, lob, revision) {
|
|
754
|
+
const rev = revision || (await this.getAll()).revision;
|
|
755
|
+
return this.http.put(`/lobs/${lobId}`, lob, { revision: rev });
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* Delete a LOB
|
|
759
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
760
|
+
*/
|
|
761
|
+
async delete(lobId, revision) {
|
|
762
|
+
const rev = revision || (await this.getAll()).revision;
|
|
763
|
+
return this.http.delete(`/lobs/${lobId}`, { revision: rev });
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
var CampaignsAPI = class {
|
|
767
|
+
constructor(http) {
|
|
768
|
+
this.http = http;
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Get all campaigns
|
|
772
|
+
*/
|
|
773
|
+
async getAll() {
|
|
774
|
+
return this.http.get("/campaigns");
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Get a campaign by ID
|
|
778
|
+
*/
|
|
779
|
+
async getById(campaignId) {
|
|
780
|
+
return this.http.get(`/campaigns/${campaignId}`);
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Create a new campaign
|
|
784
|
+
*/
|
|
785
|
+
async create(campaign) {
|
|
786
|
+
return this.http.post("/campaigns", campaign);
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Update a campaign
|
|
790
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
791
|
+
*/
|
|
792
|
+
async update(campaignId, campaign, revision) {
|
|
793
|
+
const rev = revision || (await this.getAll()).revision;
|
|
794
|
+
return this.http.put(`/campaigns/${campaignId}`, campaign, { revision: rev });
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Delete a campaign
|
|
798
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
799
|
+
*/
|
|
800
|
+
async delete(campaignId, revision) {
|
|
801
|
+
const rev = revision || (await this.getAll()).revision;
|
|
802
|
+
return this.http.delete(`/campaigns/${campaignId}`, { revision: rev });
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
var EngagementsAPI = class {
|
|
806
|
+
constructor(http) {
|
|
807
|
+
this.http = http;
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Get all engagements for a campaign
|
|
811
|
+
*/
|
|
812
|
+
async getByCampaign(campaignId) {
|
|
813
|
+
return this.http.get(`/campaigns/${campaignId}/engagements`);
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Get an engagement by ID
|
|
817
|
+
*/
|
|
818
|
+
async getById(campaignId, engagementId) {
|
|
819
|
+
return this.http.get(`/campaigns/${campaignId}/engagements/${engagementId}`);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Create a new engagement
|
|
823
|
+
*/
|
|
824
|
+
async create(engagement) {
|
|
825
|
+
return this.http.post(`/campaigns/${engagement.campaignId}/engagements`, engagement);
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Update an engagement
|
|
829
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
830
|
+
*/
|
|
831
|
+
async update(campaignId, engagementId, engagement, revision) {
|
|
832
|
+
const rev = revision || (await this.getByCampaign(campaignId)).revision;
|
|
833
|
+
return this.http.put(`/campaigns/${campaignId}/engagements/${engagementId}`, engagement, { revision: rev });
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Delete an engagement
|
|
837
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
838
|
+
*/
|
|
839
|
+
async delete(campaignId, engagementId, revision) {
|
|
840
|
+
const rev = revision || (await this.getByCampaign(campaignId)).revision;
|
|
841
|
+
return this.http.delete(`/campaigns/${campaignId}/engagements/${engagementId}`, { revision: rev });
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
var PredefinedContentAPI = class {
|
|
845
|
+
constructor(http) {
|
|
846
|
+
this.http = http;
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Get all predefined content
|
|
850
|
+
*/
|
|
851
|
+
async getAll() {
|
|
852
|
+
return this.http.get("/predefined-content");
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Get predefined content by ID
|
|
856
|
+
*/
|
|
857
|
+
async getById(contentId) {
|
|
858
|
+
return this.http.get(`/predefined-content/${contentId}`);
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Create new predefined content
|
|
862
|
+
*/
|
|
863
|
+
async create(content) {
|
|
864
|
+
return this.http.post("/predefined-content", content);
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Update predefined content
|
|
868
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
869
|
+
*/
|
|
870
|
+
async update(contentId, content, revision) {
|
|
871
|
+
const rev = revision || (await this.getAll()).revision;
|
|
872
|
+
return this.http.put(`/predefined-content/${contentId}`, content, { revision: rev });
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Delete predefined content
|
|
876
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
877
|
+
*/
|
|
878
|
+
async delete(contentId, revision) {
|
|
879
|
+
const rev = revision || (await this.getAll()).revision;
|
|
880
|
+
return this.http.delete(`/predefined-content/${contentId}`, { revision: rev });
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
var AutomaticMessagesAPI = class {
|
|
884
|
+
constructor(http) {
|
|
885
|
+
this.http = http;
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Get all automatic messages
|
|
889
|
+
*/
|
|
890
|
+
async getAll() {
|
|
891
|
+
return this.http.get("/automatic-messages");
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Get an automatic message by ID
|
|
895
|
+
*/
|
|
896
|
+
async getById(messageId) {
|
|
897
|
+
return this.http.get(`/automatic-messages/${messageId}`);
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Create a new automatic message
|
|
901
|
+
*/
|
|
902
|
+
async create(message) {
|
|
903
|
+
return this.http.post("/automatic-messages", message);
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* Update an automatic message
|
|
907
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
908
|
+
*/
|
|
909
|
+
async update(messageId, message, revision) {
|
|
910
|
+
const rev = revision || (await this.getAll()).revision;
|
|
911
|
+
return this.http.put(`/automatic-messages/${messageId}`, message, { revision: rev });
|
|
912
|
+
}
|
|
913
|
+
/**
|
|
914
|
+
* Delete an automatic message
|
|
915
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
916
|
+
*/
|
|
917
|
+
async delete(messageId, revision) {
|
|
918
|
+
const rev = revision || (await this.getAll()).revision;
|
|
919
|
+
return this.http.delete(`/automatic-messages/${messageId}`, { revision: rev });
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
var WorkingHoursAPI = class {
|
|
923
|
+
constructor(http) {
|
|
924
|
+
this.http = http;
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Get all working hours schedules
|
|
928
|
+
*/
|
|
929
|
+
async getAll() {
|
|
930
|
+
return this.http.get("/working-hours");
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Get working hours by ID
|
|
934
|
+
*/
|
|
935
|
+
async getById(scheduleId) {
|
|
936
|
+
return this.http.get(`/working-hours/${scheduleId}`);
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Create new working hours schedule
|
|
940
|
+
*/
|
|
941
|
+
async create(schedule) {
|
|
942
|
+
return this.http.post("/working-hours", schedule);
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Update working hours schedule
|
|
946
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
947
|
+
*/
|
|
948
|
+
async update(scheduleId, schedule, revision) {
|
|
949
|
+
const rev = revision || (await this.getAll()).revision;
|
|
950
|
+
return this.http.put(`/working-hours/${scheduleId}`, schedule, { revision: rev });
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Delete working hours schedule
|
|
954
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
955
|
+
*/
|
|
956
|
+
async delete(scheduleId, revision) {
|
|
957
|
+
const rev = revision || (await this.getAll()).revision;
|
|
958
|
+
return this.http.delete(`/working-hours/${scheduleId}`, { revision: rev });
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
var SpecialOccasionsAPI = class {
|
|
962
|
+
constructor(http) {
|
|
963
|
+
this.http = http;
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Get all special occasions
|
|
967
|
+
*/
|
|
968
|
+
async getAll() {
|
|
969
|
+
return this.http.get("/special-occasions");
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Get a special occasion by ID
|
|
973
|
+
*/
|
|
974
|
+
async getById(occasionId) {
|
|
975
|
+
return this.http.get(`/special-occasions/${occasionId}`);
|
|
976
|
+
}
|
|
977
|
+
/**
|
|
978
|
+
* Create a new special occasion
|
|
979
|
+
*/
|
|
980
|
+
async create(occasion) {
|
|
981
|
+
return this.http.post("/special-occasions", occasion);
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Update a special occasion
|
|
985
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
986
|
+
*/
|
|
987
|
+
async update(occasionId, occasion, revision) {
|
|
988
|
+
const rev = revision || (await this.getAll()).revision;
|
|
989
|
+
return this.http.put(`/special-occasions/${occasionId}`, occasion, { revision: rev });
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Delete a special occasion
|
|
993
|
+
* @param revision - Optional revision for optimistic locking (auto-fetched if not provided)
|
|
994
|
+
*/
|
|
995
|
+
async delete(occasionId, revision) {
|
|
996
|
+
const rev = revision || (await this.getAll()).revision;
|
|
997
|
+
return this.http.delete(`/special-occasions/${occasionId}`, { revision: rev });
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
|
|
1001
|
+
// src/api/ai-studio.api.ts
|
|
1002
|
+
var CategoriesAPI = class {
|
|
1003
|
+
constructor(http) {
|
|
1004
|
+
this.http = http;
|
|
1005
|
+
}
|
|
1006
|
+
async getAll() {
|
|
1007
|
+
return this.http.get("/ai-studio/categories");
|
|
1008
|
+
}
|
|
1009
|
+
async create(data) {
|
|
1010
|
+
return this.http.post("/ai-studio/categories", data);
|
|
1011
|
+
}
|
|
1012
|
+
async update(categoryId, data) {
|
|
1013
|
+
return this.http.put(`/ai-studio/categories/${categoryId}`, data);
|
|
1014
|
+
}
|
|
1015
|
+
async delete(categoryId) {
|
|
1016
|
+
return this.http.delete(`/ai-studio/categories/${categoryId}`);
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
var ConversationsAPI = class {
|
|
1020
|
+
constructor(http) {
|
|
1021
|
+
this.http = http;
|
|
1022
|
+
}
|
|
1023
|
+
async getAll(params) {
|
|
1024
|
+
return this.http.get("/ai-studio/conversations", { params });
|
|
1025
|
+
}
|
|
1026
|
+
async getById(convId) {
|
|
1027
|
+
return this.http.get(`/ai-studio/conversations/${convId}`);
|
|
1028
|
+
}
|
|
1029
|
+
async create(data) {
|
|
1030
|
+
return this.http.post("/ai-studio/conversations", data);
|
|
1031
|
+
}
|
|
1032
|
+
async update(convId, data) {
|
|
1033
|
+
return this.http.put(`/ai-studio/conversations/${convId}`, data);
|
|
1034
|
+
}
|
|
1035
|
+
async delete(convId) {
|
|
1036
|
+
return this.http.delete(`/ai-studio/conversations/${convId}`);
|
|
1037
|
+
}
|
|
1038
|
+
async updateAttributes(convId, data) {
|
|
1039
|
+
return this.http.put(`/ai-studio/conversations/${convId}/attributes`, data);
|
|
1040
|
+
}
|
|
1041
|
+
async close(convId) {
|
|
1042
|
+
return this.http.patch(`/ai-studio/conversations/${convId}/close`);
|
|
1043
|
+
}
|
|
1044
|
+
async export(params) {
|
|
1045
|
+
return this.http.get("/ai-studio/conversations/export", { params });
|
|
1046
|
+
}
|
|
1047
|
+
async upload(conversations) {
|
|
1048
|
+
return this.http.post("/ai-studio/conversations/upload", { conversations });
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
var SummaryAPI = class {
|
|
1052
|
+
constructor(http) {
|
|
1053
|
+
this.http = http;
|
|
1054
|
+
}
|
|
1055
|
+
async create(data) {
|
|
1056
|
+
return this.http.post("/ai-studio/summary", data);
|
|
1057
|
+
}
|
|
1058
|
+
async createBatch(data) {
|
|
1059
|
+
return this.http.post("/ai-studio/summary/batch", data);
|
|
1060
|
+
}
|
|
1061
|
+
async getBatch(offset, limit) {
|
|
1062
|
+
return this.http.get("/ai-studio/summary/batch", { params: { offset, limit } });
|
|
1063
|
+
}
|
|
1064
|
+
async getBatchById(summaryId) {
|
|
1065
|
+
return this.http.get(`/ai-studio/summary/batch/${summaryId}`);
|
|
1066
|
+
}
|
|
1067
|
+
async deleteBatch(summaryId) {
|
|
1068
|
+
return this.http.delete(`/ai-studio/summary/batch/${summaryId}`);
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
var QueryAPI = class {
|
|
1072
|
+
constructor(http) {
|
|
1073
|
+
this.http = http;
|
|
1074
|
+
}
|
|
1075
|
+
async generate(data) {
|
|
1076
|
+
return this.http.post("/ai-studio/query", data);
|
|
1077
|
+
}
|
|
1078
|
+
};
|
|
1079
|
+
var SimulationsAPI = class {
|
|
1080
|
+
constructor(http) {
|
|
1081
|
+
this.http = http;
|
|
1082
|
+
}
|
|
1083
|
+
async getAll(params) {
|
|
1084
|
+
return this.http.get("/ai-studio/simulations", { params });
|
|
1085
|
+
}
|
|
1086
|
+
async getById(simulationId) {
|
|
1087
|
+
return this.http.get(`/ai-studio/simulations/${simulationId}`);
|
|
1088
|
+
}
|
|
1089
|
+
async create(data) {
|
|
1090
|
+
return this.http.post("/ai-studio/simulations", data);
|
|
1091
|
+
}
|
|
1092
|
+
async update(simulationId, data) {
|
|
1093
|
+
return this.http.put(`/ai-studio/simulations/${simulationId}`, data);
|
|
1094
|
+
}
|
|
1095
|
+
async delete(simulationId) {
|
|
1096
|
+
return this.http.delete(`/ai-studio/simulations/${simulationId}`);
|
|
1097
|
+
}
|
|
1098
|
+
async getStatus(simulationId) {
|
|
1099
|
+
return this.http.get(`/ai-studio/simulations/${simulationId}/status`);
|
|
1100
|
+
}
|
|
1101
|
+
async getJobResults(simulationId, jobId) {
|
|
1102
|
+
return this.http.get(`/ai-studio/simulations/${simulationId}/jobs/${jobId}`);
|
|
1103
|
+
}
|
|
1104
|
+
async cancel(simulationId) {
|
|
1105
|
+
return this.http.post(`/ai-studio/simulations/${simulationId}/cancel`);
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
var TranscriptAnalysisAPI = class {
|
|
1109
|
+
constructor(http) {
|
|
1110
|
+
this.http = http;
|
|
1111
|
+
}
|
|
1112
|
+
async getAll(owner, limit, startAfterId) {
|
|
1113
|
+
return this.http.get("/ai-studio/transcript-analysis", {
|
|
1114
|
+
params: { owner, limit, start_after_id: startAfterId }
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
async getById(analysisId, excludeConversations, excludeQuestions) {
|
|
1118
|
+
return this.http.get(`/ai-studio/transcript-analysis/${analysisId}`, {
|
|
1119
|
+
params: { exclude_conversations: excludeConversations, exclude_questions: excludeQuestions }
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
async create(data) {
|
|
1123
|
+
return this.http.post("/ai-studio/transcript-analysis", data);
|
|
1124
|
+
}
|
|
1125
|
+
async update(analysisId, data) {
|
|
1126
|
+
return this.http.put(`/ai-studio/transcript-analysis/${analysisId}`, data);
|
|
1127
|
+
}
|
|
1128
|
+
async delete(analysisId) {
|
|
1129
|
+
return this.http.delete(`/ai-studio/transcript-analysis/${analysisId}`);
|
|
1130
|
+
}
|
|
1131
|
+
};
|
|
1132
|
+
var KnowledgebasesAPI = class {
|
|
1133
|
+
constructor(http) {
|
|
1134
|
+
this.http = http;
|
|
1135
|
+
}
|
|
1136
|
+
async getAll() {
|
|
1137
|
+
return this.http.get("/ai-studio/knowledgebases");
|
|
1138
|
+
}
|
|
1139
|
+
async getKai() {
|
|
1140
|
+
return this.http.get("/ai-studio/knowledgebases/kai");
|
|
1141
|
+
}
|
|
1142
|
+
async getById(kbId) {
|
|
1143
|
+
return this.http.get(`/ai-studio/knowledgebases/${kbId}`);
|
|
1144
|
+
}
|
|
1145
|
+
async delete(kbId) {
|
|
1146
|
+
return this.http.delete(`/ai-studio/knowledgebases/${kbId}`);
|
|
1147
|
+
}
|
|
1148
|
+
async getHealth(kbId) {
|
|
1149
|
+
return this.http.get(`/ai-studio/knowledgebases/${kbId}/health`);
|
|
1150
|
+
}
|
|
1151
|
+
async refresh(kbId) {
|
|
1152
|
+
return this.http.get(`/ai-studio/knowledgebases/${kbId}/refresh`);
|
|
1153
|
+
}
|
|
1154
|
+
async search(kbId, data) {
|
|
1155
|
+
return this.http.post(`/ai-studio/knowledgebases/${kbId}/search`, data);
|
|
1156
|
+
}
|
|
1157
|
+
async getItems(kbId) {
|
|
1158
|
+
return this.http.get(`/ai-studio/knowledgebases/${kbId}/items`);
|
|
1159
|
+
}
|
|
1160
|
+
async getItemsBySource(kbId, sourceId) {
|
|
1161
|
+
return this.http.get(`/ai-studio/knowledgebases/${kbId}/items/${sourceId}`);
|
|
1162
|
+
}
|
|
1163
|
+
async createItems(kbId, sourceId, items) {
|
|
1164
|
+
return this.http.post(`/ai-studio/knowledgebases/${kbId}/items/${sourceId}`, items);
|
|
1165
|
+
}
|
|
1166
|
+
async updateItems(kbId, sourceId, items) {
|
|
1167
|
+
return this.http.put(`/ai-studio/knowledgebases/${kbId}/items/${sourceId}`, items);
|
|
1168
|
+
}
|
|
1169
|
+
async deleteItems(kbId, sourceId, itemIds) {
|
|
1170
|
+
return this.http.delete(`/ai-studio/knowledgebases/${kbId}/items/${sourceId}`, { body: itemIds });
|
|
1171
|
+
}
|
|
1172
|
+
};
|
|
1173
|
+
var EvaluatorsAPI = class {
|
|
1174
|
+
constructor(http) {
|
|
1175
|
+
this.http = http;
|
|
1176
|
+
}
|
|
1177
|
+
async similarity(evaluationType, data) {
|
|
1178
|
+
return this.http.post("/ai-studio/evaluators/similarity", data, {
|
|
1179
|
+
params: { type: evaluationType }
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
async resolution(data) {
|
|
1183
|
+
return this.http.post("/ai-studio/evaluators/resolution", data);
|
|
1184
|
+
}
|
|
1185
|
+
async guidedRouting(data) {
|
|
1186
|
+
return this.http.post("/ai-studio/evaluators/guided-routing", data);
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
var GeneratorsAPI = class {
|
|
1190
|
+
constructor(http) {
|
|
1191
|
+
this.http = http;
|
|
1192
|
+
}
|
|
1193
|
+
async qaFromModel(modelId) {
|
|
1194
|
+
return this.http.get(`/ai-studio/generators/qa/model/${modelId}`);
|
|
1195
|
+
}
|
|
1196
|
+
async qaFromKnowledgebase(kbIds, generateAnswers, useRandomSections) {
|
|
1197
|
+
return this.http.get("/ai-studio/generators/qa/knowledgebase", {
|
|
1198
|
+
params: { kb_id: kbIds.join(","), generate_answers: generateAnswers, use_random_sections: useRandomSections }
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
async qaFromConversationCloud(data) {
|
|
1202
|
+
return this.http.post("/ai-studio/generators/qa/conversation-cloud", data);
|
|
1203
|
+
}
|
|
1204
|
+
async kaiRoutesLlm(data) {
|
|
1205
|
+
return this.http.post("/ai-studio/generators/routes/kai-llm", data);
|
|
1206
|
+
}
|
|
1207
|
+
async kaiRoutes(data) {
|
|
1208
|
+
return this.http.post("/ai-studio/generators/routes/kai", data);
|
|
1209
|
+
}
|
|
1210
|
+
async kaiRoutesStatus(flowId) {
|
|
1211
|
+
return this.http.get("/ai-studio/generators/routes/kai/status", {
|
|
1212
|
+
params: { flow_id: flowId }
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
};
|
|
1216
|
+
var PromptLibraryAPI = class {
|
|
1217
|
+
constructor(http) {
|
|
1218
|
+
this.http = http;
|
|
1219
|
+
}
|
|
1220
|
+
async getAll() {
|
|
1221
|
+
return this.http.get("/ai-studio/prompt-library");
|
|
1222
|
+
}
|
|
1223
|
+
async create(data) {
|
|
1224
|
+
return this.http.post("/ai-studio/prompt-library", data);
|
|
1225
|
+
}
|
|
1226
|
+
async update(promptId, data) {
|
|
1227
|
+
return this.http.put(`/ai-studio/prompt-library/${promptId}`, data);
|
|
1228
|
+
}
|
|
1229
|
+
async getProviders() {
|
|
1230
|
+
return this.http.get("/ai-studio/prompt-library/providers");
|
|
1231
|
+
}
|
|
1232
|
+
async getSystemPrompts() {
|
|
1233
|
+
return this.http.get("/ai-studio/prompt-library/system");
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
var AIStudioUsersAPI = class {
|
|
1237
|
+
constructor(http) {
|
|
1238
|
+
this.http = http;
|
|
1239
|
+
}
|
|
1240
|
+
async getSelf() {
|
|
1241
|
+
return this.http.get("/ai-studio/users/self");
|
|
1242
|
+
}
|
|
1243
|
+
async getAll() {
|
|
1244
|
+
return this.http.get("/ai-studio/users");
|
|
1245
|
+
}
|
|
1246
|
+
async getDetails() {
|
|
1247
|
+
return this.http.get("/ai-studio/users/details");
|
|
1248
|
+
}
|
|
1249
|
+
async create(data) {
|
|
1250
|
+
return this.http.post("/ai-studio/users", data);
|
|
1251
|
+
}
|
|
1252
|
+
async update(userId, data) {
|
|
1253
|
+
return this.http.put(`/ai-studio/users/${userId}`, data);
|
|
1254
|
+
}
|
|
1255
|
+
async delete(userId) {
|
|
1256
|
+
return this.http.delete(`/ai-studio/users/${userId}`);
|
|
1257
|
+
}
|
|
1258
|
+
async updateModels(userId, data) {
|
|
1259
|
+
return this.http.put(`/ai-studio/users/${userId}/models`, data);
|
|
1260
|
+
}
|
|
1261
|
+
async agreeToTerms(userId) {
|
|
1262
|
+
return this.http.get(`/ai-studio/users/${userId}/terms`);
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
var FlowsAPI = class {
|
|
1266
|
+
constructor(http, accountId) {
|
|
1267
|
+
this.http = http;
|
|
1268
|
+
this.accountId = accountId;
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* List all flows for the account
|
|
1272
|
+
* GET /api/v2/flows?account_id={accountId}
|
|
1273
|
+
*/
|
|
1274
|
+
async getAll() {
|
|
1275
|
+
return this.http.get("/ai-studio/flows", {
|
|
1276
|
+
params: { account_id: this.accountId }
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
/**
|
|
1280
|
+
* Get a specific flow by ID
|
|
1281
|
+
* GET /api/v2/flows/{flowId}
|
|
1282
|
+
*/
|
|
1283
|
+
async getById(flowId) {
|
|
1284
|
+
return this.http.get(`/ai-studio/flows/${flowId}`);
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Invoke a flow
|
|
1288
|
+
* POST /api/v2/flows/{flowId}
|
|
1289
|
+
*/
|
|
1290
|
+
async invoke(flowId, data) {
|
|
1291
|
+
return this.http.post(`/ai-studio/flows/${flowId}`, data);
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Invoke a promptless flow (quick response)
|
|
1295
|
+
* POST /api/v2/flows/response
|
|
1296
|
+
*/
|
|
1297
|
+
async invokeWithResponse(prompt, messages, text) {
|
|
1298
|
+
const body = { prompt };
|
|
1299
|
+
if (messages) body.messages = messages;
|
|
1300
|
+
if (text) body.text = text;
|
|
1301
|
+
return this.http.post("/ai-studio/flows/response", body);
|
|
1302
|
+
}
|
|
1303
|
+
};
|
|
1304
|
+
var AIStudioAPI = class {
|
|
1305
|
+
constructor(http, accountId) {
|
|
1306
|
+
const scopedHttp = http.withDefaults({ authMode: "cc-bearer" });
|
|
1307
|
+
this.categories = new CategoriesAPI(scopedHttp);
|
|
1308
|
+
this.conversations = new ConversationsAPI(scopedHttp);
|
|
1309
|
+
this.summary = new SummaryAPI(scopedHttp);
|
|
1310
|
+
this.query = new QueryAPI(scopedHttp);
|
|
1311
|
+
this.simulations = new SimulationsAPI(scopedHttp);
|
|
1312
|
+
this.transcriptAnalysis = new TranscriptAnalysisAPI(scopedHttp);
|
|
1313
|
+
this.knowledgebases = new KnowledgebasesAPI(scopedHttp);
|
|
1314
|
+
this.evaluators = new EvaluatorsAPI(scopedHttp);
|
|
1315
|
+
this.generators = new GeneratorsAPI(scopedHttp);
|
|
1316
|
+
this.promptLibrary = new PromptLibraryAPI(scopedHttp);
|
|
1317
|
+
this.users = new AIStudioUsersAPI(scopedHttp);
|
|
1318
|
+
this.flows = new FlowsAPI(scopedHttp, accountId);
|
|
1319
|
+
}
|
|
1320
|
+
};
|
|
1321
|
+
|
|
1322
|
+
// src/api/messaging.api.ts
|
|
1323
|
+
var MessagingHistoryAPI = class {
|
|
1324
|
+
constructor(http) {
|
|
1325
|
+
this.http = http;
|
|
1326
|
+
}
|
|
1327
|
+
/**
|
|
1328
|
+
* Query messaging conversations
|
|
1329
|
+
*/
|
|
1330
|
+
async query(params) {
|
|
1331
|
+
return this.http.post("/messaging/history", params);
|
|
1332
|
+
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Get a single conversation by ID
|
|
1335
|
+
*/
|
|
1336
|
+
async getConversation(conversationId) {
|
|
1337
|
+
return this.http.get(`/messaging/history/${conversationId}`);
|
|
1338
|
+
}
|
|
1339
|
+
/**
|
|
1340
|
+
* Get conversations by IDs (batch)
|
|
1341
|
+
*/
|
|
1342
|
+
async getConversations(conversationIds) {
|
|
1343
|
+
return this.http.post("/messaging/history/batch", { conversationIds });
|
|
1344
|
+
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Export conversations matching criteria
|
|
1347
|
+
*/
|
|
1348
|
+
async export(params) {
|
|
1349
|
+
return this.http.post("/messaging/history/export", params);
|
|
1350
|
+
}
|
|
1351
|
+
};
|
|
1352
|
+
var AgentMetricsAPI = class {
|
|
1353
|
+
constructor(http) {
|
|
1354
|
+
this.http = http;
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Get current metrics for agents
|
|
1358
|
+
*/
|
|
1359
|
+
async getMetrics(params) {
|
|
1360
|
+
return this.http.post("/messaging/agent-metrics", params || {});
|
|
1361
|
+
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Get metrics for a specific agent
|
|
1364
|
+
*/
|
|
1365
|
+
async getAgentMetrics(agentId) {
|
|
1366
|
+
return this.http.get(`/messaging/agent-metrics/${agentId}`);
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Get metrics summary by skill
|
|
1370
|
+
*/
|
|
1371
|
+
async getBySkill(skillId) {
|
|
1372
|
+
return this.http.get(`/messaging/agent-metrics/skill/${skillId}`);
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Get metrics summary by agent group
|
|
1376
|
+
*/
|
|
1377
|
+
async getByAgentGroup(groupId) {
|
|
1378
|
+
return this.http.get(`/messaging/agent-metrics/group/${groupId}`);
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1381
|
+
var AgentActivityAPI = class {
|
|
1382
|
+
constructor(http) {
|
|
1383
|
+
this.http = http;
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Query agent activity
|
|
1387
|
+
*/
|
|
1388
|
+
async query(params) {
|
|
1389
|
+
return this.http.post("/messaging/agent-activity", params);
|
|
1390
|
+
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Get activity for a specific agent
|
|
1393
|
+
*/
|
|
1394
|
+
async getAgentActivity(agentId, from, to) {
|
|
1395
|
+
return this.http.get(`/messaging/agent-activity/${agentId}`, {
|
|
1396
|
+
params: { from, to }
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
};
|
|
1400
|
+
var MessagingOperationsAPI = class {
|
|
1401
|
+
constructor(http) {
|
|
1402
|
+
this.http = http;
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* Transfer a conversation to another skill or agent
|
|
1406
|
+
*/
|
|
1407
|
+
async transfer(request) {
|
|
1408
|
+
return this.http.post(`/messaging/operations/${request.conversationId}/transfer`, {
|
|
1409
|
+
targetSkillId: request.targetSkillId,
|
|
1410
|
+
targetAgentId: request.targetAgentId,
|
|
1411
|
+
reason: request.reason
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Close a conversation
|
|
1416
|
+
*/
|
|
1417
|
+
async close(request) {
|
|
1418
|
+
return this.http.post(`/messaging/operations/${request.conversationId}/close`, {
|
|
1419
|
+
closeReason: request.closeReason
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
/**
|
|
1423
|
+
* Send a message to a conversation
|
|
1424
|
+
*/
|
|
1425
|
+
async sendMessage(request) {
|
|
1426
|
+
return this.http.post(`/messaging/operations/${request.conversationId}/message`, {
|
|
1427
|
+
message: request.message,
|
|
1428
|
+
contentType: request.contentType,
|
|
1429
|
+
richContent: request.richContent
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Set conversation priority
|
|
1434
|
+
*/
|
|
1435
|
+
async setPriority(conversationId, priority) {
|
|
1436
|
+
return this.http.post(`/messaging/operations/${conversationId}/priority`, { priority });
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Set conversation TTR (Time To Respond)
|
|
1440
|
+
*/
|
|
1441
|
+
async setTTR(conversationId, ttrType, value) {
|
|
1442
|
+
return this.http.post(`/messaging/operations/${conversationId}/ttr`, { ttrType, value });
|
|
1443
|
+
}
|
|
1444
|
+
};
|
|
1445
|
+
var ConnectToMessagingAPI = class {
|
|
1446
|
+
constructor(http) {
|
|
1447
|
+
this.http = http;
|
|
1448
|
+
}
|
|
1449
|
+
/**
|
|
1450
|
+
* Create a new conversation
|
|
1451
|
+
*/
|
|
1452
|
+
async createConversation(request) {
|
|
1453
|
+
return this.http.post("/messaging/connect", request);
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Get available campaigns and engagements for creating conversations
|
|
1457
|
+
*/
|
|
1458
|
+
async getAvailableEngagements() {
|
|
1459
|
+
return this.http.get("/messaging/connect/engagements");
|
|
1460
|
+
}
|
|
1461
|
+
};
|
|
1462
|
+
var OutboundReportingAPI = class {
|
|
1463
|
+
constructor(http) {
|
|
1464
|
+
this.http = http;
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Query outbound campaign reports
|
|
1468
|
+
*/
|
|
1469
|
+
async query(params) {
|
|
1470
|
+
return this.http.post("/messaging/outbound/reports", params);
|
|
1471
|
+
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Get report for a specific campaign
|
|
1474
|
+
*/
|
|
1475
|
+
async getCampaignReport(campaignId, from, to) {
|
|
1476
|
+
return this.http.get(`/messaging/outbound/reports/${campaignId}`, {
|
|
1477
|
+
params: { from, to }
|
|
1478
|
+
});
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Get aggregate outbound stats
|
|
1482
|
+
*/
|
|
1483
|
+
async getAggregateStats(from, to) {
|
|
1484
|
+
return this.http.get("/messaging/outbound/reports/aggregate", {
|
|
1485
|
+
params: { from, to }
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
};
|
|
1489
|
+
var MessagingAPI = class {
|
|
1490
|
+
constructor(http) {
|
|
1491
|
+
this.history = new MessagingHistoryAPI(http);
|
|
1492
|
+
this.agentMetrics = new AgentMetricsAPI(http);
|
|
1493
|
+
this.agentActivity = new AgentActivityAPI(http);
|
|
1494
|
+
this.operations = new MessagingOperationsAPI(http);
|
|
1495
|
+
this.connect = new ConnectToMessagingAPI(http);
|
|
1496
|
+
this.outbound = new OutboundReportingAPI(http);
|
|
1497
|
+
}
|
|
1498
|
+
};
|
|
1499
|
+
|
|
1500
|
+
// src/api/sentinel.api.ts
|
|
1501
|
+
var SentinelAPI = class {
|
|
1502
|
+
constructor(http) {
|
|
1503
|
+
this.http = http;
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Get login URL for OAuth redirect
|
|
1507
|
+
*
|
|
1508
|
+
* Returns a URL to redirect the user to for LivePerson authentication.
|
|
1509
|
+
* After successful auth, user is redirected back with an authorization code.
|
|
1510
|
+
*
|
|
1511
|
+
* @returns Login URL for OAuth redirect
|
|
1512
|
+
*
|
|
1513
|
+
* @example
|
|
1514
|
+
* ```typescript
|
|
1515
|
+
* const { url } = await sdk.sentinel.getLoginUrl();
|
|
1516
|
+
* // Redirect user to LP login
|
|
1517
|
+
* window.location.href = url;
|
|
1518
|
+
* ```
|
|
1519
|
+
*/
|
|
1520
|
+
async getLoginUrl() {
|
|
1521
|
+
const response = await this.http.get("/idp/login-url");
|
|
1522
|
+
return response.data;
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Exchange OAuth authorization code for access token
|
|
1526
|
+
*
|
|
1527
|
+
* After the user completes LP authentication and is redirected back,
|
|
1528
|
+
* use this method to exchange the authorization code for tokens.
|
|
1529
|
+
*
|
|
1530
|
+
* @param request - Token exchange request with code and redirect URI
|
|
1531
|
+
* @returns Token object with access token, refresh token, and user info
|
|
1532
|
+
*
|
|
1533
|
+
* @example
|
|
1534
|
+
* ```typescript
|
|
1535
|
+
* // Get code from URL params after redirect
|
|
1536
|
+
* const urlParams = new URLSearchParams(window.location.search);
|
|
1537
|
+
* const code = urlParams.get('code');
|
|
1538
|
+
*
|
|
1539
|
+
* const token = await sdk.sentinel.exchangeToken({
|
|
1540
|
+
* code,
|
|
1541
|
+
* redirect: window.location.origin + '/callback',
|
|
1542
|
+
* appname: 'my-app',
|
|
1543
|
+
* });
|
|
1544
|
+
*
|
|
1545
|
+
* // Store token for API calls
|
|
1546
|
+
* localStorage.setItem('lpToken', token.accessToken);
|
|
1547
|
+
* ```
|
|
1548
|
+
*/
|
|
1549
|
+
async exchangeToken(request) {
|
|
1550
|
+
const response = await this.http.post("/idp/token", request);
|
|
1551
|
+
return response.data;
|
|
1552
|
+
}
|
|
1553
|
+
/**
|
|
1554
|
+
* Logout and revoke token
|
|
1555
|
+
*
|
|
1556
|
+
* Revokes the current access token, ending the user's session.
|
|
1557
|
+
*
|
|
1558
|
+
* @example
|
|
1559
|
+
* ```typescript
|
|
1560
|
+
* await sdk.sentinel.logout();
|
|
1561
|
+
* // Clear local storage and redirect to login
|
|
1562
|
+
* localStorage.removeItem('lpToken');
|
|
1563
|
+
* window.location.href = '/login';
|
|
1564
|
+
* ```
|
|
1565
|
+
*/
|
|
1566
|
+
async logout() {
|
|
1567
|
+
await this.http.post("/idp/logout", {});
|
|
1568
|
+
}
|
|
1569
|
+
/**
|
|
1570
|
+
* Get LivePerson domains for the account
|
|
1571
|
+
*
|
|
1572
|
+
* Returns the domain URLs for various LP services.
|
|
1573
|
+
* Useful for making direct API calls to specific LP services.
|
|
1574
|
+
*
|
|
1575
|
+
* @returns Map of service names to domain URLs
|
|
1576
|
+
*
|
|
1577
|
+
* @example
|
|
1578
|
+
* ```typescript
|
|
1579
|
+
* const domains = await sdk.sentinel.getDomains();
|
|
1580
|
+
* console.log('Sentinel domain:', domains.sentinel);
|
|
1581
|
+
* console.log('Account Config domain:', domains.accountConfigReadOnly);
|
|
1582
|
+
* ```
|
|
1583
|
+
*/
|
|
1584
|
+
async getDomains() {
|
|
1585
|
+
const response = await this.http.get("/idp/domains");
|
|
1586
|
+
return response.data;
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
* Authenticate with Conversation Builder
|
|
1590
|
+
*
|
|
1591
|
+
* Exchanges the LP access token for a CB-specific token.
|
|
1592
|
+
* Required for making Conversation Builder API calls.
|
|
1593
|
+
*
|
|
1594
|
+
* @returns CB authentication info with token and organization ID
|
|
1595
|
+
*
|
|
1596
|
+
* @example
|
|
1597
|
+
* ```typescript
|
|
1598
|
+
* const cbAuth = await sdk.sentinel.authenticateCB();
|
|
1599
|
+
* if (cbAuth.success) {
|
|
1600
|
+
* const cbToken = cbAuth.successResult.apiAccessToken;
|
|
1601
|
+
* const cbOrg = cbAuth.successResult.sessionOrganizationId;
|
|
1602
|
+
* // Use cbToken for CB API calls
|
|
1603
|
+
* }
|
|
1604
|
+
* ```
|
|
1605
|
+
*/
|
|
1606
|
+
async authenticateCB() {
|
|
1607
|
+
const response = await this.http.get("/idp/authenticate-cb");
|
|
1608
|
+
return response.data;
|
|
1609
|
+
}
|
|
1610
|
+
};
|
|
1611
|
+
|
|
1612
|
+
// src/api/prompts.api.ts
|
|
1613
|
+
var LPPromptsAPI = class {
|
|
1614
|
+
constructor(http) {
|
|
1615
|
+
this.scopedHttp = http.withDefaults({
|
|
1616
|
+
params: { source: "ccui" }
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Get all system prompts (read-only, provided by LivePerson)
|
|
1621
|
+
*/
|
|
1622
|
+
async getSystemPrompts(params) {
|
|
1623
|
+
const response = await this.scopedHttp.get(
|
|
1624
|
+
"/prompts/system",
|
|
1625
|
+
{ params }
|
|
1626
|
+
);
|
|
1627
|
+
const prompts = response.data?.successResult?.prompts || [];
|
|
1628
|
+
return {
|
|
1629
|
+
data: prompts,
|
|
1630
|
+
revision: response.revision
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
/**
|
|
1634
|
+
* Get all account prompts
|
|
1635
|
+
*/
|
|
1636
|
+
async getAccountPrompts(params) {
|
|
1637
|
+
const response = await this.scopedHttp.get(
|
|
1638
|
+
"/prompts/account",
|
|
1639
|
+
{ params }
|
|
1640
|
+
);
|
|
1641
|
+
const prompts = response.data?.successResult?.prompts || [];
|
|
1642
|
+
return {
|
|
1643
|
+
data: prompts,
|
|
1644
|
+
revision: response.revision
|
|
1645
|
+
};
|
|
1646
|
+
}
|
|
1647
|
+
/**
|
|
1648
|
+
* Get a single account prompt by ID
|
|
1649
|
+
*/
|
|
1650
|
+
async getById(promptId) {
|
|
1651
|
+
return this.scopedHttp.get(`/prompts/account/${promptId}`);
|
|
1652
|
+
}
|
|
1653
|
+
/**
|
|
1654
|
+
* Create a new account prompt
|
|
1655
|
+
*/
|
|
1656
|
+
async create(prompt) {
|
|
1657
|
+
return this.scopedHttp.post("/prompts/account", prompt);
|
|
1658
|
+
}
|
|
1659
|
+
/**
|
|
1660
|
+
* Update an account prompt
|
|
1661
|
+
* @param promptId - The prompt ID
|
|
1662
|
+
* @param prompt - Updated prompt data
|
|
1663
|
+
*/
|
|
1664
|
+
async update(promptId, prompt) {
|
|
1665
|
+
return this.scopedHttp.put(`/prompts/account/${promptId}`, prompt);
|
|
1666
|
+
}
|
|
1667
|
+
/**
|
|
1668
|
+
* Delete an account prompt
|
|
1669
|
+
* @param promptId - The prompt ID
|
|
1670
|
+
*/
|
|
1671
|
+
async delete(promptId) {
|
|
1672
|
+
return this.scopedHttp.delete(`/prompts/account/${promptId}`);
|
|
1673
|
+
}
|
|
1674
|
+
/**
|
|
1675
|
+
* Get LLM provider subscriptions for the account
|
|
1676
|
+
*/
|
|
1677
|
+
async getLLMProviders() {
|
|
1678
|
+
const response = await this.scopedHttp.get(
|
|
1679
|
+
"/prompts/llm-providers"
|
|
1680
|
+
);
|
|
1681
|
+
const providers = response.data?.successResult?.provider_subscriptions || [];
|
|
1682
|
+
return {
|
|
1683
|
+
data: providers,
|
|
1684
|
+
revision: response.revision
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
};
|
|
1688
|
+
|
|
1689
|
+
// src/sdk.ts
|
|
1690
|
+
var LPExtendSDK = class {
|
|
1691
|
+
/**
|
|
1692
|
+
* Create SDK instance (use initializeSDK() instead for async init)
|
|
1693
|
+
*/
|
|
1694
|
+
constructor(config, initResult) {
|
|
1695
|
+
this.config = config;
|
|
1696
|
+
this.debug = config.debug ?? false;
|
|
1697
|
+
this.grantedScopes = initResult.grantedScopes;
|
|
1698
|
+
this.appName = initResult.appName;
|
|
1699
|
+
const timeout = config.timeout ?? 3e4;
|
|
1700
|
+
this.http = new HTTPClient(
|
|
1701
|
+
config.accountId,
|
|
1702
|
+
config.accessToken,
|
|
1703
|
+
timeout,
|
|
1704
|
+
this.debug
|
|
1705
|
+
);
|
|
1706
|
+
this.skills = new SkillsAPI(this.http);
|
|
1707
|
+
this.users = new UsersAPI(this.http);
|
|
1708
|
+
this.agentGroups = new AgentGroupsAPI(this.http);
|
|
1709
|
+
this.profiles = new ProfilesAPI(this.http);
|
|
1710
|
+
this.lobs = new LOBsAPI(this.http);
|
|
1711
|
+
this.campaigns = new CampaignsAPI(this.http);
|
|
1712
|
+
this.engagements = new EngagementsAPI(this.http);
|
|
1713
|
+
this.predefinedContent = new PredefinedContentAPI(this.http);
|
|
1714
|
+
this.automaticMessages = new AutomaticMessagesAPI(this.http);
|
|
1715
|
+
this.workingHours = new WorkingHoursAPI(this.http);
|
|
1716
|
+
this.specialOccasions = new SpecialOccasionsAPI(this.http);
|
|
1717
|
+
this.aiStudio = new AIStudioAPI(this.http, this.config.accountId);
|
|
1718
|
+
this.messaging = new MessagingAPI(this.http);
|
|
1719
|
+
this.sentinel = new SentinelAPI(this.http);
|
|
1720
|
+
this.prompts = new LPPromptsAPI(this.http);
|
|
1721
|
+
this.log("SDK initialized with scopes:", this.grantedScopes);
|
|
1722
|
+
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Get the current account ID
|
|
1725
|
+
*/
|
|
1726
|
+
get accountId() {
|
|
1727
|
+
return this.config.accountId;
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Get the app ID
|
|
1731
|
+
*/
|
|
1732
|
+
get appId() {
|
|
1733
|
+
return this.config.appId;
|
|
1734
|
+
}
|
|
1735
|
+
/**
|
|
1736
|
+
* Check if a scope was granted
|
|
1737
|
+
*/
|
|
1738
|
+
hasScope(scope) {
|
|
1739
|
+
return this.grantedScopes.includes(scope);
|
|
1740
|
+
}
|
|
1741
|
+
/**
|
|
1742
|
+
* Check if multiple scopes were granted
|
|
1743
|
+
*/
|
|
1744
|
+
hasScopes(scopes) {
|
|
1745
|
+
return scopes.every((scope) => this.grantedScopes.includes(scope));
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* Check if any of the specified scopes were granted
|
|
1749
|
+
*/
|
|
1750
|
+
hasAnyScope(scopes) {
|
|
1751
|
+
return scopes.some((scope) => this.grantedScopes.includes(scope));
|
|
1752
|
+
}
|
|
1753
|
+
/**
|
|
1754
|
+
* Debug logging
|
|
1755
|
+
*/
|
|
1756
|
+
log(...args) {
|
|
1757
|
+
if (this.debug) {
|
|
1758
|
+
console.log("[LP-Extend-SDK]", ...args);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
};
|
|
1762
|
+
async function createSDK(config) {
|
|
1763
|
+
if (!config.appId) {
|
|
1764
|
+
throw new LPExtendSDKError("appId is required", ErrorCodes.INVALID_CONFIG);
|
|
1765
|
+
}
|
|
1766
|
+
if (!config.accountId) {
|
|
1767
|
+
throw new LPExtendSDKError("accountId is required", ErrorCodes.INVALID_CONFIG);
|
|
1768
|
+
}
|
|
1769
|
+
if (!config.accessToken && !config.extendToken && !config.shellToken) {
|
|
1770
|
+
throw new LPExtendSDKError(
|
|
1771
|
+
"Either accessToken, extendToken, or shellToken is required",
|
|
1772
|
+
ErrorCodes.INVALID_CONFIG
|
|
1773
|
+
);
|
|
1774
|
+
}
|
|
1775
|
+
const debug = config.debug ?? false;
|
|
1776
|
+
const timeout = config.timeout ?? 3e4;
|
|
1777
|
+
let shellBaseUrl = config.shellBaseUrl;
|
|
1778
|
+
if (!shellBaseUrl) {
|
|
1779
|
+
if (typeof window !== "undefined") {
|
|
1780
|
+
try {
|
|
1781
|
+
if (window.self !== window.top && document.referrer) {
|
|
1782
|
+
const url = new URL(document.referrer);
|
|
1783
|
+
shellBaseUrl = url.origin;
|
|
1784
|
+
}
|
|
1785
|
+
} catch {
|
|
1786
|
+
}
|
|
1787
|
+
shellBaseUrl = shellBaseUrl || window.location.origin;
|
|
1788
|
+
} else {
|
|
1789
|
+
throw new LPExtendSDKError(
|
|
1790
|
+
"shellBaseUrl is required in non-browser environments",
|
|
1791
|
+
ErrorCodes.INVALID_CONFIG
|
|
1792
|
+
);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
let accessToken = config.accessToken;
|
|
1796
|
+
if (!accessToken && config.extendToken) {
|
|
1797
|
+
if (debug) {
|
|
1798
|
+
console.log("[LP-Extend-SDK] Verifying ExtendJWT with shell");
|
|
1799
|
+
}
|
|
1800
|
+
const verifyUrl = `${shellBaseUrl}/api/v2/auth/verify-child`;
|
|
1801
|
+
const extendController = new AbortController();
|
|
1802
|
+
const extendTimeoutId = setTimeout(() => extendController.abort(), timeout);
|
|
1803
|
+
try {
|
|
1804
|
+
const verifyResponse = await fetch(verifyUrl, {
|
|
1805
|
+
method: "POST",
|
|
1806
|
+
headers: {
|
|
1807
|
+
"Content-Type": "application/json"
|
|
1808
|
+
},
|
|
1809
|
+
body: JSON.stringify({
|
|
1810
|
+
extendToken: config.extendToken,
|
|
1811
|
+
appId: config.appId
|
|
1812
|
+
}),
|
|
1813
|
+
signal: extendController.signal
|
|
1814
|
+
});
|
|
1815
|
+
clearTimeout(extendTimeoutId);
|
|
1816
|
+
if (!verifyResponse.ok) {
|
|
1817
|
+
const errorData = await verifyResponse.json().catch(() => ({}));
|
|
1818
|
+
if (verifyResponse.status === 401) {
|
|
1819
|
+
throw new LPExtendSDKError(
|
|
1820
|
+
errorData.message || "ExtendJWT invalid or expired",
|
|
1821
|
+
ErrorCodes.UNAUTHORIZED,
|
|
1822
|
+
verifyResponse.status,
|
|
1823
|
+
errorData
|
|
1824
|
+
);
|
|
1825
|
+
}
|
|
1826
|
+
throw new LPExtendSDKError(
|
|
1827
|
+
errorData.message || `ExtendJWT verification failed: ${verifyResponse.status}`,
|
|
1828
|
+
ErrorCodes.API_ERROR,
|
|
1829
|
+
verifyResponse.status,
|
|
1830
|
+
errorData
|
|
1831
|
+
);
|
|
1832
|
+
}
|
|
1833
|
+
const authData = await verifyResponse.json();
|
|
1834
|
+
accessToken = authData.lpAccessToken;
|
|
1835
|
+
if (debug) {
|
|
1836
|
+
console.log("[LP-Extend-SDK] ExtendJWT verified, got LP access token");
|
|
1837
|
+
console.log("[LP-Extend-SDK] User:", authData.lpUserId, "Account:", authData.lpAccountId);
|
|
1838
|
+
}
|
|
1839
|
+
} catch (error) {
|
|
1840
|
+
clearTimeout(extendTimeoutId);
|
|
1841
|
+
if (error instanceof LPExtendSDKError) {
|
|
1842
|
+
throw error;
|
|
1843
|
+
}
|
|
1844
|
+
if (error.name === "AbortError") {
|
|
1845
|
+
throw new LPExtendSDKError("ExtendJWT verification timeout", ErrorCodes.TIMEOUT);
|
|
1846
|
+
}
|
|
1847
|
+
throw new LPExtendSDKError(
|
|
1848
|
+
`ExtendJWT verification failed: ${error.message}`,
|
|
1849
|
+
ErrorCodes.INIT_FAILED
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
if (!accessToken && config.shellToken) {
|
|
1854
|
+
if (debug) {
|
|
1855
|
+
console.log("[LP-Extend-SDK] Fetching LP token from shell using shellToken (legacy)");
|
|
1856
|
+
}
|
|
1857
|
+
const tokenUrl = `${shellBaseUrl}/api/v1/shell/token/${config.accountId}/lp-token`;
|
|
1858
|
+
const tokenController = new AbortController();
|
|
1859
|
+
const tokenTimeoutId = setTimeout(() => tokenController.abort(), timeout);
|
|
1860
|
+
try {
|
|
1861
|
+
const tokenResponse = await fetch(tokenUrl, {
|
|
1862
|
+
method: "POST",
|
|
1863
|
+
headers: {
|
|
1864
|
+
"Content-Type": "application/json",
|
|
1865
|
+
"X-Shell-Token": config.shellToken
|
|
1866
|
+
},
|
|
1867
|
+
body: JSON.stringify({
|
|
1868
|
+
appId: config.appId,
|
|
1869
|
+
scopes: config.scopes
|
|
1870
|
+
}),
|
|
1871
|
+
signal: tokenController.signal
|
|
1872
|
+
});
|
|
1873
|
+
clearTimeout(tokenTimeoutId);
|
|
1874
|
+
if (!tokenResponse.ok) {
|
|
1875
|
+
const errorData = await tokenResponse.json().catch(() => ({}));
|
|
1876
|
+
if (tokenResponse.status === 401) {
|
|
1877
|
+
throw new LPExtendSDKError(
|
|
1878
|
+
errorData.message || "Shell token invalid or expired",
|
|
1879
|
+
ErrorCodes.UNAUTHORIZED,
|
|
1880
|
+
tokenResponse.status,
|
|
1881
|
+
errorData
|
|
1882
|
+
);
|
|
1883
|
+
}
|
|
1884
|
+
if (tokenResponse.status === 403) {
|
|
1885
|
+
throw new LPExtendSDKError(
|
|
1886
|
+
errorData.message || "App not installed or disabled",
|
|
1887
|
+
ErrorCodes.APP_NOT_REGISTERED,
|
|
1888
|
+
tokenResponse.status,
|
|
1889
|
+
errorData
|
|
1890
|
+
);
|
|
1891
|
+
}
|
|
1892
|
+
if (tokenResponse.status === 404) {
|
|
1893
|
+
throw new LPExtendSDKError(
|
|
1894
|
+
errorData.message || "No LP token found - user may need to re-authenticate",
|
|
1895
|
+
ErrorCodes.NOT_FOUND,
|
|
1896
|
+
tokenResponse.status,
|
|
1897
|
+
errorData
|
|
1898
|
+
);
|
|
1899
|
+
}
|
|
1900
|
+
throw new LPExtendSDKError(
|
|
1901
|
+
errorData.message || `Failed to retrieve LP token: ${tokenResponse.status}`,
|
|
1902
|
+
ErrorCodes.API_ERROR,
|
|
1903
|
+
tokenResponse.status,
|
|
1904
|
+
errorData
|
|
1905
|
+
);
|
|
1906
|
+
}
|
|
1907
|
+
const tokenData = await tokenResponse.json();
|
|
1908
|
+
accessToken = tokenData.accessToken;
|
|
1909
|
+
if (debug) {
|
|
1910
|
+
console.log("[LP-Extend-SDK] LP token retrieved successfully");
|
|
1911
|
+
}
|
|
1912
|
+
} catch (error) {
|
|
1913
|
+
clearTimeout(tokenTimeoutId);
|
|
1914
|
+
if (error instanceof LPExtendSDKError) {
|
|
1915
|
+
throw error;
|
|
1916
|
+
}
|
|
1917
|
+
if (error.name === "AbortError") {
|
|
1918
|
+
throw new LPExtendSDKError("LP token retrieval timeout", ErrorCodes.TIMEOUT);
|
|
1919
|
+
}
|
|
1920
|
+
throw new LPExtendSDKError(
|
|
1921
|
+
`Failed to retrieve LP token: ${error.message}`,
|
|
1922
|
+
ErrorCodes.INIT_FAILED
|
|
1923
|
+
);
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
if (debug) {
|
|
1927
|
+
console.log("[LP-Extend-SDK] Verifying scopes with shell:", shellBaseUrl);
|
|
1928
|
+
}
|
|
1929
|
+
const initUrl = `${shellBaseUrl}/api/v1/lp/${config.accountId}/sdk/init`;
|
|
1930
|
+
const controller = new AbortController();
|
|
1931
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1932
|
+
try {
|
|
1933
|
+
const response = await fetch(initUrl, {
|
|
1934
|
+
method: "POST",
|
|
1935
|
+
headers: {
|
|
1936
|
+
"Content-Type": "application/json",
|
|
1937
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1938
|
+
"X-App-Id": config.appId
|
|
1939
|
+
},
|
|
1940
|
+
body: JSON.stringify({ scopes: config.scopes || [] }),
|
|
1941
|
+
signal: controller.signal
|
|
1942
|
+
});
|
|
1943
|
+
clearTimeout(timeoutId);
|
|
1944
|
+
if (!response.ok) {
|
|
1945
|
+
const errorBody = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
1946
|
+
if (response.status === 404) {
|
|
1947
|
+
throw new LPExtendSDKError(
|
|
1948
|
+
`App "${config.appId}" is not registered for account ${config.accountId}`,
|
|
1949
|
+
ErrorCodes.APP_NOT_REGISTERED,
|
|
1950
|
+
response.status,
|
|
1951
|
+
errorBody
|
|
1952
|
+
);
|
|
1953
|
+
}
|
|
1954
|
+
if (response.status === 403) {
|
|
1955
|
+
throw new LPExtendSDKError(
|
|
1956
|
+
errorBody.message || "App is disabled or not authorized",
|
|
1957
|
+
ErrorCodes.APP_NOT_REGISTERED,
|
|
1958
|
+
response.status,
|
|
1959
|
+
errorBody
|
|
1960
|
+
);
|
|
1961
|
+
}
|
|
1962
|
+
if (response.status === 401) {
|
|
1963
|
+
throw new LPExtendSDKError(
|
|
1964
|
+
"Authentication failed - invalid access token",
|
|
1965
|
+
ErrorCodes.UNAUTHORIZED,
|
|
1966
|
+
response.status,
|
|
1967
|
+
errorBody
|
|
1968
|
+
);
|
|
1969
|
+
}
|
|
1970
|
+
throw new LPExtendSDKError(
|
|
1971
|
+
`SDK initialization failed: ${errorBody.message || response.statusText}`,
|
|
1972
|
+
ErrorCodes.INIT_FAILED,
|
|
1973
|
+
response.status,
|
|
1974
|
+
errorBody
|
|
1975
|
+
);
|
|
1976
|
+
}
|
|
1977
|
+
const initResult = await response.json();
|
|
1978
|
+
if (debug) {
|
|
1979
|
+
console.log("[LP-Extend-SDK] Scopes verified:", initResult.grantedScopes);
|
|
1980
|
+
console.log("[LP-Extend-SDK] SDK will call LP APIs directly");
|
|
1981
|
+
}
|
|
1982
|
+
const resolvedConfig = { ...config, accessToken };
|
|
1983
|
+
return new LPExtendSDK(resolvedConfig, initResult);
|
|
1984
|
+
} catch (error) {
|
|
1985
|
+
clearTimeout(timeoutId);
|
|
1986
|
+
if (error.name === "AbortError") {
|
|
1987
|
+
throw new LPExtendSDKError("SDK initialization timeout", ErrorCodes.TIMEOUT);
|
|
1988
|
+
}
|
|
1989
|
+
if (error instanceof LPExtendSDKError) {
|
|
1990
|
+
throw error;
|
|
1991
|
+
}
|
|
1992
|
+
throw new LPExtendSDKError(
|
|
1993
|
+
`SDK initialization failed: ${error.message}`,
|
|
1994
|
+
ErrorCodes.INIT_FAILED
|
|
1995
|
+
);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
// src/index.ts
|
|
2000
|
+
async function initializeSDK(config) {
|
|
2001
|
+
return createSDK(config);
|
|
2002
|
+
}
|
|
2003
|
+
var VERSION = "1.0.0";
|
|
2004
|
+
var Scopes = {
|
|
2005
|
+
// Account Configuration
|
|
2006
|
+
SKILLS: "skills",
|
|
2007
|
+
USERS: "users",
|
|
2008
|
+
AGENT_GROUPS: "agentGroups",
|
|
2009
|
+
PROFILES: "profiles",
|
|
2010
|
+
LOBS: "lobs",
|
|
2011
|
+
PREDEFINED_CONTENT: "predefinedContent",
|
|
2012
|
+
AUTOMATIC_MESSAGES: "automaticMessages",
|
|
2013
|
+
WORKING_HOURS: "workingHours",
|
|
2014
|
+
SPECIAL_OCCASIONS: "specialOccasions",
|
|
2015
|
+
CAMPAIGNS: "campaigns",
|
|
2016
|
+
ENGAGEMENTS: "engagements",
|
|
2017
|
+
// Messaging & Conversations
|
|
2018
|
+
MESSAGING_HISTORY: "messagingHistory",
|
|
2019
|
+
MESSAGING_OPERATIONS: "messagingOperations",
|
|
2020
|
+
CONNECT_TO_MESSAGING: "connectToMessaging",
|
|
2021
|
+
// Agent & Reporting
|
|
2022
|
+
AGENT_METRICS: "agentMetrics",
|
|
2023
|
+
AGENT_ACTIVITY: "agentActivity",
|
|
2024
|
+
OUTBOUND_REPORTING: "outboundReporting",
|
|
2025
|
+
// AI & Automation
|
|
2026
|
+
AI_STUDIO: "aiStudio",
|
|
2027
|
+
CONVERSATION_BUILDER: "conversationBuilder",
|
|
2028
|
+
CONVERSATION_ORCHESTRATOR: "conversationOrchestrator",
|
|
2029
|
+
/** AI Studio Prompt Library (different from LP Prompts) */
|
|
2030
|
+
PROMPT_LIBRARY: "promptLibrary",
|
|
2031
|
+
/** LP Prompts API (Prompt Library) */
|
|
2032
|
+
LP_PROMPTS: "prompts",
|
|
2033
|
+
FAAS: "faas",
|
|
2034
|
+
// Proactive
|
|
2035
|
+
PROACTIVE_MESSAGING: "proactiveMessaging"
|
|
2036
|
+
};
|
|
2037
|
+
async function getShellToken(config) {
|
|
2038
|
+
const { shellBaseUrl, accountId, shellToken, appId, scopes, timeout = 1e4 } = config;
|
|
2039
|
+
if (!shellBaseUrl) {
|
|
2040
|
+
throw new LPExtendSDKError("shellBaseUrl is required", ErrorCodes.INVALID_CONFIG);
|
|
2041
|
+
}
|
|
2042
|
+
if (!accountId) {
|
|
2043
|
+
throw new LPExtendSDKError("accountId is required", ErrorCodes.INVALID_CONFIG);
|
|
2044
|
+
}
|
|
2045
|
+
if (!shellToken) {
|
|
2046
|
+
throw new LPExtendSDKError("shellToken is required", ErrorCodes.INVALID_CONFIG);
|
|
2047
|
+
}
|
|
2048
|
+
if (!appId) {
|
|
2049
|
+
throw new LPExtendSDKError("appId is required", ErrorCodes.INVALID_CONFIG);
|
|
2050
|
+
}
|
|
2051
|
+
const url = `${shellBaseUrl.replace(/\/$/, "")}/api/v1/shell/token/${accountId}/lp-token`;
|
|
2052
|
+
const controller = new AbortController();
|
|
2053
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
2054
|
+
try {
|
|
2055
|
+
const response = await fetch(url, {
|
|
2056
|
+
method: "POST",
|
|
2057
|
+
headers: {
|
|
2058
|
+
"Content-Type": "application/json",
|
|
2059
|
+
"X-Shell-Token": shellToken
|
|
2060
|
+
},
|
|
2061
|
+
body: JSON.stringify({
|
|
2062
|
+
appId,
|
|
2063
|
+
scopes
|
|
2064
|
+
}),
|
|
2065
|
+
signal: controller.signal
|
|
2066
|
+
});
|
|
2067
|
+
clearTimeout(timeoutId);
|
|
2068
|
+
if (!response.ok) {
|
|
2069
|
+
const errorData = await response.json().catch(() => ({}));
|
|
2070
|
+
if (response.status === 401) {
|
|
2071
|
+
throw new LPExtendSDKError(
|
|
2072
|
+
errorData.message || "Shell token invalid or expired",
|
|
2073
|
+
ErrorCodes.UNAUTHORIZED,
|
|
2074
|
+
response.status,
|
|
2075
|
+
errorData
|
|
2076
|
+
);
|
|
2077
|
+
}
|
|
2078
|
+
if (response.status === 403) {
|
|
2079
|
+
throw new LPExtendSDKError(
|
|
2080
|
+
errorData.message || "App not installed or disabled",
|
|
2081
|
+
ErrorCodes.APP_NOT_REGISTERED,
|
|
2082
|
+
response.status,
|
|
2083
|
+
errorData
|
|
2084
|
+
);
|
|
2085
|
+
}
|
|
2086
|
+
if (response.status === 404) {
|
|
2087
|
+
throw new LPExtendSDKError(
|
|
2088
|
+
errorData.message || "No LP token found for user",
|
|
2089
|
+
ErrorCodes.NOT_FOUND,
|
|
2090
|
+
response.status,
|
|
2091
|
+
errorData
|
|
2092
|
+
);
|
|
2093
|
+
}
|
|
2094
|
+
throw new LPExtendSDKError(
|
|
2095
|
+
errorData.message || `Shell token request failed: ${response.status}`,
|
|
2096
|
+
ErrorCodes.API_ERROR,
|
|
2097
|
+
response.status,
|
|
2098
|
+
errorData
|
|
2099
|
+
);
|
|
2100
|
+
}
|
|
2101
|
+
const data = await response.json();
|
|
2102
|
+
return data;
|
|
2103
|
+
} catch (error) {
|
|
2104
|
+
clearTimeout(timeoutId);
|
|
2105
|
+
if (error instanceof LPExtendSDKError) {
|
|
2106
|
+
throw error;
|
|
2107
|
+
}
|
|
2108
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
2109
|
+
throw new LPExtendSDKError("Shell token request timed out", ErrorCodes.TIMEOUT);
|
|
2110
|
+
}
|
|
2111
|
+
throw new LPExtendSDKError(
|
|
2112
|
+
`Failed to retrieve shell token: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
2113
|
+
ErrorCodes.API_ERROR
|
|
2114
|
+
);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
export { AIStudioAPI, AIStudioUsersAPI, AgentActivityAPI, AgentGroupsAPI, AgentMetricsAPI, AutomaticMessagesAPI, CampaignsAPI, CategoriesAPI, ConnectToMessagingAPI, ConversationsAPI, EngagementsAPI, ErrorCodes, EvaluatorsAPI, FlowsAPI, GeneratorsAPI, KnowledgebasesAPI, LOBsAPI, LPExtendSDK, LPExtendSDKError, LPPromptsAPI, MessagingAPI, MessagingHistoryAPI, MessagingOperationsAPI, OutboundReportingAPI, PredefinedContentAPI, ProfilesAPI, PromptLibraryAPI, QueryAPI, Scopes, SentinelAPI, SimulationsAPI, SkillsAPI, SpecialOccasionsAPI, SummaryAPI, TranscriptAnalysisAPI, UsersAPI, VERSION, WorkingHoursAPI, createSDK, getShellToken, initializeSDK };
|
|
2119
|
+
//# sourceMappingURL=index.mjs.map
|
|
2120
|
+
//# sourceMappingURL=index.mjs.map
|