dalvon-mcp 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +743 -0
- package/dist/clients/dalvon.d.ts +258 -0
- package/dist/clients/dalvon.d.ts.map +1 -0
- package/dist/clients/dalvon.js +1240 -0
- package/dist/clients/dalvon.js.map +1 -0
- package/dist/clients/knowledge.d.ts +59 -0
- package/dist/clients/knowledge.d.ts.map +1 -0
- package/dist/clients/knowledge.js +267 -0
- package/dist/clients/knowledge.js.map +1 -0
- package/dist/clients/telefonieren.d.ts +258 -0
- package/dist/clients/telefonieren.d.ts.map +1 -0
- package/dist/clients/telefonieren.js +1240 -0
- package/dist/clients/telefonieren.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +76 -0
- package/dist/config.js.map +1 -0
- package/dist/environment.d.ts +33 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +63 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/agents.d.ts +8 -0
- package/dist/tools/agents.d.ts.map +1 -0
- package/dist/tools/agents.js +1880 -0
- package/dist/tools/agents.js.map +1 -0
- package/dist/tools/billing.d.ts +8 -0
- package/dist/tools/billing.d.ts.map +1 -0
- package/dist/tools/billing.js +205 -0
- package/dist/tools/billing.js.map +1 -0
- package/dist/tools/calendar.d.ts +8 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +347 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/calls.d.ts +8 -0
- package/dist/tools/calls.d.ts.map +1 -0
- package/dist/tools/calls.js +508 -0
- package/dist/tools/calls.js.map +1 -0
- package/dist/tools/campaigns.d.ts +8 -0
- package/dist/tools/campaigns.d.ts.map +1 -0
- package/dist/tools/campaigns.js +531 -0
- package/dist/tools/campaigns.js.map +1 -0
- package/dist/tools/channels.d.ts +8 -0
- package/dist/tools/channels.d.ts.map +1 -0
- package/dist/tools/channels.js +165 -0
- package/dist/tools/channels.js.map +1 -0
- package/dist/tools/chats.d.ts +8 -0
- package/dist/tools/chats.d.ts.map +1 -0
- package/dist/tools/chats.js +142 -0
- package/dist/tools/chats.js.map +1 -0
- package/dist/tools/collections.d.ts +8 -0
- package/dist/tools/collections.d.ts.map +1 -0
- package/dist/tools/collections.js +389 -0
- package/dist/tools/collections.js.map +1 -0
- package/dist/tools/contacts.d.ts +8 -0
- package/dist/tools/contacts.d.ts.map +1 -0
- package/dist/tools/contacts.js +430 -0
- package/dist/tools/contacts.js.map +1 -0
- package/dist/tools/crawler.d.ts +8 -0
- package/dist/tools/crawler.d.ts.map +1 -0
- package/dist/tools/crawler.js +263 -0
- package/dist/tools/crawler.js.map +1 -0
- package/dist/tools/dnc.d.ts +8 -0
- package/dist/tools/dnc.d.ts.map +1 -0
- package/dist/tools/dnc.js +287 -0
- package/dist/tools/dnc.js.map +1 -0
- package/dist/tools/documents.d.ts +9 -0
- package/dist/tools/documents.d.ts.map +1 -0
- package/dist/tools/documents.js +518 -0
- package/dist/tools/documents.js.map +1 -0
- package/dist/tools/engines.d.ts +8 -0
- package/dist/tools/engines.d.ts.map +1 -0
- package/dist/tools/engines.js +271 -0
- package/dist/tools/engines.js.map +1 -0
- package/dist/tools/environment.d.ts +9 -0
- package/dist/tools/environment.d.ts.map +1 -0
- package/dist/tools/environment.js +59 -0
- package/dist/tools/environment.js.map +1 -0
- package/dist/tools/forwarding.d.ts +8 -0
- package/dist/tools/forwarding.d.ts.map +1 -0
- package/dist/tools/forwarding.js +30 -0
- package/dist/tools/forwarding.js.map +1 -0
- package/dist/tools/index.d.ts +58 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +158 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/integrations.d.ts +8 -0
- package/dist/tools/integrations.d.ts.map +1 -0
- package/dist/tools/integrations.js +234 -0
- package/dist/tools/integrations.js.map +1 -0
- package/dist/tools/mailbox.d.ts +8 -0
- package/dist/tools/mailbox.d.ts.map +1 -0
- package/dist/tools/mailbox.js +105 -0
- package/dist/tools/mailbox.js.map +1 -0
- package/dist/tools/media.d.ts +8 -0
- package/dist/tools/media.d.ts.map +1 -0
- package/dist/tools/media.js +223 -0
- package/dist/tools/media.js.map +1 -0
- package/dist/tools/numbers.d.ts +8 -0
- package/dist/tools/numbers.d.ts.map +1 -0
- package/dist/tools/numbers.js +560 -0
- package/dist/tools/numbers.js.map +1 -0
- package/dist/tools/organizations.d.ts +8 -0
- package/dist/tools/organizations.d.ts.map +1 -0
- package/dist/tools/organizations.js +234 -0
- package/dist/tools/organizations.js.map +1 -0
- package/dist/tools/postprocessing.d.ts +8 -0
- package/dist/tools/postprocessing.d.ts.map +1 -0
- package/dist/tools/postprocessing.js +383 -0
- package/dist/tools/postprocessing.js.map +1 -0
- package/dist/tools/pronunciations.d.ts +8 -0
- package/dist/tools/pronunciations.d.ts.map +1 -0
- package/dist/tools/pronunciations.js +236 -0
- package/dist/tools/pronunciations.js.map +1 -0
- package/dist/tools/rules.d.ts +8 -0
- package/dist/tools/rules.d.ts.map +1 -0
- package/dist/tools/rules.js +465 -0
- package/dist/tools/rules.js.map +1 -0
- package/dist/tools/statistics.d.ts +8 -0
- package/dist/tools/statistics.d.ts.map +1 -0
- package/dist/tools/statistics.js +120 -0
- package/dist/tools/statistics.js.map +1 -0
- package/dist/tools/templates.d.ts +8 -0
- package/dist/tools/templates.d.ts.map +1 -0
- package/dist/tools/templates.js +211 -0
- package/dist/tools/templates.js.map +1 -0
- package/dist/tools/tests.d.ts +8 -0
- package/dist/tools/tests.d.ts.map +1 -0
- package/dist/tools/tests.js +329 -0
- package/dist/tools/tests.js.map +1 -0
- package/dist/tools/users.d.ts +8 -0
- package/dist/tools/users.d.ts.map +1 -0
- package/dist/tools/users.js +484 -0
- package/dist/tools/users.js.map +1 -0
- package/dist/tools/voice-preview.d.ts +8 -0
- package/dist/tools/voice-preview.d.ts.map +1 -0
- package/dist/tools/voice-preview.js +100 -0
- package/dist/tools/voice-preview.js.map +1 -0
- package/dist/tools/voices.d.ts +8 -0
- package/dist/tools/voices.d.ts.map +1 -0
- package/dist/tools/voices.js +110 -0
- package/dist/tools/voices.js.map +1 -0
- package/dist/tools/whitelabels.d.ts +8 -0
- package/dist/tools/whitelabels.d.ts.map +1 -0
- package/dist/tools/whitelabels.js +199 -0
- package/dist/tools/whitelabels.js.map +1 -0
- package/dist/tools/widget-config.d.ts +8 -0
- package/dist/tools/widget-config.d.ts.map +1 -0
- package/dist/tools/widget-config.js +116 -0
- package/dist/tools/widget-config.js.map +1 -0
- package/dist/types/api.d.ts +303 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +6 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/tools.d.ts +41 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +6 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/errors.d.ts +31 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +77 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +25 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +34 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +68 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,1240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telefonieren.ai API Client
|
|
3
|
+
* Handles all communication with api.dalvon.ai
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
const MAX_RETRIES = 3;
|
|
7
|
+
const RETRY_DELAY_MS = 1000;
|
|
8
|
+
export class DalvonClient {
|
|
9
|
+
apiKey;
|
|
10
|
+
baseUrl;
|
|
11
|
+
constructor(apiKey, baseUrl = 'https://api.dalvon.ai') {
|
|
12
|
+
this.apiKey = apiKey;
|
|
13
|
+
this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Reconfigure credentials and base URL at runtime.
|
|
17
|
+
*/
|
|
18
|
+
reconfigure(apiKey, baseUrl) {
|
|
19
|
+
this.apiKey = apiKey;
|
|
20
|
+
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Make HTTP request with retry logic
|
|
24
|
+
*/
|
|
25
|
+
async makeRequest(method, endpoint, options = {}) {
|
|
26
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
27
|
+
// Add query params
|
|
28
|
+
if (options.params) {
|
|
29
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
30
|
+
if (value !== undefined && value !== null) {
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
value.forEach((v) => url.searchParams.append(key, String(v)));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
url.searchParams.set(key, String(value));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const headers = {
|
|
41
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
42
|
+
'Content-Type': 'application/json',
|
|
43
|
+
};
|
|
44
|
+
let lastError = null;
|
|
45
|
+
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
46
|
+
try {
|
|
47
|
+
logger.debug(`${method} ${url.toString()}`, {
|
|
48
|
+
attempt,
|
|
49
|
+
body: options.body,
|
|
50
|
+
});
|
|
51
|
+
const response = await fetch(url.toString(), {
|
|
52
|
+
method,
|
|
53
|
+
headers,
|
|
54
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
55
|
+
});
|
|
56
|
+
const responseText = await response.text();
|
|
57
|
+
logger.debug(`Response status: ${response.status}`, {
|
|
58
|
+
status: response.status,
|
|
59
|
+
body: responseText.substring(0, 500),
|
|
60
|
+
});
|
|
61
|
+
if (response.status >= 400) {
|
|
62
|
+
let details;
|
|
63
|
+
try {
|
|
64
|
+
details = JSON.parse(responseText);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
details = responseText;
|
|
68
|
+
}
|
|
69
|
+
logger.warn(`API Error: ${response.status}`, {
|
|
70
|
+
url: url.toString(),
|
|
71
|
+
status: response.status,
|
|
72
|
+
details,
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: `API request failed with status ${response.status}`,
|
|
77
|
+
statusCode: response.status,
|
|
78
|
+
details,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// Parse successful response
|
|
82
|
+
let data;
|
|
83
|
+
try {
|
|
84
|
+
data = JSON.parse(responseText);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
data = responseText;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
success: true,
|
|
91
|
+
data,
|
|
92
|
+
statusCode: response.status,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
97
|
+
logger.warn(`Request failed (attempt ${attempt}/${MAX_RETRIES})`, {
|
|
98
|
+
error: lastError.message,
|
|
99
|
+
url: url.toString(),
|
|
100
|
+
});
|
|
101
|
+
// Only retry on network errors, not on 4xx/5xx
|
|
102
|
+
if (attempt < MAX_RETRIES) {
|
|
103
|
+
await this.delay(RETRY_DELAY_MS * attempt); // Exponential backoff
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
logger.error('All retry attempts failed', lastError);
|
|
108
|
+
return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: `Network error after ${MAX_RETRIES} attempts: ${lastError?.message}`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
delay(ms) {
|
|
114
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Make HTTP request sending form data (multipart/form-data) instead of JSON.
|
|
118
|
+
* Used for endpoints that expect Form() parameters (e.g. rules).
|
|
119
|
+
*/
|
|
120
|
+
async makeFormDataRequest(method, endpoint, data, params) {
|
|
121
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
122
|
+
if (params) {
|
|
123
|
+
for (const [key, value] of Object.entries(params)) {
|
|
124
|
+
if (value !== undefined && value !== null) {
|
|
125
|
+
if (Array.isArray(value)) {
|
|
126
|
+
value.forEach((v) => url.searchParams.append(key, String(v)));
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
url.searchParams.set(key, String(value));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
let lastError = null;
|
|
135
|
+
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
136
|
+
try {
|
|
137
|
+
const formData = new FormData();
|
|
138
|
+
for (const [key, value] of Object.entries(data)) {
|
|
139
|
+
if (value === undefined || value === null)
|
|
140
|
+
continue;
|
|
141
|
+
if (Array.isArray(value)) {
|
|
142
|
+
value.forEach((v) => formData.append(key, String(v)));
|
|
143
|
+
}
|
|
144
|
+
else if (typeof value === 'boolean') {
|
|
145
|
+
formData.append(key, value ? 'true' : 'false');
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
formData.append(key, String(value));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
logger.debug(`${method} ${url.toString()} (form-data)`, {
|
|
152
|
+
attempt,
|
|
153
|
+
fields: Object.keys(data),
|
|
154
|
+
});
|
|
155
|
+
const response = await fetch(url.toString(), {
|
|
156
|
+
method,
|
|
157
|
+
headers: {
|
|
158
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
159
|
+
},
|
|
160
|
+
body: formData,
|
|
161
|
+
});
|
|
162
|
+
const responseText = await response.text();
|
|
163
|
+
logger.debug(`Response status: ${response.status}`, {
|
|
164
|
+
status: response.status,
|
|
165
|
+
body: responseText.substring(0, 500),
|
|
166
|
+
});
|
|
167
|
+
if (response.status >= 400) {
|
|
168
|
+
let details;
|
|
169
|
+
try {
|
|
170
|
+
details = JSON.parse(responseText);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
details = responseText;
|
|
174
|
+
}
|
|
175
|
+
logger.warn(`API Error: ${response.status}`, {
|
|
176
|
+
url: url.toString(),
|
|
177
|
+
status: response.status,
|
|
178
|
+
details,
|
|
179
|
+
});
|
|
180
|
+
return {
|
|
181
|
+
success: false,
|
|
182
|
+
error: `API request failed with status ${response.status}`,
|
|
183
|
+
statusCode: response.status,
|
|
184
|
+
details,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
let responseData;
|
|
188
|
+
try {
|
|
189
|
+
responseData = JSON.parse(responseText);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
responseData = responseText;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
success: true,
|
|
196
|
+
data: responseData,
|
|
197
|
+
statusCode: response.status,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
202
|
+
logger.warn(`Request failed (attempt ${attempt}/${MAX_RETRIES})`, {
|
|
203
|
+
error: lastError.message,
|
|
204
|
+
url: url.toString(),
|
|
205
|
+
});
|
|
206
|
+
if (attempt < MAX_RETRIES) {
|
|
207
|
+
await this.delay(RETRY_DELAY_MS * attempt);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
logger.error('All retry attempts failed', lastError);
|
|
212
|
+
return {
|
|
213
|
+
success: false,
|
|
214
|
+
error: `Network error after ${MAX_RETRIES} attempts: ${lastError?.message}`,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* CRITICAL: Transform flat agent data into nested structure expected by API
|
|
219
|
+
* - prompt must be {"user_prompt": "text"}, NOT just a string!
|
|
220
|
+
* - conversation config goes into "conversation" object
|
|
221
|
+
* - features config goes into "features" object
|
|
222
|
+
* - template config goes into "template" object
|
|
223
|
+
*/
|
|
224
|
+
prepareAgentData(agentData) {
|
|
225
|
+
const llmFields = [
|
|
226
|
+
'model', 'prompt', 'first_message', 'temperature', 'max_tokens',
|
|
227
|
+
'reasoning_effort', 'llm_fixed', 'prompt_hidden', 'customizable_variables',
|
|
228
|
+
];
|
|
229
|
+
const conversationFields = [
|
|
230
|
+
'language', 'multi_language', 'language_presets', 'voice_id', 'voice_ids',
|
|
231
|
+
'speed', 'interruption', 'record_voice', 'retention_days',
|
|
232
|
+
'max_duration_seconds', 'max_duration_message', 'agent_concurrency_limit',
|
|
233
|
+
'stt_provider', 'stt_model',
|
|
234
|
+
'background_sound_config', 'noise_cancellation_config', 'voice_mode',
|
|
235
|
+
];
|
|
236
|
+
const visibilityFields = ['visibility', 'hide_details', 'hidden'];
|
|
237
|
+
const inheritanceFields = ['parent_id', 'enable_childs'];
|
|
238
|
+
// Fields that are already nested and should pass through directly
|
|
239
|
+
const directFields = ['name', 'description', 'tags', 'features', 'workflow', 'chat', 'preview'];
|
|
240
|
+
const llmConfig = {};
|
|
241
|
+
const conversationConfig = {};
|
|
242
|
+
const templateConfig = {};
|
|
243
|
+
const visibilityConfig = {};
|
|
244
|
+
const inheritanceConfig = {};
|
|
245
|
+
const remainingData = {};
|
|
246
|
+
for (const [key, value] of Object.entries(agentData)) {
|
|
247
|
+
if (value === null || value === undefined) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (directFields.includes(key)) {
|
|
251
|
+
remainingData[key] = value;
|
|
252
|
+
}
|
|
253
|
+
else if (llmFields.includes(key)) {
|
|
254
|
+
if (key === 'prompt') {
|
|
255
|
+
if (typeof value === 'string') {
|
|
256
|
+
llmConfig.prompt = { user_prompt: value };
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
llmConfig.prompt = value;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
llmConfig[key] = value;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
else if (conversationFields.includes(key)) {
|
|
267
|
+
if (key === 'voice_id' && typeof value === 'string') {
|
|
268
|
+
conversationConfig.voice_ids = [value];
|
|
269
|
+
}
|
|
270
|
+
else if (key === 'background_sound_config') {
|
|
271
|
+
conversationConfig.background_sound = value;
|
|
272
|
+
}
|
|
273
|
+
else if (key === 'noise_cancellation_config') {
|
|
274
|
+
conversationConfig.noise_cancellation = value;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
conversationConfig[key] = value;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else if (visibilityFields.includes(key)) {
|
|
281
|
+
visibilityConfig[key] = value;
|
|
282
|
+
}
|
|
283
|
+
else if (inheritanceFields.includes(key)) {
|
|
284
|
+
inheritanceConfig[key] = value;
|
|
285
|
+
}
|
|
286
|
+
else if (key === 'template_id' || key === 'is_template') {
|
|
287
|
+
templateConfig[key] = value;
|
|
288
|
+
}
|
|
289
|
+
else if (key === 'template_variables') {
|
|
290
|
+
templateConfig.template_variables = { _values: value };
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
remainingData[key] = value;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (Object.keys(llmConfig).length > 0) {
|
|
297
|
+
remainingData.llm = llmConfig;
|
|
298
|
+
}
|
|
299
|
+
if (Object.keys(conversationConfig).length > 0) {
|
|
300
|
+
remainingData.conversation = conversationConfig;
|
|
301
|
+
}
|
|
302
|
+
if (Object.keys(templateConfig).length > 0) {
|
|
303
|
+
remainingData.template = templateConfig;
|
|
304
|
+
}
|
|
305
|
+
if (Object.keys(visibilityConfig).length > 0) {
|
|
306
|
+
remainingData.visibility = visibilityConfig;
|
|
307
|
+
}
|
|
308
|
+
if (Object.keys(inheritanceConfig).length > 0) {
|
|
309
|
+
remainingData.inheritance = inheritanceConfig;
|
|
310
|
+
}
|
|
311
|
+
logger.debug('Transformed agent data', { transformed: remainingData });
|
|
312
|
+
return remainingData;
|
|
313
|
+
}
|
|
314
|
+
// ==================== AGENT METHODS ====================
|
|
315
|
+
async createAgent(agentData, targetUserId) {
|
|
316
|
+
const preparedData = this.prepareAgentData(agentData);
|
|
317
|
+
const params = {};
|
|
318
|
+
if (targetUserId)
|
|
319
|
+
params.target_user_id = targetUserId;
|
|
320
|
+
return this.makeRequest('POST', '/agents/', { body: preparedData, params });
|
|
321
|
+
}
|
|
322
|
+
async updateAgent(agentId, agentData, targetUserId) {
|
|
323
|
+
const preparedData = this.prepareAgentData(agentData);
|
|
324
|
+
const params = {};
|
|
325
|
+
if (targetUserId)
|
|
326
|
+
params.target_user_id = targetUserId;
|
|
327
|
+
return this.makeRequest('PATCH', `/agents/${agentId}`, { body: preparedData, params });
|
|
328
|
+
}
|
|
329
|
+
async getAgent(agentId) {
|
|
330
|
+
return this.makeRequest('GET', `/agents/${agentId}`);
|
|
331
|
+
}
|
|
332
|
+
async listAgents(params = {}) {
|
|
333
|
+
return this.makeRequest('GET', '/agents/', { params });
|
|
334
|
+
}
|
|
335
|
+
async deleteAgent(agentId, targetUserId) {
|
|
336
|
+
const params = {};
|
|
337
|
+
if (targetUserId)
|
|
338
|
+
params.target_user_id = targetUserId;
|
|
339
|
+
return this.makeRequest('DELETE', `/agents/${agentId}`, { params });
|
|
340
|
+
}
|
|
341
|
+
async duplicateAgent(agentId, targetUserId) {
|
|
342
|
+
const params = {};
|
|
343
|
+
if (targetUserId)
|
|
344
|
+
params.target_user_id = targetUserId;
|
|
345
|
+
return this.makeRequest('GET', `/agents/${agentId}/duplicate`, { params });
|
|
346
|
+
}
|
|
347
|
+
async getAgentStats(params = {}) {
|
|
348
|
+
return this.makeRequest('GET', '/agents/stats', { params });
|
|
349
|
+
}
|
|
350
|
+
async listChildAgents(agentId, includeDescendants = false) {
|
|
351
|
+
return this.makeRequest('GET', `/agents/${agentId}/children`, {
|
|
352
|
+
params: { include_descendants: includeDescendants },
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
// ==================== CALL METHODS ====================
|
|
356
|
+
async listCalls(params = {}) {
|
|
357
|
+
return this.makeRequest('GET', '/calls/', { params });
|
|
358
|
+
}
|
|
359
|
+
async initiateCall(callData) {
|
|
360
|
+
return this.makeRequest('POST', '/calls/', { body: callData });
|
|
361
|
+
}
|
|
362
|
+
async getCallDetails(callId, targetUserId) {
|
|
363
|
+
const params = {};
|
|
364
|
+
if (targetUserId)
|
|
365
|
+
params.target_user_id = targetUserId;
|
|
366
|
+
return this.makeRequest('GET', `/calls/${callId}`, { params });
|
|
367
|
+
}
|
|
368
|
+
async deleteCall(callId, memoryOnly = false) {
|
|
369
|
+
return this.makeRequest('DELETE', `/calls/${callId}`, {
|
|
370
|
+
params: { memory_only: memoryOnly },
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
async submitCallFeedback(callId, rating, note) {
|
|
374
|
+
const data = { rating };
|
|
375
|
+
if (note)
|
|
376
|
+
data.note = note;
|
|
377
|
+
return this.makeRequest('POST', `/calls/${callId}/feedback`, { body: data });
|
|
378
|
+
}
|
|
379
|
+
async getCallFeedback(callId) {
|
|
380
|
+
return this.makeRequest('GET', `/calls/${callId}/feedback`);
|
|
381
|
+
}
|
|
382
|
+
async cleanupExpiredCalls(params = {}) {
|
|
383
|
+
return this.makeRequest('GET', '/calls/cleanup', { params });
|
|
384
|
+
}
|
|
385
|
+
// ==================== TEMPLATE METHODS ====================
|
|
386
|
+
async listTemplates(params = {}) {
|
|
387
|
+
return this.makeRequest('GET', '/agents/templates', { params });
|
|
388
|
+
}
|
|
389
|
+
async getTemplate(templateId, targetUserId) {
|
|
390
|
+
const params = {};
|
|
391
|
+
if (targetUserId)
|
|
392
|
+
params.target_user_id = targetUserId;
|
|
393
|
+
return this.makeRequest('GET', `/agents/templates/${templateId}`, { params });
|
|
394
|
+
}
|
|
395
|
+
async createTemplate(templateData, targetUserId) {
|
|
396
|
+
const params = {};
|
|
397
|
+
if (targetUserId)
|
|
398
|
+
params.target_user_id = targetUserId;
|
|
399
|
+
return this.makeRequest('POST', '/agents/templates', { body: templateData, params });
|
|
400
|
+
}
|
|
401
|
+
async updateTemplate(templateId, templateData, targetUserId) {
|
|
402
|
+
const params = {};
|
|
403
|
+
if (targetUserId)
|
|
404
|
+
params.target_user_id = targetUserId;
|
|
405
|
+
return this.makeRequest('PATCH', `/agents/templates/${templateId}`, { body: templateData, params });
|
|
406
|
+
}
|
|
407
|
+
async deleteTemplate(templateId, targetUserId) {
|
|
408
|
+
const params = {};
|
|
409
|
+
if (targetUserId)
|
|
410
|
+
params.target_user_id = targetUserId;
|
|
411
|
+
return this.makeRequest('DELETE', `/agents/templates/${templateId}`, { params });
|
|
412
|
+
}
|
|
413
|
+
// ==================== AGENT VERSIONING METHODS (API-Sync 2026-01) ====================
|
|
414
|
+
/**
|
|
415
|
+
* Get agent with optional specific version
|
|
416
|
+
* @param agentId - Agent UUID
|
|
417
|
+
* @param version - Optional version UUID (defaults to draft version)
|
|
418
|
+
*/
|
|
419
|
+
async getAgentVersion(agentId, version, targetUserId) {
|
|
420
|
+
const params = {};
|
|
421
|
+
if (version)
|
|
422
|
+
params.version = version;
|
|
423
|
+
if (targetUserId)
|
|
424
|
+
params.target_user_id = targetUserId;
|
|
425
|
+
return this.makeRequest('GET', `/agents/${agentId}`, { params });
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Publish the current draft version of an agent
|
|
429
|
+
* Creates an immutable snapshot that can be used in production
|
|
430
|
+
*/
|
|
431
|
+
async publishAgentVersion(agentId, versionName, targetUserId) {
|
|
432
|
+
const body = {};
|
|
433
|
+
if (versionName)
|
|
434
|
+
body.version_name = versionName;
|
|
435
|
+
const params = {};
|
|
436
|
+
if (targetUserId)
|
|
437
|
+
params.target_user_id = targetUserId;
|
|
438
|
+
return this.makeRequest('POST', `/agents/${agentId}/publish`, { body, params });
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* List all versions of an agent (draft, published, archived)
|
|
442
|
+
*/
|
|
443
|
+
async listAgentVersions(agentId, includeDraft = true, includeArchived = false) {
|
|
444
|
+
return this.makeRequest('GET', `/agents/${agentId}/versions`, {
|
|
445
|
+
params: { include_draft: includeDraft, include_archived: includeArchived },
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Configure A/B testing traffic distribution between agent versions
|
|
450
|
+
* @param config - Map of version_id to weight (0.0-1.0), or null for latest_published mode
|
|
451
|
+
*/
|
|
452
|
+
async configureAgentTraffic(agentId, config) {
|
|
453
|
+
return this.makeRequest('PUT', `/agents/${agentId}/traffic`, { body: { config } });
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Get current traffic distribution statistics for an agent
|
|
457
|
+
*/
|
|
458
|
+
async getAgentTrafficStats(agentId) {
|
|
459
|
+
return this.makeRequest('GET', `/agents/${agentId}/traffic`);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Archive a published version (removes from A/B testing pool)
|
|
463
|
+
*/
|
|
464
|
+
async archiveAgentVersion(agentId, versionId) {
|
|
465
|
+
return this.makeRequest('PATCH', `/agents/${agentId}`, {
|
|
466
|
+
params: { version: versionId },
|
|
467
|
+
body: { status: 'archived' },
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
// ==================== EXTENDED AGENT METHODS (Phase 1) ====================
|
|
471
|
+
async refreshAgents(params = {}) {
|
|
472
|
+
return this.makeRequest('POST', '/agents/refresh', { params });
|
|
473
|
+
}
|
|
474
|
+
async transferAgent(transferData) {
|
|
475
|
+
return this.makeRequest('POST', '/agents/transfer', { body: transferData });
|
|
476
|
+
}
|
|
477
|
+
async getAgentStatistics(agentId, params = {}) {
|
|
478
|
+
return this.makeRequest('GET', `/agents/${agentId}/statistics`, { params });
|
|
479
|
+
}
|
|
480
|
+
// ==================== EXTENDED CALL METHODS (Phase 1) ====================
|
|
481
|
+
async markCallsAsRead(callIds, unread = false) {
|
|
482
|
+
return this.makeRequest('PATCH', '/calls/mark-read', { body: { call_ids: callIds, unread } });
|
|
483
|
+
}
|
|
484
|
+
async listCallCategories() {
|
|
485
|
+
return this.makeRequest('GET', '/calls/categories');
|
|
486
|
+
}
|
|
487
|
+
async updateCallCategories(categories) {
|
|
488
|
+
return this.makeRequest('PATCH', '/calls/categories', { body: { categories } });
|
|
489
|
+
}
|
|
490
|
+
async updateCallMetadata(callId, metadata) {
|
|
491
|
+
return this.makeRequest('PATCH', `/calls/${callId}`, { body: metadata });
|
|
492
|
+
}
|
|
493
|
+
// ==================== CONTACT METHODS (Phase 1) ====================
|
|
494
|
+
async listContacts(params = {}) {
|
|
495
|
+
// Convert offset to skip for backend compatibility
|
|
496
|
+
if (params.offset !== undefined) {
|
|
497
|
+
params.skip = params.offset;
|
|
498
|
+
delete params.offset;
|
|
499
|
+
}
|
|
500
|
+
return this.makeRequest('GET', '/contacts/', { params });
|
|
501
|
+
}
|
|
502
|
+
async getContact(contactId, targetUserId) {
|
|
503
|
+
const params = {};
|
|
504
|
+
if (targetUserId)
|
|
505
|
+
params.target_user_id = targetUserId;
|
|
506
|
+
return this.makeRequest('GET', `/contacts/${contactId}`, { params });
|
|
507
|
+
}
|
|
508
|
+
async createContact(contactData, targetUserId) {
|
|
509
|
+
const params = {};
|
|
510
|
+
if (targetUserId)
|
|
511
|
+
params.target_user_id = targetUserId;
|
|
512
|
+
return this.makeRequest('POST', '/contacts/', { body: [contactData], params });
|
|
513
|
+
}
|
|
514
|
+
async updateContact(contactId, contactData, targetUserId) {
|
|
515
|
+
const params = {};
|
|
516
|
+
if (targetUserId)
|
|
517
|
+
params.target_user_id = targetUserId;
|
|
518
|
+
return this.makeRequest('PATCH', `/contacts/${contactId}`, { body: contactData, params });
|
|
519
|
+
}
|
|
520
|
+
async deleteContact(contactId, targetUserId) {
|
|
521
|
+
const params = {};
|
|
522
|
+
if (targetUserId)
|
|
523
|
+
params.target_user_id = targetUserId;
|
|
524
|
+
return this.makeRequest('DELETE', `/contacts/${contactId}`, { params });
|
|
525
|
+
}
|
|
526
|
+
async bulkDeleteContacts(contactIds) {
|
|
527
|
+
return this.makeRequest('DELETE', '/contacts/', { body: { contact_ids: contactIds } });
|
|
528
|
+
}
|
|
529
|
+
async manageContactCategories(contactId, action, categories) {
|
|
530
|
+
return this.makeRequest('POST', `/contacts/${contactId}/categories`, {
|
|
531
|
+
body: { action, categories },
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Import contacts from CSV/Excel file
|
|
536
|
+
* Note: This requires multipart/form-data which needs special handling
|
|
537
|
+
*/
|
|
538
|
+
async importContacts(file, fileName, params = {}) {
|
|
539
|
+
const url = `${this.baseUrl}/contacts/import`;
|
|
540
|
+
try {
|
|
541
|
+
const formData = new FormData();
|
|
542
|
+
// Detect mime type
|
|
543
|
+
const mimeType = fileName.endsWith('.csv')
|
|
544
|
+
? 'text/csv'
|
|
545
|
+
: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
|
|
546
|
+
const blob = new Blob([file], { type: mimeType });
|
|
547
|
+
formData.append('file', blob, fileName);
|
|
548
|
+
// Add params as form fields
|
|
549
|
+
for (const [key, value] of Object.entries(params)) {
|
|
550
|
+
if (value !== undefined && value !== null) {
|
|
551
|
+
formData.append(key, String(value));
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
const response = await fetch(url, {
|
|
555
|
+
method: 'POST',
|
|
556
|
+
headers: {
|
|
557
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
558
|
+
},
|
|
559
|
+
body: formData,
|
|
560
|
+
});
|
|
561
|
+
const responseText = await response.text();
|
|
562
|
+
if (response.status >= 400) {
|
|
563
|
+
let details;
|
|
564
|
+
try {
|
|
565
|
+
details = JSON.parse(responseText);
|
|
566
|
+
}
|
|
567
|
+
catch {
|
|
568
|
+
details = responseText;
|
|
569
|
+
}
|
|
570
|
+
return {
|
|
571
|
+
success: false,
|
|
572
|
+
error: `Import failed with status ${response.status}`,
|
|
573
|
+
statusCode: response.status,
|
|
574
|
+
details,
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
let data;
|
|
578
|
+
try {
|
|
579
|
+
data = JSON.parse(responseText);
|
|
580
|
+
}
|
|
581
|
+
catch {
|
|
582
|
+
data = responseText;
|
|
583
|
+
}
|
|
584
|
+
return {
|
|
585
|
+
success: true,
|
|
586
|
+
data,
|
|
587
|
+
statusCode: response.status,
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
catch (error) {
|
|
591
|
+
logger.error('Contact import failed', error);
|
|
592
|
+
return {
|
|
593
|
+
success: false,
|
|
594
|
+
error: `Import error: ${error instanceof Error ? error.message : String(error)}`,
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
// REMOVED: Campaign methods - campaigns not implemented in backend
|
|
599
|
+
// ==================== RULES METHODS (Phase 1) ====================
|
|
600
|
+
async listRules(params = {}) {
|
|
601
|
+
if (params.offset !== undefined) {
|
|
602
|
+
params.skip = params.offset;
|
|
603
|
+
delete params.offset;
|
|
604
|
+
}
|
|
605
|
+
return this.makeRequest('GET', '/rules/', { params });
|
|
606
|
+
}
|
|
607
|
+
async getRule(ruleId) {
|
|
608
|
+
return this.makeRequest('GET', `/rules/${ruleId}`);
|
|
609
|
+
}
|
|
610
|
+
async createRule(ruleData) {
|
|
611
|
+
return this.makeFormDataRequest('POST', '/rules/', ruleData);
|
|
612
|
+
}
|
|
613
|
+
async updateRule(ruleId, ruleData) {
|
|
614
|
+
return this.makeFormDataRequest('PATCH', `/rules/${ruleId}`, ruleData);
|
|
615
|
+
}
|
|
616
|
+
async deleteRule(ruleId) {
|
|
617
|
+
return this.makeRequest('DELETE', `/rules/${ruleId}`);
|
|
618
|
+
}
|
|
619
|
+
async getRateLimitSettings(params = {}) {
|
|
620
|
+
return this.makeRequest('GET', '/rules/rate-limit', { params });
|
|
621
|
+
}
|
|
622
|
+
async updateRateLimitSettings(rateLimitData) {
|
|
623
|
+
return this.makeRequest('PUT', '/rules/rate-limit', { body: rateLimitData });
|
|
624
|
+
}
|
|
625
|
+
async deleteRateLimitSettings(settingsId) {
|
|
626
|
+
return this.makeRequest('DELETE', `/rules/rate-limit/${settingsId}`);
|
|
627
|
+
}
|
|
628
|
+
// ==================== NUMBERS METHODS (Reworked API-Sync 2026-01 - Replaces Hotlines) ====================
|
|
629
|
+
async listPhoneNumbers(params = {}) {
|
|
630
|
+
if (params.offset !== undefined) {
|
|
631
|
+
params.skip = params.offset;
|
|
632
|
+
delete params.offset;
|
|
633
|
+
}
|
|
634
|
+
return this.makeRequest('GET', '/numbers/', { params });
|
|
635
|
+
}
|
|
636
|
+
async getPhoneNumber(numberId) {
|
|
637
|
+
return this.makeRequest('GET', `/numbers/${numberId}`);
|
|
638
|
+
}
|
|
639
|
+
async provisionPhoneNumber(numberData, targetUserId) {
|
|
640
|
+
const params = {};
|
|
641
|
+
if (targetUserId)
|
|
642
|
+
params.target_user_id = targetUserId;
|
|
643
|
+
return this.makeRequest('POST', '/numbers/', { body: numberData, params });
|
|
644
|
+
}
|
|
645
|
+
async updatePhoneNumber(numberId, numberData, targetUserId) {
|
|
646
|
+
const params = {};
|
|
647
|
+
if (targetUserId)
|
|
648
|
+
params.target_user_id = targetUserId;
|
|
649
|
+
return this.makeRequest('PATCH', `/numbers/${numberId}`, { body: numberData, params });
|
|
650
|
+
}
|
|
651
|
+
async releasePhoneNumber(numberId, targetUserId) {
|
|
652
|
+
const params = {};
|
|
653
|
+
if (targetUserId)
|
|
654
|
+
params.target_user_id = targetUserId;
|
|
655
|
+
return this.makeRequest('DELETE', `/numbers/${numberId}`, { params });
|
|
656
|
+
}
|
|
657
|
+
async searchAvailableNumbers(params = {}) {
|
|
658
|
+
return this.makeRequest('GET', '/numbers/available', { params });
|
|
659
|
+
}
|
|
660
|
+
// --- NEW: Agent Assignment (replaces Hotlines) ---
|
|
661
|
+
/**
|
|
662
|
+
* Assign an agent to a phone number for inbound call routing
|
|
663
|
+
* This replaces the old hotlines functionality
|
|
664
|
+
*/
|
|
665
|
+
async assignNumberToAgent(numberId, agentId) {
|
|
666
|
+
return this.makeRequest('PATCH', `/numbers/${numberId}`, { body: { agent_id: agentId } });
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Remove agent assignment from a phone number
|
|
670
|
+
*/
|
|
671
|
+
async unassignNumber(numberId) {
|
|
672
|
+
return this.makeRequest('PATCH', `/numbers/${numberId}`, { body: { agent_id: null } });
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Get the effective area code based on organization/whitelabel settings
|
|
676
|
+
*/
|
|
677
|
+
async getEffectiveAreaCode() {
|
|
678
|
+
return this.makeRequest('GET', '/numbers/effective-area-code');
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Transfer numbers to another user
|
|
682
|
+
*/
|
|
683
|
+
async transferNumbers(numberIds, targetUserId) {
|
|
684
|
+
return this.makeRequest('POST', '/numbers/transfer', {
|
|
685
|
+
body: { number_ids: numberIds, target_user_id: targetUserId },
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Refresh Twilio webhooks for all numbers (Admin only)
|
|
690
|
+
*/
|
|
691
|
+
async refreshNumberWebhooks(forceRefresh = false) {
|
|
692
|
+
return this.makeRequest('POST', '/numbers/refresh', { params: { force_refresh: forceRefresh } });
|
|
693
|
+
}
|
|
694
|
+
// ==================== VOICES METHODS (Phase 2) ====================
|
|
695
|
+
async listVoices(params = {}) {
|
|
696
|
+
return this.makeRequest('GET', '/voices/', { params });
|
|
697
|
+
}
|
|
698
|
+
async getVoice(voiceId) {
|
|
699
|
+
return this.makeRequest('GET', `/voices/${voiceId}`);
|
|
700
|
+
}
|
|
701
|
+
async refreshVoices() {
|
|
702
|
+
return this.makeRequest('POST', '/voices/refresh');
|
|
703
|
+
}
|
|
704
|
+
// ==================== VOICE PREVIEW METHODS (Phase 2) ====================
|
|
705
|
+
async generateVoicePreview(previewData) {
|
|
706
|
+
return this.makeRequest('POST', '/voice-preview/', { body: previewData });
|
|
707
|
+
}
|
|
708
|
+
async getVoicePreview(previewId) {
|
|
709
|
+
return this.makeRequest('GET', `/voice-preview/${previewId}`);
|
|
710
|
+
}
|
|
711
|
+
// ==================== HOTLINES METHODS (DEPRECATED - Use Numbers with agent_id) ====================
|
|
712
|
+
// API-Sync 2026-01: Hotlines have been replaced by direct agent assignment on Numbers
|
|
713
|
+
// Use assignNumberToAgent() and unassignNumber() instead
|
|
714
|
+
// ==================== FORWARDING METHODS (Phase 2) ====================
|
|
715
|
+
async refreshForwardingRules() {
|
|
716
|
+
return this.makeRequest('POST', '/forwarding/refresh');
|
|
717
|
+
}
|
|
718
|
+
// ==================== MEDIA METHODS (Phase 2) ====================
|
|
719
|
+
async listMedia(params = {}) {
|
|
720
|
+
return this.makeRequest('GET', '/media/', { params });
|
|
721
|
+
}
|
|
722
|
+
async getMedia(mediaId) {
|
|
723
|
+
return this.makeRequest('GET', `/media/${mediaId}`);
|
|
724
|
+
}
|
|
725
|
+
async deleteMedia(gcsUrl, bucketType) {
|
|
726
|
+
const params = new URLSearchParams({ gcs_url: gcsUrl, bucket_type: bucketType });
|
|
727
|
+
return this.makeRequest('DELETE', `/media?${params.toString()}`);
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Upload media file (audio or image)
|
|
731
|
+
* Note: This requires multipart/form-data which needs special handling
|
|
732
|
+
*/
|
|
733
|
+
async uploadMedia(file, fileName, mediaType, params = {}) {
|
|
734
|
+
const url = `${this.baseUrl}/media/upload`;
|
|
735
|
+
try {
|
|
736
|
+
const formData = new FormData();
|
|
737
|
+
// Detect mime type based on file extension
|
|
738
|
+
const ext = fileName.toLowerCase().split('.').pop();
|
|
739
|
+
let mimeType = 'application/octet-stream';
|
|
740
|
+
if (mediaType === 'audio') {
|
|
741
|
+
if (ext === 'mp3')
|
|
742
|
+
mimeType = 'audio/mpeg';
|
|
743
|
+
else if (ext === 'wav')
|
|
744
|
+
mimeType = 'audio/wav';
|
|
745
|
+
else if (ext === 'ogg')
|
|
746
|
+
mimeType = 'audio/ogg';
|
|
747
|
+
else if (ext === 'm4a')
|
|
748
|
+
mimeType = 'audio/mp4';
|
|
749
|
+
}
|
|
750
|
+
else if (mediaType === 'image') {
|
|
751
|
+
if (ext === 'png')
|
|
752
|
+
mimeType = 'image/png';
|
|
753
|
+
else if (ext === 'jpg' || ext === 'jpeg')
|
|
754
|
+
mimeType = 'image/jpeg';
|
|
755
|
+
else if (ext === 'gif')
|
|
756
|
+
mimeType = 'image/gif';
|
|
757
|
+
else if (ext === 'webp')
|
|
758
|
+
mimeType = 'image/webp';
|
|
759
|
+
}
|
|
760
|
+
const blob = new Blob([file], { type: mimeType });
|
|
761
|
+
formData.append('file', blob, fileName);
|
|
762
|
+
formData.append('media_type', mediaType);
|
|
763
|
+
// Add additional params
|
|
764
|
+
for (const [key, value] of Object.entries(params)) {
|
|
765
|
+
if (value !== undefined && value !== null) {
|
|
766
|
+
formData.append(key, String(value));
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
const response = await fetch(url, {
|
|
770
|
+
method: 'POST',
|
|
771
|
+
headers: {
|
|
772
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
773
|
+
},
|
|
774
|
+
body: formData,
|
|
775
|
+
});
|
|
776
|
+
const responseText = await response.text();
|
|
777
|
+
if (response.status >= 400) {
|
|
778
|
+
let details;
|
|
779
|
+
try {
|
|
780
|
+
details = JSON.parse(responseText);
|
|
781
|
+
}
|
|
782
|
+
catch {
|
|
783
|
+
details = responseText;
|
|
784
|
+
}
|
|
785
|
+
return {
|
|
786
|
+
success: false,
|
|
787
|
+
error: `Upload failed with status ${response.status}`,
|
|
788
|
+
statusCode: response.status,
|
|
789
|
+
details,
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
let data;
|
|
793
|
+
try {
|
|
794
|
+
data = JSON.parse(responseText);
|
|
795
|
+
}
|
|
796
|
+
catch {
|
|
797
|
+
data = responseText;
|
|
798
|
+
}
|
|
799
|
+
return {
|
|
800
|
+
success: true,
|
|
801
|
+
data,
|
|
802
|
+
statusCode: response.status,
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
catch (error) {
|
|
806
|
+
logger.error('Media upload failed', error);
|
|
807
|
+
return {
|
|
808
|
+
success: false,
|
|
809
|
+
error: `Upload error: ${error instanceof Error ? error.message : String(error)}`,
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
async generateTTS(ttsData) {
|
|
814
|
+
return this.makeRequest('POST', '/media/generate-tts', { body: ttsData });
|
|
815
|
+
}
|
|
816
|
+
// ==================== PRONUNCIATIONS METHODS (Phase 2) ====================
|
|
817
|
+
async listPronunciations(params = {}) {
|
|
818
|
+
return this.makeRequest('GET', '/pronunciations/', { params });
|
|
819
|
+
}
|
|
820
|
+
async getPronunciation(pronunciationId) {
|
|
821
|
+
return this.makeRequest('GET', `/pronunciations/${pronunciationId}`);
|
|
822
|
+
}
|
|
823
|
+
async createPronunciation(pronunciationData, targetUserId) {
|
|
824
|
+
const params = {};
|
|
825
|
+
if (targetUserId)
|
|
826
|
+
params.target_user_id = targetUserId;
|
|
827
|
+
return this.makeRequest('POST', '/pronunciations/', { body: pronunciationData, params });
|
|
828
|
+
}
|
|
829
|
+
async updatePronunciation(pronunciationId, pronunciationData, targetUserId) {
|
|
830
|
+
const params = {};
|
|
831
|
+
if (targetUserId)
|
|
832
|
+
params.target_user_id = targetUserId;
|
|
833
|
+
return this.makeRequest('PATCH', `/pronunciations/${pronunciationId}`, { body: pronunciationData, params });
|
|
834
|
+
}
|
|
835
|
+
async deletePronunciation(pronunciationId, targetUserId) {
|
|
836
|
+
const params = {};
|
|
837
|
+
if (targetUserId)
|
|
838
|
+
params.target_user_id = targetUserId;
|
|
839
|
+
return this.makeRequest('DELETE', `/pronunciations/${pronunciationId}`, { params });
|
|
840
|
+
}
|
|
841
|
+
// ==================== INTEGRATIONS METHODS ====================
|
|
842
|
+
// --- Connections System ---
|
|
843
|
+
async createConnection(connectionData) {
|
|
844
|
+
return this.makeRequest('POST', '/integrations/connections', { body: connectionData });
|
|
845
|
+
}
|
|
846
|
+
async listConnections(params = {}) {
|
|
847
|
+
if (params.offset !== undefined) {
|
|
848
|
+
params.skip = params.offset;
|
|
849
|
+
delete params.offset;
|
|
850
|
+
}
|
|
851
|
+
return this.makeRequest('GET', '/integrations/connections', { params });
|
|
852
|
+
}
|
|
853
|
+
async getConnection(connectionId) {
|
|
854
|
+
return this.makeRequest('GET', `/integrations/connections/${connectionId}`);
|
|
855
|
+
}
|
|
856
|
+
async updateConnection(connectionId, connectionData) {
|
|
857
|
+
return this.makeRequest('PATCH', `/integrations/connections/${connectionId}`, { body: connectionData });
|
|
858
|
+
}
|
|
859
|
+
async deleteConnection(connectionId) {
|
|
860
|
+
return this.makeRequest('DELETE', `/integrations/connections/${connectionId}`);
|
|
861
|
+
}
|
|
862
|
+
async testConnection(connectionId) {
|
|
863
|
+
return this.makeRequest('POST', `/integrations/connections/${connectionId}/test`);
|
|
864
|
+
}
|
|
865
|
+
async listPlatforms() {
|
|
866
|
+
return this.makeRequest('GET', '/integrations/platforms');
|
|
867
|
+
}
|
|
868
|
+
// --- Connection Actions ---
|
|
869
|
+
async createConnectionAction(connectionId, actionData) {
|
|
870
|
+
return this.makeRequest('POST', `/integrations/connections/${connectionId}/actions`, { body: actionData });
|
|
871
|
+
}
|
|
872
|
+
async updateConnectionAction(connectionId, actionId, actionData) {
|
|
873
|
+
return this.makeRequest('PATCH', `/integrations/connections/${connectionId}/actions/${actionId}`, { body: actionData });
|
|
874
|
+
}
|
|
875
|
+
async deleteConnectionAction(connectionId, actionId) {
|
|
876
|
+
return this.makeRequest('DELETE', `/integrations/connections/${connectionId}/actions/${actionId}`);
|
|
877
|
+
}
|
|
878
|
+
// --- Legacy OAuth (deprecated, use Connections) ---
|
|
879
|
+
async getOAuthAuthorizationUrl(provider, params = {}) {
|
|
880
|
+
return this.makeRequest('GET', `/integrations/oauth/${provider}/authorize`, { params });
|
|
881
|
+
}
|
|
882
|
+
// ==================== POSTPROCESSING METHODS (Phase 3) ====================
|
|
883
|
+
async listPostprocessingResults(params = {}) {
|
|
884
|
+
if (params.offset !== undefined) {
|
|
885
|
+
params.skip = params.offset;
|
|
886
|
+
delete params.offset;
|
|
887
|
+
}
|
|
888
|
+
return this.makeRequest('GET', '/postprocessing/', { params });
|
|
889
|
+
}
|
|
890
|
+
async getPostprocessingResult(resultId, targetUserId) {
|
|
891
|
+
const params = {};
|
|
892
|
+
if (targetUserId)
|
|
893
|
+
params.target_user_id = targetUserId;
|
|
894
|
+
return this.makeRequest('GET', `/postprocessing/${resultId}`, { params });
|
|
895
|
+
}
|
|
896
|
+
async triggerPostprocessing(callId, postprocessingData = {}) {
|
|
897
|
+
return this.makeRequest('POST', '/postprocessing/', { body: { call_id: callId, ...postprocessingData } });
|
|
898
|
+
}
|
|
899
|
+
async updatePostprocessingResult(resultId, resultData) {
|
|
900
|
+
return this.makeRequest('PATCH', `/postprocessing/${resultId}`, { body: resultData });
|
|
901
|
+
}
|
|
902
|
+
async deletePostprocessingResult(resultId) {
|
|
903
|
+
return this.makeRequest('DELETE', `/postprocessing/${resultId}`);
|
|
904
|
+
}
|
|
905
|
+
async updateCallFromPostprocessing(callId, postprocessingData) {
|
|
906
|
+
return this.makeRequest('POST', '/postprocessing/update-call', { body: { call_id: callId, ...postprocessingData } });
|
|
907
|
+
}
|
|
908
|
+
async transferPostprocessingData(transferData) {
|
|
909
|
+
return this.makeRequest('POST', '/postprocessing/transfer', { body: transferData });
|
|
910
|
+
}
|
|
911
|
+
// REMOVED: DNC methods - DNC is now part of rules in backend
|
|
912
|
+
// ==================== CHANNELS METHODS (Phase 6) ====================
|
|
913
|
+
async listChannels(params = {}) {
|
|
914
|
+
if (params.offset !== undefined) {
|
|
915
|
+
params.skip = params.offset;
|
|
916
|
+
delete params.offset;
|
|
917
|
+
}
|
|
918
|
+
return this.makeRequest('GET', '/channels/', { params });
|
|
919
|
+
}
|
|
920
|
+
async getChannel(channelId) {
|
|
921
|
+
return this.makeRequest('GET', `/channels/${channelId}`);
|
|
922
|
+
}
|
|
923
|
+
async configureChannel(channelData, targetUserId) {
|
|
924
|
+
const params = {};
|
|
925
|
+
if (targetUserId)
|
|
926
|
+
params.target_user_id = targetUserId;
|
|
927
|
+
return this.makeRequest('POST', '/channels/', { body: channelData, params });
|
|
928
|
+
}
|
|
929
|
+
// ==================== MAILBOX METHODS (Phase 6) ====================
|
|
930
|
+
async listMailboxMessages(params = {}) {
|
|
931
|
+
if (params.offset !== undefined) {
|
|
932
|
+
params.skip = params.offset;
|
|
933
|
+
delete params.offset;
|
|
934
|
+
}
|
|
935
|
+
return this.makeRequest('GET', '/mailbox/', { params });
|
|
936
|
+
}
|
|
937
|
+
async getMailboxMessage(messageId) {
|
|
938
|
+
return this.makeRequest('GET', `/mailbox/${messageId}`);
|
|
939
|
+
}
|
|
940
|
+
// ==================== USERS METHODS (Phase 4) ====================
|
|
941
|
+
async listUsers(params = {}) {
|
|
942
|
+
if (params.offset !== undefined) {
|
|
943
|
+
params.skip = params.offset;
|
|
944
|
+
delete params.offset;
|
|
945
|
+
}
|
|
946
|
+
return this.makeRequest('GET', '/users/', { params });
|
|
947
|
+
}
|
|
948
|
+
async createUsers(usersData) {
|
|
949
|
+
return this.makeRequest('POST', '/users/', { body: usersData });
|
|
950
|
+
}
|
|
951
|
+
async getCurrentUser() {
|
|
952
|
+
return this.makeRequest('GET', '/users/me');
|
|
953
|
+
}
|
|
954
|
+
async updateCurrentUser(userData) {
|
|
955
|
+
return this.makeRequest('PATCH', '/users/me', { body: userData });
|
|
956
|
+
}
|
|
957
|
+
async changePassword(passwordData) {
|
|
958
|
+
return this.makeRequest('POST', '/users/me/password', { body: passwordData });
|
|
959
|
+
}
|
|
960
|
+
async getUser(userId) {
|
|
961
|
+
return this.makeRequest('GET', `/users/${userId}`);
|
|
962
|
+
}
|
|
963
|
+
async updateUser(userId, userData) {
|
|
964
|
+
return this.makeRequest('PATCH', `/users/${userId}`, { body: userData });
|
|
965
|
+
}
|
|
966
|
+
async deleteUser(userId) {
|
|
967
|
+
return this.makeRequest('DELETE', `/users/${userId}`);
|
|
968
|
+
}
|
|
969
|
+
async getUserPermissions(userId) {
|
|
970
|
+
return this.makeRequest('GET', `/users/${userId}/permissions`);
|
|
971
|
+
}
|
|
972
|
+
async resetUserPassword(userId) {
|
|
973
|
+
return this.makeRequest('POST', `/users/${userId}/reset-password`);
|
|
974
|
+
}
|
|
975
|
+
async listRoles(params = {}) {
|
|
976
|
+
return this.makeRequest('GET', '/users/roles', { params });
|
|
977
|
+
}
|
|
978
|
+
async createRole(roleData) {
|
|
979
|
+
return this.makeRequest('POST', '/users/roles', { body: roleData });
|
|
980
|
+
}
|
|
981
|
+
async updateRole(roleId, roleData) {
|
|
982
|
+
return this.makeRequest('PATCH', `/users/roles/${roleId}`, { body: roleData });
|
|
983
|
+
}
|
|
984
|
+
async deleteRole(roleId) {
|
|
985
|
+
return this.makeRequest('DELETE', `/users/roles/${roleId}`);
|
|
986
|
+
}
|
|
987
|
+
async manageApiKeys(userId, action, keyData) {
|
|
988
|
+
if (action === 'list') {
|
|
989
|
+
return this.makeRequest('GET', `/users/${userId}/keys`);
|
|
990
|
+
}
|
|
991
|
+
else if (action === 'create') {
|
|
992
|
+
return this.makeRequest('POST', `/users/${userId}/keys`, { body: keyData });
|
|
993
|
+
}
|
|
994
|
+
else {
|
|
995
|
+
return this.makeRequest('DELETE', `/users/${userId}/keys/${keyData?.key_id}`);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
// ==================== ORGANIZATIONS METHODS (Phase 4) ====================
|
|
999
|
+
async listOrganizations(params = {}) {
|
|
1000
|
+
if (params.offset !== undefined) {
|
|
1001
|
+
params.skip = params.offset;
|
|
1002
|
+
delete params.offset;
|
|
1003
|
+
}
|
|
1004
|
+
return this.makeRequest('GET', '/organizations/', { params });
|
|
1005
|
+
}
|
|
1006
|
+
async getOrganization(organizationId) {
|
|
1007
|
+
return this.makeRequest('GET', `/organizations/${organizationId}`);
|
|
1008
|
+
}
|
|
1009
|
+
async createOrganization(organizationData) {
|
|
1010
|
+
const { name, description, ...rest } = organizationData;
|
|
1011
|
+
const body = {
|
|
1012
|
+
basic_info: { name, description },
|
|
1013
|
+
...rest,
|
|
1014
|
+
};
|
|
1015
|
+
return this.makeRequest('POST', '/organizations/', { body });
|
|
1016
|
+
}
|
|
1017
|
+
async updateOrganization(organizationId, organizationData) {
|
|
1018
|
+
return this.makeRequest('PATCH', `/organizations/${organizationId}`, { body: organizationData });
|
|
1019
|
+
}
|
|
1020
|
+
async deleteOrganization(organizationId) {
|
|
1021
|
+
return this.makeRequest('DELETE', `/organizations/${organizationId}`);
|
|
1022
|
+
}
|
|
1023
|
+
async getOrganizationSettings(organizationId) {
|
|
1024
|
+
return this.makeRequest('GET', `/organizations/${organizationId}/settings`);
|
|
1025
|
+
}
|
|
1026
|
+
// ==================== WHITELABELS METHODS (Phase 4) ====================
|
|
1027
|
+
async listWhitelabels(params = {}) {
|
|
1028
|
+
if (params.offset !== undefined) {
|
|
1029
|
+
params.skip = params.offset;
|
|
1030
|
+
delete params.offset;
|
|
1031
|
+
}
|
|
1032
|
+
return this.makeRequest('GET', '/whitelabels/', { params });
|
|
1033
|
+
}
|
|
1034
|
+
async getWhitelabel(whitelabelId) {
|
|
1035
|
+
return this.makeRequest('GET', `/whitelabels/${whitelabelId}`);
|
|
1036
|
+
}
|
|
1037
|
+
async createWhitelabel(whitelabelData) {
|
|
1038
|
+
return this.makeRequest('POST', '/whitelabels/', { body: whitelabelData });
|
|
1039
|
+
}
|
|
1040
|
+
async updateWhitelabel(whitelabelId, whitelabelData) {
|
|
1041
|
+
return this.makeRequest('PATCH', `/whitelabels/${whitelabelId}`, { body: whitelabelData });
|
|
1042
|
+
}
|
|
1043
|
+
async deleteWhitelabel(whitelabelId) {
|
|
1044
|
+
return this.makeRequest('DELETE', `/whitelabels/${whitelabelId}`);
|
|
1045
|
+
}
|
|
1046
|
+
// ==================== BILLING METHODS (Phase 4) ====================
|
|
1047
|
+
async getBillingOverview() {
|
|
1048
|
+
return this.makeRequest('GET', '/billing/');
|
|
1049
|
+
}
|
|
1050
|
+
async listInvoices(params = {}) {
|
|
1051
|
+
if (params.offset !== undefined) {
|
|
1052
|
+
params.skip = params.offset;
|
|
1053
|
+
delete params.offset;
|
|
1054
|
+
}
|
|
1055
|
+
return this.makeRequest('GET', '/billing/invoices', { params });
|
|
1056
|
+
}
|
|
1057
|
+
async getInvoice(invoiceId) {
|
|
1058
|
+
return this.makeRequest('GET', `/billing/invoices/${invoiceId}`);
|
|
1059
|
+
}
|
|
1060
|
+
async listTransactions(params = {}) {
|
|
1061
|
+
if (params.offset !== undefined) {
|
|
1062
|
+
params.skip = params.offset;
|
|
1063
|
+
delete params.offset;
|
|
1064
|
+
}
|
|
1065
|
+
return this.makeRequest('GET', '/billing/transactions', { params });
|
|
1066
|
+
}
|
|
1067
|
+
async getPricingPackages() {
|
|
1068
|
+
return this.makeRequest('GET', '/billing/packages');
|
|
1069
|
+
}
|
|
1070
|
+
async getUsage(params = {}) {
|
|
1071
|
+
return this.makeRequest('GET', '/billing/usage', { params });
|
|
1072
|
+
}
|
|
1073
|
+
async getBillingSettings(organizationId) {
|
|
1074
|
+
const path = organizationId ? `/organizations/${organizationId}/billing` : '/billing/settings';
|
|
1075
|
+
return this.makeRequest('GET', path);
|
|
1076
|
+
}
|
|
1077
|
+
async updateBillingSettings(organizationId, data) {
|
|
1078
|
+
const path = organizationId ? `/organizations/${organizationId}/billing` : '/billing/settings';
|
|
1079
|
+
return this.makeRequest('PUT', path, { body: data });
|
|
1080
|
+
}
|
|
1081
|
+
// ==================== CHAT METHODS ====================
|
|
1082
|
+
async createChat(chatData) {
|
|
1083
|
+
return this.makeRequest('POST', '/chats', { body: chatData });
|
|
1084
|
+
}
|
|
1085
|
+
async listChats(params = {}) {
|
|
1086
|
+
return this.makeRequest('GET', '/chats', { params });
|
|
1087
|
+
}
|
|
1088
|
+
async getChat(chatId) {
|
|
1089
|
+
return this.makeRequest('GET', `/chats/${chatId}`);
|
|
1090
|
+
}
|
|
1091
|
+
async deleteChat(chatId) {
|
|
1092
|
+
return this.makeRequest('DELETE', `/chats/${chatId}`);
|
|
1093
|
+
}
|
|
1094
|
+
// ==================== WIDGET CONFIG METHODS ====================
|
|
1095
|
+
async getWidgetConfig(organizationId) {
|
|
1096
|
+
return this.makeRequest('GET', `/organizations/${organizationId}/chat-widget-config`);
|
|
1097
|
+
}
|
|
1098
|
+
async updateWidgetConfig(organizationId, config) {
|
|
1099
|
+
return this.makeRequest('PATCH', `/organizations/${organizationId}/chat-widget-config`, { body: config });
|
|
1100
|
+
}
|
|
1101
|
+
async getAgentWidgetConfig(agentId) {
|
|
1102
|
+
return this.makeRequest('GET', `/chat-widget/${agentId}/config`);
|
|
1103
|
+
}
|
|
1104
|
+
// ==================== TEST METHODS ====================
|
|
1105
|
+
async createTestCase(agentId, testData) {
|
|
1106
|
+
return this.makeRequest('POST', `/agents/${agentId}/tests`, { body: testData });
|
|
1107
|
+
}
|
|
1108
|
+
async listTestCases(agentId) {
|
|
1109
|
+
return this.makeRequest('GET', `/agents/${agentId}/tests`);
|
|
1110
|
+
}
|
|
1111
|
+
async getTestCase(agentId, testCaseId) {
|
|
1112
|
+
return this.makeRequest('GET', `/agents/${agentId}/tests/${testCaseId}`);
|
|
1113
|
+
}
|
|
1114
|
+
async updateTestCase(agentId, testCaseId, testData) {
|
|
1115
|
+
return this.makeRequest('PATCH', `/agents/${agentId}/tests/${testCaseId}`, { body: testData });
|
|
1116
|
+
}
|
|
1117
|
+
async deleteTestCase(agentId, testCaseId) {
|
|
1118
|
+
return this.makeRequest('DELETE', `/agents/${agentId}/tests/${testCaseId}`);
|
|
1119
|
+
}
|
|
1120
|
+
async listTestRuns(agentId, params = {}) {
|
|
1121
|
+
return this.makeRequest('GET', `/agents/${agentId}/tests/runs`, { params });
|
|
1122
|
+
}
|
|
1123
|
+
async getTestRun(agentId, runId) {
|
|
1124
|
+
return this.makeRequest('GET', `/agents/${agentId}/tests/runs/${runId}`);
|
|
1125
|
+
}
|
|
1126
|
+
async runTest(agentId, testCaseId) {
|
|
1127
|
+
return this.makeRequest('POST', `/agents/${agentId}/tests/${testCaseId}/run`);
|
|
1128
|
+
}
|
|
1129
|
+
async runAllTests(agentId) {
|
|
1130
|
+
return this.makeRequest('POST', `/agents/${agentId}/tests/run`);
|
|
1131
|
+
}
|
|
1132
|
+
// ==================== STATISTICS METHODS ====================
|
|
1133
|
+
async getStatistic(endpoint, params = {}) {
|
|
1134
|
+
return this.makeRequest('GET', `/statistics/${endpoint}`, { params });
|
|
1135
|
+
}
|
|
1136
|
+
// ==================== CALENDAR METHODS ====================
|
|
1137
|
+
async getCalendarAuthUrl(params) {
|
|
1138
|
+
return this.makeRequest('GET', '/calendar/auth/connect', { params });
|
|
1139
|
+
}
|
|
1140
|
+
async disconnectCalendar(connectionId) {
|
|
1141
|
+
return this.makeRequest('POST', `/calendar/auth/disconnect/${connectionId}`);
|
|
1142
|
+
}
|
|
1143
|
+
async listCalendarConnections(params = {}) {
|
|
1144
|
+
return this.makeRequest('GET', '/calendar/connections', { params });
|
|
1145
|
+
}
|
|
1146
|
+
async getCalendarConnection(connectionId) {
|
|
1147
|
+
return this.makeRequest('GET', `/calendar/connections/${connectionId}`);
|
|
1148
|
+
}
|
|
1149
|
+
async updateCalendarConnection(connectionId, data) {
|
|
1150
|
+
return this.makeRequest('PATCH', `/calendar/connections/${connectionId}`, { body: data });
|
|
1151
|
+
}
|
|
1152
|
+
async listCalendarConnectionCalendars(connectionId) {
|
|
1153
|
+
return this.makeRequest('GET', `/calendar/connections/${connectionId}/calendars`);
|
|
1154
|
+
}
|
|
1155
|
+
async listAvailableCalendarConnections() {
|
|
1156
|
+
return this.makeRequest('GET', '/calendar/connections/available');
|
|
1157
|
+
}
|
|
1158
|
+
async listBookingTypes() {
|
|
1159
|
+
return this.makeRequest('GET', '/calendar/booking-types');
|
|
1160
|
+
}
|
|
1161
|
+
async createBookingType(data) {
|
|
1162
|
+
return this.makeRequest('POST', '/calendar/booking-types', { body: data });
|
|
1163
|
+
}
|
|
1164
|
+
async getBookingType(bookingTypeId) {
|
|
1165
|
+
return this.makeRequest('GET', `/calendar/booking-types/${bookingTypeId}`);
|
|
1166
|
+
}
|
|
1167
|
+
async updateBookingType(bookingTypeId, data) {
|
|
1168
|
+
return this.makeRequest('PATCH', `/calendar/booking-types/${bookingTypeId}`, { body: data });
|
|
1169
|
+
}
|
|
1170
|
+
async deleteBookingType(bookingTypeId) {
|
|
1171
|
+
return this.makeRequest('DELETE', `/calendar/booking-types/${bookingTypeId}`);
|
|
1172
|
+
}
|
|
1173
|
+
async addBookingTypeMember(bookingTypeId, data) {
|
|
1174
|
+
return this.makeRequest('POST', `/calendar/booking-types/${bookingTypeId}/members`, { body: data });
|
|
1175
|
+
}
|
|
1176
|
+
async removeBookingTypeMember(bookingTypeId, memberId) {
|
|
1177
|
+
return this.makeRequest('DELETE', `/calendar/booking-types/${bookingTypeId}/members/${memberId}`);
|
|
1178
|
+
}
|
|
1179
|
+
async listAppointments(params = {}) {
|
|
1180
|
+
return this.makeRequest('GET', '/calendar/appointments', { params });
|
|
1181
|
+
}
|
|
1182
|
+
async cancelAppointment(appointmentId) {
|
|
1183
|
+
return this.makeRequest('POST', `/calendar/appointments/${appointmentId}/cancel`);
|
|
1184
|
+
}
|
|
1185
|
+
// ==================== CAMPAIGN METHODS ====================
|
|
1186
|
+
async listCampaigns(params = {}) {
|
|
1187
|
+
if (params.offset !== undefined) {
|
|
1188
|
+
params.skip = params.offset;
|
|
1189
|
+
delete params.offset;
|
|
1190
|
+
}
|
|
1191
|
+
return this.makeRequest('GET', '/campaigns/', { params });
|
|
1192
|
+
}
|
|
1193
|
+
async getCampaign(campaignId) {
|
|
1194
|
+
return this.makeRequest('GET', `/campaigns/${campaignId}`);
|
|
1195
|
+
}
|
|
1196
|
+
async createCampaign(campaignData, targetUserId) {
|
|
1197
|
+
const params = {};
|
|
1198
|
+
if (targetUserId)
|
|
1199
|
+
params.target_user_id = targetUserId;
|
|
1200
|
+
return this.makeRequest('POST', '/campaigns/', { body: campaignData, params });
|
|
1201
|
+
}
|
|
1202
|
+
async updateCampaign(campaignId, campaignData, targetUserId) {
|
|
1203
|
+
const params = {};
|
|
1204
|
+
if (targetUserId)
|
|
1205
|
+
params.target_user_id = targetUserId;
|
|
1206
|
+
return this.makeRequest('PATCH', `/campaigns/${campaignId}`, { body: campaignData, params });
|
|
1207
|
+
}
|
|
1208
|
+
async deleteCampaign(campaignId) {
|
|
1209
|
+
return this.makeRequest('DELETE', `/campaigns/${campaignId}`);
|
|
1210
|
+
}
|
|
1211
|
+
async startCampaign(campaignId) {
|
|
1212
|
+
return this.makeRequest('POST', `/campaigns/${campaignId}/start`);
|
|
1213
|
+
}
|
|
1214
|
+
async pauseCampaign(campaignId) {
|
|
1215
|
+
return this.makeRequest('POST', `/campaigns/${campaignId}/pause`);
|
|
1216
|
+
}
|
|
1217
|
+
async resumeCampaign(campaignId) {
|
|
1218
|
+
return this.makeRequest('POST', `/campaigns/${campaignId}/resume`);
|
|
1219
|
+
}
|
|
1220
|
+
async cancelCampaign(campaignId) {
|
|
1221
|
+
return this.makeRequest('POST', `/campaigns/${campaignId}/cancel`);
|
|
1222
|
+
}
|
|
1223
|
+
async getCampaignStats(campaignId) {
|
|
1224
|
+
return this.makeRequest('GET', `/campaigns/${campaignId}/stats`);
|
|
1225
|
+
}
|
|
1226
|
+
async addCampaignContacts(campaignId, contactIds) {
|
|
1227
|
+
return this.makeRequest('POST', `/campaigns/${campaignId}/contacts`, { body: { contact_ids: contactIds } });
|
|
1228
|
+
}
|
|
1229
|
+
async getCampaignContacts(campaignId, params = {}) {
|
|
1230
|
+
if (params.offset !== undefined) {
|
|
1231
|
+
params.skip = params.offset;
|
|
1232
|
+
delete params.offset;
|
|
1233
|
+
}
|
|
1234
|
+
return this.makeRequest('GET', `/campaigns/${campaignId}/contacts`, { params });
|
|
1235
|
+
}
|
|
1236
|
+
async removeCampaignContact(campaignId, contactId) {
|
|
1237
|
+
return this.makeRequest('DELETE', `/campaigns/${campaignId}/contacts/${contactId}`);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
//# sourceMappingURL=dalvon.js.map
|