@sinch/functions-runtime 0.1.0-beta.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +207 -0
- package/dist/bin/sinch-runtime.js +812 -0
- package/dist/bin/sinch-runtime.js.map +1 -0
- package/dist/index.d.ts +1359 -0
- package/dist/index.js +1946 -0
- package/dist/index.js.map +1 -0
- package/package.json +80 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1359 @@
|
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
import { ConversationService } from '@sinch/conversation';
|
|
4
|
+
import { NumbersService } from '@sinch/numbers';
|
|
5
|
+
import { SmsService } from '@sinch/sms';
|
|
6
|
+
import { Voice, VoiceService } from '@sinch/voice';
|
|
7
|
+
import { Express as Express$1, NextFunction, Request as Request$1, Response as Response$1 } from 'express';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* SVAML (Sinch Voice Application Markup Language) types
|
|
11
|
+
*
|
|
12
|
+
* These are internal types used by the builders. Users should use the builders
|
|
13
|
+
* (createIceBuilder, createAceBuilder, createPieBuilder, createMenu) rather
|
|
14
|
+
* than constructing SVAML responses directly.
|
|
15
|
+
*
|
|
16
|
+
* For SDK types, import directly from '@sinch/voice':
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import type { Voice } from '@sinch/voice';
|
|
19
|
+
* // Use Voice.IceResponse, Voice.SvamlAction, etc.
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/** Text-to-speech instruction */
|
|
23
|
+
export interface SayInstruction {
|
|
24
|
+
name: "say";
|
|
25
|
+
text: string;
|
|
26
|
+
locale?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Play single audio file instruction */
|
|
29
|
+
export interface PlayInstruction {
|
|
30
|
+
name: "play";
|
|
31
|
+
url: string;
|
|
32
|
+
}
|
|
33
|
+
/** Play multiple audio files instruction */
|
|
34
|
+
export interface PlayFilesInstruction {
|
|
35
|
+
name: "playFiles";
|
|
36
|
+
ids: string[];
|
|
37
|
+
locale?: string;
|
|
38
|
+
}
|
|
39
|
+
/** Start call recording instruction */
|
|
40
|
+
export interface StartRecordingInstruction {
|
|
41
|
+
name: "startRecording";
|
|
42
|
+
options?: {
|
|
43
|
+
destinationUrl?: string;
|
|
44
|
+
credentials?: string;
|
|
45
|
+
format?: string;
|
|
46
|
+
notificationEvents?: boolean;
|
|
47
|
+
transcriptionEnabled?: boolean;
|
|
48
|
+
transcriptionLocale?: string;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Stop call recording instruction */
|
|
52
|
+
export interface StopRecordingInstruction {
|
|
53
|
+
name: "stopRecording";
|
|
54
|
+
}
|
|
55
|
+
/** Set cookie instruction (persists data across callbacks) */
|
|
56
|
+
export interface SetCookieInstruction {
|
|
57
|
+
name: "setCookie";
|
|
58
|
+
key: string;
|
|
59
|
+
value: string;
|
|
60
|
+
}
|
|
61
|
+
/** Answer the call instruction */
|
|
62
|
+
export interface AnswerInstruction {
|
|
63
|
+
name: "answer";
|
|
64
|
+
}
|
|
65
|
+
/** Send DTMF tones instruction */
|
|
66
|
+
export interface SendDtmfInstruction {
|
|
67
|
+
name: "sendDtmf";
|
|
68
|
+
value: string;
|
|
69
|
+
}
|
|
70
|
+
/** Union type for all SVAML instructions */
|
|
71
|
+
export type SvamletInstruction = SayInstruction | PlayInstruction | PlayFilesInstruction | StartRecordingInstruction | StopRecordingInstruction | SetCookieInstruction | AnswerInstruction | SendDtmfInstruction;
|
|
72
|
+
/** Base action with name */
|
|
73
|
+
export interface BaseAction {
|
|
74
|
+
name: string;
|
|
75
|
+
}
|
|
76
|
+
/** Hangup action */
|
|
77
|
+
export interface HangupAction extends BaseAction {
|
|
78
|
+
name: "hangup";
|
|
79
|
+
}
|
|
80
|
+
/** Continue action */
|
|
81
|
+
export interface ContinueAction extends BaseAction {
|
|
82
|
+
name: "continue";
|
|
83
|
+
}
|
|
84
|
+
/** Connect to PSTN action */
|
|
85
|
+
export interface ConnectPstnAction extends BaseAction {
|
|
86
|
+
name: "connectPstn";
|
|
87
|
+
number: string;
|
|
88
|
+
cli?: string;
|
|
89
|
+
maxDuration?: number;
|
|
90
|
+
timeout?: number;
|
|
91
|
+
enableAce?: boolean;
|
|
92
|
+
enableDice?: boolean;
|
|
93
|
+
enablePie?: boolean;
|
|
94
|
+
dtmf?: string;
|
|
95
|
+
custom?: string;
|
|
96
|
+
indications?: string;
|
|
97
|
+
amd?: {
|
|
98
|
+
enabled: boolean;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** Connect to SIP action */
|
|
102
|
+
export interface ConnectSipAction extends BaseAction {
|
|
103
|
+
name: "connectSip";
|
|
104
|
+
destination: string;
|
|
105
|
+
cli?: string;
|
|
106
|
+
headers?: Record<string, string>;
|
|
107
|
+
custom?: string;
|
|
108
|
+
}
|
|
109
|
+
/** Connect to MXP (Sinch SDK) action */
|
|
110
|
+
export interface ConnectMxpAction extends BaseAction {
|
|
111
|
+
name: "connectMxp";
|
|
112
|
+
destination: string;
|
|
113
|
+
cli?: string;
|
|
114
|
+
custom?: string;
|
|
115
|
+
}
|
|
116
|
+
/** Connect to conference action */
|
|
117
|
+
export interface ConnectConfAction extends BaseAction {
|
|
118
|
+
name: "connectConf";
|
|
119
|
+
conferenceId: string;
|
|
120
|
+
moh?: string;
|
|
121
|
+
enableDice?: boolean;
|
|
122
|
+
custom?: string;
|
|
123
|
+
}
|
|
124
|
+
/** Park (hold) action */
|
|
125
|
+
export interface ParkAction extends BaseAction {
|
|
126
|
+
name: "park";
|
|
127
|
+
holdPrompt?: string;
|
|
128
|
+
maxDuration?: number;
|
|
129
|
+
custom?: string;
|
|
130
|
+
}
|
|
131
|
+
/** Run IVR menu action */
|
|
132
|
+
export interface RunMenuAction extends BaseAction {
|
|
133
|
+
name: "runMenu";
|
|
134
|
+
menus: Menu[];
|
|
135
|
+
barge?: boolean;
|
|
136
|
+
enableDice?: boolean;
|
|
137
|
+
custom?: string;
|
|
138
|
+
}
|
|
139
|
+
/** Union type for all SVAML actions */
|
|
140
|
+
export type SvamletAction = HangupAction | ContinueAction | ConnectPstnAction | ConnectSipAction | ConnectMxpAction | ConnectConfAction | ParkAction | RunMenuAction;
|
|
141
|
+
/** Menu option definition */
|
|
142
|
+
export interface MenuOption {
|
|
143
|
+
dtmf: string;
|
|
144
|
+
action: string;
|
|
145
|
+
}
|
|
146
|
+
/** Menu definition */
|
|
147
|
+
export interface Menu {
|
|
148
|
+
id: string;
|
|
149
|
+
mainPrompt: string;
|
|
150
|
+
repeatPrompt?: string;
|
|
151
|
+
options: MenuOption[];
|
|
152
|
+
repeats?: number;
|
|
153
|
+
maxDigits?: number;
|
|
154
|
+
timeoutMills?: number;
|
|
155
|
+
locale?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Complete SVAML response structure
|
|
159
|
+
*
|
|
160
|
+
* Every voice callback must return a SvamletResponse (or null for DICE).
|
|
161
|
+
*/
|
|
162
|
+
export interface SvamletResponse {
|
|
163
|
+
/** Instructions to execute before the action */
|
|
164
|
+
instructions?: SvamletInstruction[];
|
|
165
|
+
/** Action to take after instructions complete */
|
|
166
|
+
action: SvamletAction;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Valid DTMF keys for menu options
|
|
170
|
+
*/
|
|
171
|
+
export type DtmfKey = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "*" | "#";
|
|
172
|
+
/**
|
|
173
|
+
* Menu action types
|
|
174
|
+
* - 'return' - Return to PIE callback with DTMF value
|
|
175
|
+
* - 'return(value)' - Return to PIE callback with custom value
|
|
176
|
+
* - 'menu(menuId)' - Navigate to submenu
|
|
177
|
+
*/
|
|
178
|
+
export type MenuAction = "return" | `return(${string})` | `menu(${string})`;
|
|
179
|
+
/**
|
|
180
|
+
* Complete menu structure for runMenu action
|
|
181
|
+
*/
|
|
182
|
+
export interface MenuStructure {
|
|
183
|
+
/** Enable barge-in (interrupt prompts with input) */
|
|
184
|
+
barge: boolean;
|
|
185
|
+
/** Array of menu definitions */
|
|
186
|
+
menus: Menu[];
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Language option for language selection menu template
|
|
190
|
+
*/
|
|
191
|
+
export interface LanguageOption {
|
|
192
|
+
/** DTMF key to press */
|
|
193
|
+
dtmf: DtmfKey;
|
|
194
|
+
/** Display name of the language */
|
|
195
|
+
name: string;
|
|
196
|
+
/** Locale code to return (e.g., 'en-US') */
|
|
197
|
+
value: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Simple menu option for quick menu creation
|
|
201
|
+
*/
|
|
202
|
+
export interface SimpleMenuOption {
|
|
203
|
+
/** DTMF key */
|
|
204
|
+
dtmf: string;
|
|
205
|
+
/** Menu action */
|
|
206
|
+
action: string;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Menu builder for creating voice IVR menus with validation
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* // Simple menu
|
|
214
|
+
* const menu = new MenuBuilder()
|
|
215
|
+
* .prompt('Press 1 for sales, 2 for support')
|
|
216
|
+
* .option('1', 'return(sales)')
|
|
217
|
+
* .option('2', 'return(support)')
|
|
218
|
+
* .build();
|
|
219
|
+
*
|
|
220
|
+
* // Multi-level menu with submenus
|
|
221
|
+
* const menu = new MenuBuilder()
|
|
222
|
+
* .prompt('Press 1 for English, 2 for Spanish')
|
|
223
|
+
* .option('1', 'menu(english)')
|
|
224
|
+
* .option('2', 'menu(spanish)')
|
|
225
|
+
* .addSubmenu('english')
|
|
226
|
+
* .prompt('Press 1 for sales, 2 for support')
|
|
227
|
+
* .option('1', 'return(en-sales)')
|
|
228
|
+
* .option('2', 'return(en-support)')
|
|
229
|
+
* .build();
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export declare class MenuBuilder {
|
|
233
|
+
private menuStructure;
|
|
234
|
+
private currentMenu;
|
|
235
|
+
/**
|
|
236
|
+
* Create a new MenuBuilder
|
|
237
|
+
*
|
|
238
|
+
* @param id - Menu ID (must be 'main' for root menu)
|
|
239
|
+
* @throws Error if id is not 'main' for root menu
|
|
240
|
+
*/
|
|
241
|
+
constructor(id?: string);
|
|
242
|
+
/**
|
|
243
|
+
* Set the main prompt for the menu
|
|
244
|
+
*
|
|
245
|
+
* @param text - The prompt text (will be wrapped in TTS tags)
|
|
246
|
+
* @param locale - Voice locale (default: 'en-US')
|
|
247
|
+
*/
|
|
248
|
+
prompt(text: string, locale?: string): this;
|
|
249
|
+
/**
|
|
250
|
+
* Set the repeat prompt (played when user doesn't respond)
|
|
251
|
+
*
|
|
252
|
+
* @param text - The repeat prompt text
|
|
253
|
+
*/
|
|
254
|
+
repeatPrompt(text: string): this;
|
|
255
|
+
/**
|
|
256
|
+
* Add a menu option
|
|
257
|
+
*
|
|
258
|
+
* @param dtmf - The DTMF key (0-9, *, #)
|
|
259
|
+
* @param action - Action: 'return', 'return(value)', or 'menu(menuid)'
|
|
260
|
+
* @throws Error if DTMF key or action is invalid
|
|
261
|
+
*/
|
|
262
|
+
option(dtmf: string, action?: string): this;
|
|
263
|
+
/**
|
|
264
|
+
* Set maximum number of digits to collect
|
|
265
|
+
*
|
|
266
|
+
* @param digits - Maximum digits (1-20)
|
|
267
|
+
* @throws Error if digits is out of range
|
|
268
|
+
*/
|
|
269
|
+
maxDigits(digits: number): this;
|
|
270
|
+
/**
|
|
271
|
+
* Set timeout in milliseconds
|
|
272
|
+
*
|
|
273
|
+
* @param ms - Timeout in milliseconds (1000-30000)
|
|
274
|
+
* @throws Error if timeout is out of range
|
|
275
|
+
*/
|
|
276
|
+
timeout(ms: number): this;
|
|
277
|
+
/**
|
|
278
|
+
* Set number of times to repeat the menu
|
|
279
|
+
*
|
|
280
|
+
* @param count - Number of repeats (0-5)
|
|
281
|
+
* @throws Error if count is out of range
|
|
282
|
+
*/
|
|
283
|
+
repeats(count: number): this;
|
|
284
|
+
/**
|
|
285
|
+
* Enable/disable barge-in (allow interrupting prompts with input)
|
|
286
|
+
*
|
|
287
|
+
* @param enabled - Whether to allow barge-in (default: true)
|
|
288
|
+
*/
|
|
289
|
+
barge(enabled?: boolean): this;
|
|
290
|
+
/**
|
|
291
|
+
* Add the current menu and start a new submenu
|
|
292
|
+
*
|
|
293
|
+
* @param id - Menu ID for the submenu
|
|
294
|
+
* @throws Error if submenu ID is invalid
|
|
295
|
+
*/
|
|
296
|
+
addSubmenu(id: string): this;
|
|
297
|
+
/**
|
|
298
|
+
* Build and return the complete menu structure
|
|
299
|
+
*
|
|
300
|
+
* @throws Error if menu structure is invalid
|
|
301
|
+
*/
|
|
302
|
+
build(): MenuStructure;
|
|
303
|
+
/**
|
|
304
|
+
* Get just the menus array (for use with runMenu action)
|
|
305
|
+
*/
|
|
306
|
+
buildMenus(): Menu[];
|
|
307
|
+
/**
|
|
308
|
+
* Validate DTMF key format
|
|
309
|
+
*/
|
|
310
|
+
private isValidDtmf;
|
|
311
|
+
/**
|
|
312
|
+
* Validate action format
|
|
313
|
+
*/
|
|
314
|
+
private isValidAction;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Create a new MenuBuilder
|
|
318
|
+
*
|
|
319
|
+
* @param id - Menu ID (defaults to 'main')
|
|
320
|
+
*/
|
|
321
|
+
export declare function createMenu(id?: string): MenuBuilder;
|
|
322
|
+
/**
|
|
323
|
+
* Create a simple menu quickly
|
|
324
|
+
*
|
|
325
|
+
* @param prompt - Main prompt text
|
|
326
|
+
* @param options - Array of menu options
|
|
327
|
+
*/
|
|
328
|
+
export declare function createSimpleMenu(prompt: string, options?: SimpleMenuOption[]): MenuStructure;
|
|
329
|
+
/**
|
|
330
|
+
* Pre-built menu templates for common use cases
|
|
331
|
+
*/
|
|
332
|
+
export declare const MenuTemplates: {
|
|
333
|
+
/**
|
|
334
|
+
* Standard business menu (Sales, Support, Operator)
|
|
335
|
+
*
|
|
336
|
+
* @param companyName - Company name for greeting
|
|
337
|
+
*/
|
|
338
|
+
readonly business: (companyName?: string) => MenuStructure;
|
|
339
|
+
/**
|
|
340
|
+
* Yes/No confirmation menu
|
|
341
|
+
*
|
|
342
|
+
* @param question - Question to ask
|
|
343
|
+
*/
|
|
344
|
+
readonly yesNo: (question?: string) => MenuStructure;
|
|
345
|
+
/**
|
|
346
|
+
* Language selection menu
|
|
347
|
+
*
|
|
348
|
+
* @param languages - Language options
|
|
349
|
+
*/
|
|
350
|
+
readonly language: (languages?: LanguageOption[]) => MenuStructure;
|
|
351
|
+
/**
|
|
352
|
+
* After hours menu
|
|
353
|
+
*
|
|
354
|
+
* @param companyName - Company name
|
|
355
|
+
* @param businessHours - Business hours text
|
|
356
|
+
*/
|
|
357
|
+
readonly afterHours: (companyName?: string, businessHours?: string) => MenuStructure;
|
|
358
|
+
/**
|
|
359
|
+
* Recording consent menu
|
|
360
|
+
*/
|
|
361
|
+
readonly recordingConsent: () => MenuStructure;
|
|
362
|
+
/**
|
|
363
|
+
* Numeric input menu (for collecting multi-digit input like account numbers)
|
|
364
|
+
*
|
|
365
|
+
* @param prompt - Instructions for user
|
|
366
|
+
* @param digits - Number of digits to collect (default: 4)
|
|
367
|
+
*/
|
|
368
|
+
readonly numericInput: (prompt: string, digits?: number) => MenuStructure;
|
|
369
|
+
};
|
|
370
|
+
export interface RecordingOptions {
|
|
371
|
+
/** URL to send the recording to */
|
|
372
|
+
destinationUrl?: string;
|
|
373
|
+
/** Credentials for the destination */
|
|
374
|
+
credentials?: string;
|
|
375
|
+
/** Recording format */
|
|
376
|
+
format?: "mp3" | "wav";
|
|
377
|
+
/** Enable notification events */
|
|
378
|
+
notificationEvents?: boolean;
|
|
379
|
+
/** Enable transcription */
|
|
380
|
+
transcriptionEnabled?: boolean;
|
|
381
|
+
/** Transcription locale */
|
|
382
|
+
transcriptionLocale?: string;
|
|
383
|
+
}
|
|
384
|
+
export interface ConnectPstnOptions {
|
|
385
|
+
/** CLI (Caller ID) to display */
|
|
386
|
+
cli?: string;
|
|
387
|
+
/** Maximum duration in seconds */
|
|
388
|
+
maxDuration?: number;
|
|
389
|
+
/** Timeout in seconds */
|
|
390
|
+
timeout?: number;
|
|
391
|
+
/** Enable ACE callback */
|
|
392
|
+
enableAce?: boolean;
|
|
393
|
+
/** Enable DICE callback */
|
|
394
|
+
enableDice?: boolean;
|
|
395
|
+
/** Enable PIE callback */
|
|
396
|
+
enablePie?: boolean;
|
|
397
|
+
/** DTMF to send on connect */
|
|
398
|
+
dtmf?: string;
|
|
399
|
+
/** Custom data to pass to callbacks */
|
|
400
|
+
custom?: string;
|
|
401
|
+
/** Dial tone indications */
|
|
402
|
+
indications?: "se" | "us" | "no" | "fi" | "uk" | "de" | "fr";
|
|
403
|
+
/** Enable AMD (Answering Machine Detection) */
|
|
404
|
+
amd?: {
|
|
405
|
+
enabled: boolean;
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
export interface ConnectSipOptions {
|
|
409
|
+
/** CLI (Caller ID) to display */
|
|
410
|
+
cli?: string;
|
|
411
|
+
/** Custom SIP headers */
|
|
412
|
+
headers?: Record<string, string>;
|
|
413
|
+
/** Custom data to pass to callbacks */
|
|
414
|
+
custom?: string;
|
|
415
|
+
}
|
|
416
|
+
export interface ConnectMxpOptions {
|
|
417
|
+
/** CLI (Caller ID) to display */
|
|
418
|
+
cli?: string;
|
|
419
|
+
/** Custom data to pass to callbacks */
|
|
420
|
+
custom?: string;
|
|
421
|
+
}
|
|
422
|
+
export interface ConnectConfOptions {
|
|
423
|
+
/** Music on hold */
|
|
424
|
+
moh?: "ring" | "music";
|
|
425
|
+
/** Enable DICE callback */
|
|
426
|
+
enableDice?: boolean;
|
|
427
|
+
/** Custom data to pass to callbacks */
|
|
428
|
+
custom?: string;
|
|
429
|
+
}
|
|
430
|
+
export interface ParkOptions {
|
|
431
|
+
/** Maximum park duration in seconds */
|
|
432
|
+
maxDuration?: number;
|
|
433
|
+
/** Custom data to pass to callbacks */
|
|
434
|
+
custom?: string;
|
|
435
|
+
}
|
|
436
|
+
export interface RunMenuOptions {
|
|
437
|
+
/** Allow user to interrupt prompts */
|
|
438
|
+
barge?: boolean;
|
|
439
|
+
/** Enable DICE callback */
|
|
440
|
+
enableDice?: boolean;
|
|
441
|
+
/** Custom data to pass to callbacks */
|
|
442
|
+
custom?: string;
|
|
443
|
+
}
|
|
444
|
+
declare abstract class BaseSvamlBuilder<T extends BaseSvamlBuilder<T>> {
|
|
445
|
+
protected instructions: SvamletInstruction[];
|
|
446
|
+
protected action: SvamletAction | null;
|
|
447
|
+
/**
|
|
448
|
+
* Add a text-to-speech instruction
|
|
449
|
+
*
|
|
450
|
+
* @param text - Text to speak
|
|
451
|
+
* @param locale - Voice locale (e.g., 'en-US')
|
|
452
|
+
*/
|
|
453
|
+
say(text: string, locale?: string): T;
|
|
454
|
+
/**
|
|
455
|
+
* Play an audio file
|
|
456
|
+
*
|
|
457
|
+
* @param url - URL of the audio file to play
|
|
458
|
+
*/
|
|
459
|
+
play(url: string): T;
|
|
460
|
+
/**
|
|
461
|
+
* Play multiple audio files
|
|
462
|
+
*
|
|
463
|
+
* @param urls - Array of audio file URLs
|
|
464
|
+
* @param locale - Locale for any TTS prompts
|
|
465
|
+
*/
|
|
466
|
+
playFiles(urls: string[], locale?: string): T;
|
|
467
|
+
/**
|
|
468
|
+
* Start recording the call
|
|
469
|
+
*
|
|
470
|
+
* @param options - Recording options
|
|
471
|
+
*/
|
|
472
|
+
startRecording(options?: RecordingOptions): T;
|
|
473
|
+
/**
|
|
474
|
+
* Stop recording the call
|
|
475
|
+
*/
|
|
476
|
+
stopRecording(): T;
|
|
477
|
+
/**
|
|
478
|
+
* Set a cookie (persists data across callbacks)
|
|
479
|
+
*
|
|
480
|
+
* @param key - Cookie key
|
|
481
|
+
* @param value - Cookie value
|
|
482
|
+
*/
|
|
483
|
+
setCookie(key: string, value: string): T;
|
|
484
|
+
/**
|
|
485
|
+
* Send DTMF tones
|
|
486
|
+
*
|
|
487
|
+
* @param digits - DTMF digits to send
|
|
488
|
+
*/
|
|
489
|
+
sendDtmf(digits: string): T;
|
|
490
|
+
/**
|
|
491
|
+
* Hang up the call
|
|
492
|
+
*/
|
|
493
|
+
hangup(): T;
|
|
494
|
+
/**
|
|
495
|
+
* Continue to next callback
|
|
496
|
+
*/
|
|
497
|
+
continue(): T;
|
|
498
|
+
/**
|
|
499
|
+
* Build the final SVAML response
|
|
500
|
+
*
|
|
501
|
+
* @throws Error if no action has been set
|
|
502
|
+
*/
|
|
503
|
+
build(): SvamletResponse;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* ICE (Incoming Call Event) SVAML Builder
|
|
507
|
+
*
|
|
508
|
+
* Use this to build responses for incoming call events.
|
|
509
|
+
*
|
|
510
|
+
* @example
|
|
511
|
+
* ```typescript
|
|
512
|
+
* export async function ice(context, event) {
|
|
513
|
+
* return new IceSvamlBuilder()
|
|
514
|
+
* .say('Welcome! Connecting you now.')
|
|
515
|
+
* .connectPstn('+15551234567')
|
|
516
|
+
* .build();
|
|
517
|
+
* }
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
export declare class IceSvamlBuilder extends BaseSvamlBuilder<IceSvamlBuilder> {
|
|
521
|
+
/**
|
|
522
|
+
* Answer the call explicitly
|
|
523
|
+
*/
|
|
524
|
+
answer(): this;
|
|
525
|
+
/**
|
|
526
|
+
* Connect to a PSTN phone number
|
|
527
|
+
*
|
|
528
|
+
* @param number - E.164 formatted phone number (e.g., '+15551234567')
|
|
529
|
+
* @param options - Connection options
|
|
530
|
+
*/
|
|
531
|
+
connectPstn(number: string, options?: ConnectPstnOptions): this;
|
|
532
|
+
/**
|
|
533
|
+
* Connect to a SIP endpoint
|
|
534
|
+
*
|
|
535
|
+
* @param destination - SIP URI
|
|
536
|
+
* @param options - Connection options
|
|
537
|
+
*/
|
|
538
|
+
connectSip(destination: string, options?: ConnectSipOptions): this;
|
|
539
|
+
/**
|
|
540
|
+
* Connect to an MXP (Sinch SDK) user
|
|
541
|
+
*
|
|
542
|
+
* @param destination - MXP user identifier
|
|
543
|
+
* @param options - Connection options
|
|
544
|
+
*/
|
|
545
|
+
connectMxp(destination: string, options?: ConnectMxpOptions): this;
|
|
546
|
+
/**
|
|
547
|
+
* Join a conference
|
|
548
|
+
*
|
|
549
|
+
* @param conferenceId - Conference ID to join
|
|
550
|
+
* @param options - Conference options
|
|
551
|
+
*/
|
|
552
|
+
connectConf(conferenceId: string, options?: ConnectConfOptions): this;
|
|
553
|
+
/**
|
|
554
|
+
* Run an IVR menu
|
|
555
|
+
*
|
|
556
|
+
* @param menus - Array of menu definitions or MenuStructure from createMenu().build()
|
|
557
|
+
* @param options - Menu options
|
|
558
|
+
*/
|
|
559
|
+
runMenu(menus: Menu[] | MenuStructure, options?: RunMenuOptions): this;
|
|
560
|
+
/**
|
|
561
|
+
* Park the call (put on hold)
|
|
562
|
+
*
|
|
563
|
+
* @param holdPrompt - Prompt to play while on hold
|
|
564
|
+
* @param options - Park options
|
|
565
|
+
*/
|
|
566
|
+
park(holdPrompt?: string, options?: ParkOptions): this;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* ACE (Answered Call Event) SVAML Builder
|
|
570
|
+
*
|
|
571
|
+
* Use this to build responses for answered call events (outbound calls).
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```typescript
|
|
575
|
+
* export async function ace(context, event) {
|
|
576
|
+
* if (event.amd?.status === 'machine') {
|
|
577
|
+
* return new AceSvamlBuilder().hangup().build();
|
|
578
|
+
* }
|
|
579
|
+
* return new AceSvamlBuilder()
|
|
580
|
+
* .say('Hello! This is a call from Acme Corp.')
|
|
581
|
+
* .continue()
|
|
582
|
+
* .build();
|
|
583
|
+
* }
|
|
584
|
+
* ```
|
|
585
|
+
*/
|
|
586
|
+
export declare class AceSvamlBuilder extends BaseSvamlBuilder<AceSvamlBuilder> {
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* PIE (Prompt Input Event) SVAML Builder
|
|
590
|
+
*
|
|
591
|
+
* Use this to build responses for user input events (DTMF/voice).
|
|
592
|
+
*
|
|
593
|
+
* @example
|
|
594
|
+
* ```typescript
|
|
595
|
+
* export async function pie(context, event) {
|
|
596
|
+
* const selection = event.menuResult?.value;
|
|
597
|
+
*
|
|
598
|
+
* if (selection === '1') {
|
|
599
|
+
* return new PieSvamlBuilder()
|
|
600
|
+
* .say('Connecting you to sales.')
|
|
601
|
+
* .connectPstn('+15551234567')
|
|
602
|
+
* .build();
|
|
603
|
+
* }
|
|
604
|
+
*
|
|
605
|
+
* return new PieSvamlBuilder()
|
|
606
|
+
* .say('Goodbye!')
|
|
607
|
+
* .hangup()
|
|
608
|
+
* .build();
|
|
609
|
+
* }
|
|
610
|
+
* ```
|
|
611
|
+
*/
|
|
612
|
+
export declare class PieSvamlBuilder extends BaseSvamlBuilder<PieSvamlBuilder> {
|
|
613
|
+
/**
|
|
614
|
+
* Connect to a PSTN phone number
|
|
615
|
+
*
|
|
616
|
+
* @param number - E.164 formatted phone number
|
|
617
|
+
* @param options - Connection options
|
|
618
|
+
*/
|
|
619
|
+
connectPstn(number: string, options?: ConnectPstnOptions): this;
|
|
620
|
+
/**
|
|
621
|
+
* Run an IVR menu
|
|
622
|
+
*
|
|
623
|
+
* @param menus - Array of menu definitions or MenuStructure from createMenu().build()
|
|
624
|
+
* @param options - Menu options
|
|
625
|
+
*/
|
|
626
|
+
runMenu(menus: Menu[] | MenuStructure, options?: RunMenuOptions): this;
|
|
627
|
+
/**
|
|
628
|
+
* Park the call (put on hold)
|
|
629
|
+
*
|
|
630
|
+
* @param holdPrompt - Prompt to play while on hold
|
|
631
|
+
* @param options - Park options
|
|
632
|
+
*/
|
|
633
|
+
park(holdPrompt?: string, options?: ParkOptions): this;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Create a new ICE SVAML builder
|
|
637
|
+
*/
|
|
638
|
+
export declare function createIceBuilder(): IceSvamlBuilder;
|
|
639
|
+
/**
|
|
640
|
+
* Create a new ACE SVAML builder
|
|
641
|
+
*/
|
|
642
|
+
export declare function createAceBuilder(): AceSvamlBuilder;
|
|
643
|
+
/**
|
|
644
|
+
* Create a new PIE SVAML builder
|
|
645
|
+
*/
|
|
646
|
+
export declare function createPieBuilder(): PieSvamlBuilder;
|
|
647
|
+
/**
|
|
648
|
+
* Cache interface for Sinch Functions
|
|
649
|
+
*
|
|
650
|
+
* Both dev (LocalCache) and prod (DaprCache) implement this interface,
|
|
651
|
+
* allowing seamless package swap during deployment.
|
|
652
|
+
*/
|
|
653
|
+
/**
|
|
654
|
+
* Function cache interface
|
|
655
|
+
*
|
|
656
|
+
* Provides key-value storage with TTL support.
|
|
657
|
+
* In development, uses in-memory storage.
|
|
658
|
+
* In production, uses Dapr state store.
|
|
659
|
+
*/
|
|
660
|
+
export interface IFunctionCache {
|
|
661
|
+
/**
|
|
662
|
+
* Store a value with optional TTL
|
|
663
|
+
*
|
|
664
|
+
* @param key - Cache key
|
|
665
|
+
* @param value - Value to store (will be JSON serialized)
|
|
666
|
+
* @param ttlSeconds - Time to live in seconds (default: 3600)
|
|
667
|
+
*/
|
|
668
|
+
set<T = unknown>(key: string, value: T, ttlSeconds?: number): Promise<void>;
|
|
669
|
+
/**
|
|
670
|
+
* Retrieve a value from cache
|
|
671
|
+
*
|
|
672
|
+
* @param key - Cache key
|
|
673
|
+
* @returns The stored value or null if not found/expired
|
|
674
|
+
*/
|
|
675
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
676
|
+
/**
|
|
677
|
+
* Check if a key exists in the cache
|
|
678
|
+
*
|
|
679
|
+
* @param key - Cache key
|
|
680
|
+
*/
|
|
681
|
+
has(key: string): Promise<boolean>;
|
|
682
|
+
/**
|
|
683
|
+
* Delete a value from cache
|
|
684
|
+
*
|
|
685
|
+
* @param key - Cache key
|
|
686
|
+
* @returns true if the key existed and was deleted
|
|
687
|
+
*/
|
|
688
|
+
delete(key: string): Promise<boolean>;
|
|
689
|
+
/**
|
|
690
|
+
* Extend TTL for a key
|
|
691
|
+
*
|
|
692
|
+
* @param key - Cache key
|
|
693
|
+
* @param additionalSeconds - Additional seconds to add to TTL
|
|
694
|
+
* @returns true if the key exists and TTL was extended
|
|
695
|
+
*/
|
|
696
|
+
extend(key: string, additionalSeconds: number): Promise<boolean>;
|
|
697
|
+
/**
|
|
698
|
+
* Get all keys matching a pattern
|
|
699
|
+
*
|
|
700
|
+
* @param pattern - Pattern with * wildcard (default: '*')
|
|
701
|
+
* @returns Array of matching keys
|
|
702
|
+
*/
|
|
703
|
+
keys(pattern?: string): Promise<string[]>;
|
|
704
|
+
/**
|
|
705
|
+
* Get multiple values at once
|
|
706
|
+
*
|
|
707
|
+
* @param keys - Array of keys to retrieve
|
|
708
|
+
* @returns Object with keys and their values (or null if not found)
|
|
709
|
+
*/
|
|
710
|
+
getMany<T = unknown>(keys: string[]): Promise<Record<string, T | null>>;
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Function configuration with environment variables
|
|
714
|
+
*/
|
|
715
|
+
export interface FunctionConfig {
|
|
716
|
+
/** Project ID */
|
|
717
|
+
projectId: string;
|
|
718
|
+
/** Function name */
|
|
719
|
+
functionName: string;
|
|
720
|
+
/** Environment (development, production) */
|
|
721
|
+
environment: "development" | "production";
|
|
722
|
+
/** Custom environment variables */
|
|
723
|
+
variables?: Record<string, string>;
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Main function context object passed to all handlers
|
|
727
|
+
*
|
|
728
|
+
* Note: Call-specific data like callId is available on the callback event data,
|
|
729
|
+
* not on the context object.
|
|
730
|
+
*/
|
|
731
|
+
export interface FunctionContext {
|
|
732
|
+
/** Configuration including environment variables */
|
|
733
|
+
config: FunctionConfig;
|
|
734
|
+
/** Cache client for persistent data */
|
|
735
|
+
cache: IFunctionCache;
|
|
736
|
+
/** Request ID for tracing */
|
|
737
|
+
requestId?: string;
|
|
738
|
+
/** Timestamp of the request */
|
|
739
|
+
timestamp?: string;
|
|
740
|
+
/** Environment variables */
|
|
741
|
+
env?: Record<string, string | undefined>;
|
|
742
|
+
/** Sinch Voice SDK client (if available) */
|
|
743
|
+
voice?: VoiceService;
|
|
744
|
+
/** Sinch Conversation SDK client (if available) */
|
|
745
|
+
conversation?: ConversationService;
|
|
746
|
+
/** Sinch SMS SDK client (if available) */
|
|
747
|
+
sms?: SmsService;
|
|
748
|
+
/** Sinch Numbers SDK client (if available) */
|
|
749
|
+
numbers?: NumbersService;
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Application credentials structure
|
|
753
|
+
*/
|
|
754
|
+
export interface ApplicationCredentials {
|
|
755
|
+
applicationKey: string;
|
|
756
|
+
applicationSecret: string;
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Configuration summary for debugging
|
|
760
|
+
*/
|
|
761
|
+
export interface ConfigSummary {
|
|
762
|
+
environment: "production" | "development";
|
|
763
|
+
variables: Record<string, string | undefined>;
|
|
764
|
+
secrets: Record<string, string>;
|
|
765
|
+
hasApplicationCredentials: boolean;
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* Universal configuration utility class
|
|
769
|
+
*
|
|
770
|
+
* Provides a consistent interface for accessing environment variables,
|
|
771
|
+
* secrets, and configuration across local and production environments.
|
|
772
|
+
*/
|
|
773
|
+
export declare class UniversalConfig {
|
|
774
|
+
private context;
|
|
775
|
+
private env;
|
|
776
|
+
/**
|
|
777
|
+
* Create a new UniversalConfig instance
|
|
778
|
+
*
|
|
779
|
+
* @param context - Function execution context
|
|
780
|
+
*/
|
|
781
|
+
constructor(context: FunctionContext);
|
|
782
|
+
/**
|
|
783
|
+
* Get a secret value (e.g., API keys, passwords, tokens)
|
|
784
|
+
*
|
|
785
|
+
* @param name - Secret name (e.g., 'PROJECT_ID_API_SECRET')
|
|
786
|
+
* @param defaultValue - Optional default value if secret not found
|
|
787
|
+
*/
|
|
788
|
+
getSecret(name: string, defaultValue?: string | null): string | null;
|
|
789
|
+
/**
|
|
790
|
+
* Get an environment variable (non-secret configuration)
|
|
791
|
+
*
|
|
792
|
+
* @param name - Variable name (e.g., 'COMPANY_NAME', 'API_URL')
|
|
793
|
+
* @param defaultValue - Optional default value
|
|
794
|
+
*/
|
|
795
|
+
getVariable(name: string, defaultValue?: string | null): string | null;
|
|
796
|
+
/**
|
|
797
|
+
* Check if a secret exists (has a value)
|
|
798
|
+
*
|
|
799
|
+
* @param name - Secret name
|
|
800
|
+
*/
|
|
801
|
+
hasSecret(name: string): boolean;
|
|
802
|
+
/**
|
|
803
|
+
* Check if a variable exists (has a value)
|
|
804
|
+
*
|
|
805
|
+
* @param name - Variable name
|
|
806
|
+
*/
|
|
807
|
+
hasVariable(name: string): boolean;
|
|
808
|
+
/**
|
|
809
|
+
* Get required secret (throws error if not found)
|
|
810
|
+
*
|
|
811
|
+
* @param name - Secret name
|
|
812
|
+
* @throws Error if secret is not found
|
|
813
|
+
*/
|
|
814
|
+
requireSecret(name: string): string;
|
|
815
|
+
/**
|
|
816
|
+
* Get required variable (throws error if not found)
|
|
817
|
+
*
|
|
818
|
+
* @param name - Variable name
|
|
819
|
+
* @throws Error if variable is not found
|
|
820
|
+
*/
|
|
821
|
+
requireVariable(name: string): string;
|
|
822
|
+
/**
|
|
823
|
+
* Get Sinch application credentials
|
|
824
|
+
*/
|
|
825
|
+
getApplicationCredentials(): ApplicationCredentials | null;
|
|
826
|
+
/**
|
|
827
|
+
* Check if running in development mode
|
|
828
|
+
*/
|
|
829
|
+
isDevelopment(): boolean;
|
|
830
|
+
/**
|
|
831
|
+
* Check if running in production mode
|
|
832
|
+
*/
|
|
833
|
+
isProduction(): boolean;
|
|
834
|
+
/**
|
|
835
|
+
* Get cache client instance
|
|
836
|
+
*/
|
|
837
|
+
getCache(): IFunctionCache | undefined;
|
|
838
|
+
/**
|
|
839
|
+
* Get comprehensive configuration summary (useful for debugging)
|
|
840
|
+
* Excludes actual secret values for security
|
|
841
|
+
*/
|
|
842
|
+
getConfigSummary(): ConfigSummary;
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Create a universal config instance for a function execution context
|
|
846
|
+
*
|
|
847
|
+
* @param context - Function execution context
|
|
848
|
+
*/
|
|
849
|
+
export declare function createConfig(context: FunctionContext): UniversalConfig;
|
|
850
|
+
export declare const createUniversalConfig: typeof createConfig;
|
|
851
|
+
/**
|
|
852
|
+
* HTTP request/response types for custom API endpoints
|
|
853
|
+
*/
|
|
854
|
+
/**
|
|
855
|
+
* HTTP methods supported by function endpoints
|
|
856
|
+
*/
|
|
857
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
858
|
+
/**
|
|
859
|
+
* HTTP request for custom endpoints
|
|
860
|
+
*
|
|
861
|
+
* Abstraction over Express request for user-friendly API handling.
|
|
862
|
+
*/
|
|
863
|
+
export interface FunctionRequest {
|
|
864
|
+
/** HTTP method */
|
|
865
|
+
method: HttpMethod;
|
|
866
|
+
/** Request path */
|
|
867
|
+
path: string;
|
|
868
|
+
/** Query parameters */
|
|
869
|
+
query?: Record<string, string | string[]>;
|
|
870
|
+
/** Request headers (lowercase keys) */
|
|
871
|
+
headers?: Record<string, string>;
|
|
872
|
+
/** Request body (parsed JSON) */
|
|
873
|
+
body?: unknown;
|
|
874
|
+
/** Route parameters (e.g., /users/:id) */
|
|
875
|
+
params?: Record<string, string>;
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* HTTP response for custom endpoints
|
|
879
|
+
*
|
|
880
|
+
* Return this from custom API handlers to control the response.
|
|
881
|
+
*/
|
|
882
|
+
export interface FunctionResponse {
|
|
883
|
+
/** HTTP status code (default: 200) */
|
|
884
|
+
statusCode: number;
|
|
885
|
+
/** Response headers */
|
|
886
|
+
headers?: Record<string, string>;
|
|
887
|
+
/** Response body (will be JSON serialized) */
|
|
888
|
+
body?: unknown;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Create a response with custom status code
|
|
892
|
+
*/
|
|
893
|
+
export declare function createResponse<T>(statusCode: number, body?: T, headers?: Record<string, string>): FunctionResponse;
|
|
894
|
+
/**
|
|
895
|
+
* Create a JSON response
|
|
896
|
+
*/
|
|
897
|
+
export declare function createJsonResponse<T>(body: T, statusCode?: number): FunctionResponse;
|
|
898
|
+
/**
|
|
899
|
+
* Create an error response
|
|
900
|
+
*/
|
|
901
|
+
export declare function createErrorResponse(message: string, statusCode?: number): FunctionResponse;
|
|
902
|
+
/**
|
|
903
|
+
* Voice event handler function signature
|
|
904
|
+
*
|
|
905
|
+
* @template T - The specific callback data type
|
|
906
|
+
* @template R - The return type (SVAML or void for notification events)
|
|
907
|
+
*/
|
|
908
|
+
export type VoiceEventHandler<T, R = SvamletResponse | void> = (context: FunctionContext, callbackData: T) => Promise<R>;
|
|
909
|
+
/**
|
|
910
|
+
* Custom API handler function signature
|
|
911
|
+
*/
|
|
912
|
+
export type ApiHandler = (context: FunctionContext, request: FunctionRequest) => Promise<FunctionResponse | unknown>;
|
|
913
|
+
/**
|
|
914
|
+
* ICE (Incoming Call Event) handler
|
|
915
|
+
*/
|
|
916
|
+
export type IceHandler = (context: FunctionContext, callbackData: Voice.IceRequest) => Promise<SvamletResponse>;
|
|
917
|
+
/**
|
|
918
|
+
* ACE (Answered Call Event) handler
|
|
919
|
+
*/
|
|
920
|
+
export type AceHandler = (context: FunctionContext, callbackData: Voice.AceRequest) => Promise<SvamletResponse>;
|
|
921
|
+
/**
|
|
922
|
+
* PIE (Prompt Input Event) handler
|
|
923
|
+
*/
|
|
924
|
+
export type PieHandler = (context: FunctionContext, callbackData: Voice.PieRequest) => Promise<SvamletResponse>;
|
|
925
|
+
/**
|
|
926
|
+
* DICE (Disconnect Call Event) handler
|
|
927
|
+
*/
|
|
928
|
+
export type DiceHandler = (context: FunctionContext, callbackData: Voice.DiceRequest) => Promise<void>;
|
|
929
|
+
/**
|
|
930
|
+
* Notify handler
|
|
931
|
+
*/
|
|
932
|
+
export type NotifyHandler = (context: FunctionContext, callbackData: Voice.NotifyRequest) => Promise<void>;
|
|
933
|
+
/**
|
|
934
|
+
* Voice function export structure
|
|
935
|
+
*
|
|
936
|
+
* This is the shape of the module that users export from function.ts.
|
|
937
|
+
* The runtime discovers and invokes the appropriate handler based on
|
|
938
|
+
* the incoming request.
|
|
939
|
+
*
|
|
940
|
+
* @example
|
|
941
|
+
* ```typescript
|
|
942
|
+
* import type { VoiceFunction } from '@sinch/functions-runtime';
|
|
943
|
+
* import type { Voice } from '@sinch/voice';
|
|
944
|
+
*
|
|
945
|
+
* export default {
|
|
946
|
+
* async ice(context, data: Voice.IceRequest) {
|
|
947
|
+
* const { cli, to } = data;
|
|
948
|
+
* return createIceBuilder().hangup().build();
|
|
949
|
+
* }
|
|
950
|
+
* } satisfies VoiceFunction;
|
|
951
|
+
* ```
|
|
952
|
+
*/
|
|
953
|
+
export interface VoiceFunction {
|
|
954
|
+
/** Handle ICE (Incoming Call Event) */
|
|
955
|
+
ice?: IceHandler;
|
|
956
|
+
/** Handle ACE (Answered Call Event) */
|
|
957
|
+
ace?: AceHandler;
|
|
958
|
+
/** Handle PIE (Prompt Input Event) */
|
|
959
|
+
pie?: PieHandler;
|
|
960
|
+
/** Handle DICE (Disconnect Call Event) */
|
|
961
|
+
dice?: DiceHandler;
|
|
962
|
+
/** Handle notify events */
|
|
963
|
+
notify?: NotifyHandler;
|
|
964
|
+
/** Default handler for GET / */
|
|
965
|
+
default?: ApiHandler;
|
|
966
|
+
/** Custom API endpoints (any other exported function) */
|
|
967
|
+
[key: string]: unknown;
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* @deprecated Use VoiceFunction instead. SinchFunction will be removed in a future version.
|
|
971
|
+
*/
|
|
972
|
+
export type SinchFunction = VoiceFunction;
|
|
973
|
+
/**
|
|
974
|
+
* Options for camelCase key transformation
|
|
975
|
+
*/
|
|
976
|
+
export interface CamelCaseOptions {
|
|
977
|
+
/** Transform nested objects */
|
|
978
|
+
deep?: boolean;
|
|
979
|
+
/** Paths to skip transformation */
|
|
980
|
+
stopPaths?: string[];
|
|
981
|
+
/** Keys to exclude from transformation */
|
|
982
|
+
exclude?: (string | RegExp)[];
|
|
983
|
+
}
|
|
984
|
+
/**
|
|
985
|
+
* Options for JSON parsing middleware
|
|
986
|
+
*/
|
|
987
|
+
export interface JsonParsingOptions {
|
|
988
|
+
/** Maximum body size (default: '10mb') */
|
|
989
|
+
limit?: string;
|
|
990
|
+
/** Accept JSON5 features (default: true) */
|
|
991
|
+
allowJson5?: boolean;
|
|
992
|
+
/** CamelCase transformation options */
|
|
993
|
+
camelCase?: CamelCaseOptions;
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Extended Express Request with rawBody for signature validation
|
|
997
|
+
*/
|
|
998
|
+
export interface SinchRequest extends Request {
|
|
999
|
+
rawBody?: string;
|
|
1000
|
+
_keysTransformed?: boolean;
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Convert string to camelCase
|
|
1004
|
+
*
|
|
1005
|
+
* Handles:
|
|
1006
|
+
* - snake_case: call_id -> callId
|
|
1007
|
+
* - kebab-case: call-id -> callId
|
|
1008
|
+
* - lowercase concatenated: callid -> callId
|
|
1009
|
+
*/
|
|
1010
|
+
export declare function toCamelCase(str: string): string;
|
|
1011
|
+
/**
|
|
1012
|
+
* Deep transform object keys to camelCase
|
|
1013
|
+
*/
|
|
1014
|
+
export declare function transformKeys<T>(obj: T, options?: CamelCaseOptions): T;
|
|
1015
|
+
/**
|
|
1016
|
+
* Parse JSON with fallback to basic JSON5 support
|
|
1017
|
+
*/
|
|
1018
|
+
export declare function parseJson(text: string, allowJson5?: boolean): unknown;
|
|
1019
|
+
/**
|
|
1020
|
+
* Create Express middleware for lenient JSON parsing with camelCase transformation
|
|
1021
|
+
*/
|
|
1022
|
+
export declare function createLenientJsonParser(options?: JsonParsingOptions): (req: SinchRequest, res: Response, next: NextFunction) => void;
|
|
1023
|
+
/**
|
|
1024
|
+
* Setup Express app with JSON parsing middleware
|
|
1025
|
+
*/
|
|
1026
|
+
export declare function setupJsonParsing(app: Express, options?: JsonParsingOptions): Express;
|
|
1027
|
+
/**
|
|
1028
|
+
* Options for creating the Express app
|
|
1029
|
+
*/
|
|
1030
|
+
export interface AppOptions {
|
|
1031
|
+
/** JSON parsing options */
|
|
1032
|
+
jsonParsingOptions?: JsonParsingOptions;
|
|
1033
|
+
/** Enable landing page for browser requests at root (default: true) */
|
|
1034
|
+
landingPageEnabled?: boolean;
|
|
1035
|
+
/** Directory to serve static files from (optional) */
|
|
1036
|
+
staticDir?: string;
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Options for setting up the request handler
|
|
1040
|
+
*/
|
|
1041
|
+
export interface RequestHandlerOptions {
|
|
1042
|
+
/** Function to load user code module (can be sync or async for ESM) */
|
|
1043
|
+
loadUserFunction?: () => SinchFunction | Promise<SinchFunction>;
|
|
1044
|
+
/** Function to build context for each request */
|
|
1045
|
+
buildContext?: (req: Request) => FunctionContext;
|
|
1046
|
+
/** Logger function */
|
|
1047
|
+
logger?: (...args: unknown[]) => void;
|
|
1048
|
+
/** Enable landing page for browser requests at root (default: true) */
|
|
1049
|
+
landingPageEnabled?: boolean;
|
|
1050
|
+
/** Called when request starts */
|
|
1051
|
+
onRequestStart?: (data: {
|
|
1052
|
+
functionName: string;
|
|
1053
|
+
req: Request;
|
|
1054
|
+
}) => void;
|
|
1055
|
+
/** Called when request ends */
|
|
1056
|
+
onRequestEnd?: (data: {
|
|
1057
|
+
functionName: string;
|
|
1058
|
+
req: Request;
|
|
1059
|
+
response?: FormattedResponse;
|
|
1060
|
+
error?: Error;
|
|
1061
|
+
duration: number;
|
|
1062
|
+
statusCode: number;
|
|
1063
|
+
}) => void;
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Formatted response structure
|
|
1067
|
+
*/
|
|
1068
|
+
export interface FormattedResponse {
|
|
1069
|
+
statusCode: number;
|
|
1070
|
+
headers?: Record<string, string>;
|
|
1071
|
+
body?: unknown;
|
|
1072
|
+
}
|
|
1073
|
+
/** Voice callback function names */
|
|
1074
|
+
export declare const VOICE_CALLBACKS: readonly [
|
|
1075
|
+
"ice",
|
|
1076
|
+
"ace",
|
|
1077
|
+
"pie",
|
|
1078
|
+
"dice",
|
|
1079
|
+
"notify"
|
|
1080
|
+
];
|
|
1081
|
+
/** Notification-only events (don't require SVAML response) */
|
|
1082
|
+
export declare const NOTIFICATION_EVENTS: readonly [
|
|
1083
|
+
"dice",
|
|
1084
|
+
"notify"
|
|
1085
|
+
];
|
|
1086
|
+
export type VoiceCallback = (typeof VOICE_CALLBACKS)[number];
|
|
1087
|
+
export type NotificationEvent = (typeof NOTIFICATION_EVENTS)[number];
|
|
1088
|
+
/**
|
|
1089
|
+
* Check if a function name is a voice callback
|
|
1090
|
+
*/
|
|
1091
|
+
export declare function isVoiceCallback(functionName: string): functionName is VoiceCallback;
|
|
1092
|
+
/**
|
|
1093
|
+
* Check if a function is a notification-only event
|
|
1094
|
+
*/
|
|
1095
|
+
export declare function isNotificationEvent(functionName: string): functionName is NotificationEvent;
|
|
1096
|
+
/**
|
|
1097
|
+
* Extract function name from request path or body
|
|
1098
|
+
*/
|
|
1099
|
+
export declare function extractFunctionName(path: string, body?: {
|
|
1100
|
+
event?: string;
|
|
1101
|
+
}): string;
|
|
1102
|
+
/**
|
|
1103
|
+
* Generate unique request ID
|
|
1104
|
+
*/
|
|
1105
|
+
export declare function generateRequestId(): string;
|
|
1106
|
+
/**
|
|
1107
|
+
* Format SVAML response for voice callbacks
|
|
1108
|
+
*/
|
|
1109
|
+
export declare function formatSvamlResponse(result: unknown, functionName: string): FormattedResponse;
|
|
1110
|
+
/**
|
|
1111
|
+
* Format custom endpoint response
|
|
1112
|
+
*/
|
|
1113
|
+
export declare function formatCustomResponse(result: unknown): FormattedResponse;
|
|
1114
|
+
/**
|
|
1115
|
+
* Validate voice callback request
|
|
1116
|
+
*/
|
|
1117
|
+
export declare function validateVoiceRequest(body: unknown): {
|
|
1118
|
+
valid: boolean;
|
|
1119
|
+
error?: string;
|
|
1120
|
+
expectedEvents?: string[];
|
|
1121
|
+
};
|
|
1122
|
+
/**
|
|
1123
|
+
* Build base context object for function execution
|
|
1124
|
+
*
|
|
1125
|
+
* Note: Call-specific data like callId is available on the callback event data,
|
|
1126
|
+
* not on the context object.
|
|
1127
|
+
*/
|
|
1128
|
+
export declare function buildBaseContext(req: Request, config?: Partial<FunctionConfig>): FunctionContext;
|
|
1129
|
+
/**
|
|
1130
|
+
* Handle voice callback execution
|
|
1131
|
+
*/
|
|
1132
|
+
export declare function handleVoiceCallback(functionName: string, userFunction: SinchFunction, context: FunctionContext, callbackData: unknown, logger?: (...args: unknown[]) => void): Promise<FormattedResponse>;
|
|
1133
|
+
/**
|
|
1134
|
+
* Handle custom endpoint execution
|
|
1135
|
+
*/
|
|
1136
|
+
export declare function handleCustomEndpoint(functionName: string, userFunction: SinchFunction, context: FunctionContext, request: FunctionRequest, logger?: (...args: unknown[]) => void): Promise<FormattedResponse>;
|
|
1137
|
+
/**
|
|
1138
|
+
* Create and configure Express app with standard middleware
|
|
1139
|
+
*/
|
|
1140
|
+
export declare function createApp(options?: AppOptions): Express;
|
|
1141
|
+
/**
|
|
1142
|
+
* Setup the main request handler
|
|
1143
|
+
*/
|
|
1144
|
+
export declare function setupRequestHandler(app: Express, options?: RequestHandlerOptions): void;
|
|
1145
|
+
export interface SinchClients {
|
|
1146
|
+
voice?: VoiceService;
|
|
1147
|
+
conversation?: ConversationService;
|
|
1148
|
+
sms?: SmsService;
|
|
1149
|
+
numbers?: NumbersService;
|
|
1150
|
+
validateWebhookSignature?: (requestData: WebhookRequestData) => boolean;
|
|
1151
|
+
}
|
|
1152
|
+
export interface WebhookRequestData {
|
|
1153
|
+
method: string;
|
|
1154
|
+
path: string;
|
|
1155
|
+
headers: Record<string, string>;
|
|
1156
|
+
body: string;
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Get or create Sinch clients (with caching)
|
|
1160
|
+
*/
|
|
1161
|
+
export declare function getSinchClients(): SinchClients;
|
|
1162
|
+
/**
|
|
1163
|
+
* Reset cached clients (useful for testing)
|
|
1164
|
+
*/
|
|
1165
|
+
export declare function resetSinchClients(): void;
|
|
1166
|
+
/**
|
|
1167
|
+
* Simple template renderer for HTML files
|
|
1168
|
+
* Replaces {{variableName}} placeholders with actual values
|
|
1169
|
+
*/
|
|
1170
|
+
export declare class TemplateRender {
|
|
1171
|
+
/**
|
|
1172
|
+
* Load and render an HTML template with variables
|
|
1173
|
+
* @param templatePath - Path to the HTML template file
|
|
1174
|
+
* @param variables - Object containing variables to replace in template
|
|
1175
|
+
* @returns Rendered HTML string
|
|
1176
|
+
*/
|
|
1177
|
+
static render(templatePath: string, variables?: Record<string, any>): string;
|
|
1178
|
+
/**
|
|
1179
|
+
* Get the absolute path to a template file relative to the current directory
|
|
1180
|
+
* @param templateName - Name of the template file (e.g., 'index.html')
|
|
1181
|
+
* @param baseDir - Base directory to search from (defaults to cwd)
|
|
1182
|
+
* @returns Absolute path to the template file
|
|
1183
|
+
*/
|
|
1184
|
+
static getTemplatePath(templateName: string, baseDir?: string): string;
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Version extractor utility for reading template versions from README.md files
|
|
1188
|
+
*/
|
|
1189
|
+
export declare class VersionExtractor {
|
|
1190
|
+
/**
|
|
1191
|
+
* Extract version from README.md file in the template directory
|
|
1192
|
+
* Looks for "Template Version: X.X.X" pattern in the last few lines
|
|
1193
|
+
* @param templateDir - Path to the template directory containing README.md
|
|
1194
|
+
* @returns Version string or default fallback
|
|
1195
|
+
*/
|
|
1196
|
+
static getTemplateVersion(templateDir?: string): string;
|
|
1197
|
+
}
|
|
1198
|
+
export interface DefaultEndpointOptions {
|
|
1199
|
+
serviceName?: string;
|
|
1200
|
+
companyName?: string;
|
|
1201
|
+
templateVersion?: string;
|
|
1202
|
+
availableEndpoints?: Record<string, string>;
|
|
1203
|
+
}
|
|
1204
|
+
export interface HttpRequest {
|
|
1205
|
+
method: string;
|
|
1206
|
+
path: string;
|
|
1207
|
+
query?: Record<string, any>;
|
|
1208
|
+
headers?: Record<string, string>;
|
|
1209
|
+
body?: any;
|
|
1210
|
+
params?: Record<string, string>;
|
|
1211
|
+
}
|
|
1212
|
+
export interface HttpResponse {
|
|
1213
|
+
statusCode: number;
|
|
1214
|
+
headers: Record<string, string>;
|
|
1215
|
+
body: any;
|
|
1216
|
+
}
|
|
1217
|
+
export declare class DefaultEndpointHandler {
|
|
1218
|
+
/**
|
|
1219
|
+
* Handle the default endpoint with content negotiation
|
|
1220
|
+
* @param context - Function context with config and cache
|
|
1221
|
+
* @param request - HTTP request object with method, path, query, headers, body, params
|
|
1222
|
+
* @param options - Configuration options for the response
|
|
1223
|
+
* @returns HTTP response object with statusCode, headers, and body
|
|
1224
|
+
*/
|
|
1225
|
+
static handle(context: FunctionContext, request: HttpRequest, options?: DefaultEndpointOptions): Promise<HttpResponse>;
|
|
1226
|
+
}
|
|
1227
|
+
/** @deprecated Import from '@sinch/voice' instead: `import type { Voice } from '@sinch/voice'` then use `Voice.IceRequest` */
|
|
1228
|
+
export type IceCallbackData = Voice.IceRequest;
|
|
1229
|
+
/** @deprecated Import from '@sinch/voice' instead */
|
|
1230
|
+
export type AceCallbackData = Voice.AceRequest;
|
|
1231
|
+
/** @deprecated Import from '@sinch/voice' instead */
|
|
1232
|
+
export type PieCallbackData = Voice.PieRequest;
|
|
1233
|
+
/** @deprecated Import from '@sinch/voice' instead */
|
|
1234
|
+
export type DiceCallbackData = Voice.DiceRequest;
|
|
1235
|
+
/** @deprecated Import from '@sinch/voice' instead */
|
|
1236
|
+
export type NotifyCallbackData = Voice.NotifyRequest;
|
|
1237
|
+
/** @deprecated Import from '@sinch/voice' instead */
|
|
1238
|
+
export type MenuResult = Voice.MenuResult;
|
|
1239
|
+
/** @deprecated Import from '@sinch/voice' instead */
|
|
1240
|
+
export type AmdResult = Voice.AnsweringMachineDetection;
|
|
1241
|
+
/** @deprecated Import from '@sinch/voice' instead */
|
|
1242
|
+
export type DisconnectReason = Voice.DiceReasonEnum;
|
|
1243
|
+
/** @deprecated Import from '@sinch/voice' instead */
|
|
1244
|
+
export type CallResult = Voice.ResultEnum;
|
|
1245
|
+
/**
|
|
1246
|
+
* Union type for all voice callback data
|
|
1247
|
+
*/
|
|
1248
|
+
export type VoiceCallbackData = Voice.IceRequest | Voice.AceRequest | Voice.PieRequest | Voice.DiceRequest | Voice.NotifyRequest;
|
|
1249
|
+
/**
|
|
1250
|
+
* Local cache client for development
|
|
1251
|
+
*
|
|
1252
|
+
* Implements IFunctionCache using an in-memory Map with TTL support.
|
|
1253
|
+
* Data is lost when the process restarts.
|
|
1254
|
+
*/
|
|
1255
|
+
export declare class LocalCache implements IFunctionCache {
|
|
1256
|
+
private cache;
|
|
1257
|
+
constructor();
|
|
1258
|
+
set<T = unknown>(key: string, value: T, ttlSeconds?: number): Promise<void>;
|
|
1259
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
1260
|
+
has(key: string): Promise<boolean>;
|
|
1261
|
+
delete(key: string): Promise<boolean>;
|
|
1262
|
+
extend(key: string, additionalSeconds: number): Promise<boolean>;
|
|
1263
|
+
keys(pattern?: string): Promise<string[]>;
|
|
1264
|
+
getMany<T = unknown>(keys: string[]): Promise<Record<string, T | null>>;
|
|
1265
|
+
/**
|
|
1266
|
+
* Clear all entries from the cache
|
|
1267
|
+
* (Utility method for testing)
|
|
1268
|
+
*/
|
|
1269
|
+
clear(): Promise<void>;
|
|
1270
|
+
/**
|
|
1271
|
+
* Get the number of entries in the cache
|
|
1272
|
+
* (Utility method for debugging)
|
|
1273
|
+
*/
|
|
1274
|
+
get size(): number;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* Factory function to create a cache client
|
|
1278
|
+
*
|
|
1279
|
+
* @param _projectId - Project ID (unused in local development)
|
|
1280
|
+
* @param _functionName - Function name (unused in local development)
|
|
1281
|
+
*/
|
|
1282
|
+
export declare function createCacheClient(_projectId?: string, _functionName?: string): IFunctionCache;
|
|
1283
|
+
/**
|
|
1284
|
+
* Tunnel Client for Sinch Functions
|
|
1285
|
+
*
|
|
1286
|
+
* Connects to the Sinch Functions API via WebSocket to receive
|
|
1287
|
+
* incoming voice callbacks during local development.
|
|
1288
|
+
*/
|
|
1289
|
+
export declare class TunnelClient {
|
|
1290
|
+
private ws;
|
|
1291
|
+
private tunnelUrl;
|
|
1292
|
+
private isConnected;
|
|
1293
|
+
private reconnectAttempts;
|
|
1294
|
+
private maxReconnectAttempts;
|
|
1295
|
+
private reconnectDelay;
|
|
1296
|
+
private heartbeatInterval;
|
|
1297
|
+
private localPort;
|
|
1298
|
+
constructor(localPort?: number);
|
|
1299
|
+
connect(): Promise<void>;
|
|
1300
|
+
private handleMessage;
|
|
1301
|
+
private handleRequest;
|
|
1302
|
+
private sendPong;
|
|
1303
|
+
private startHeartbeat;
|
|
1304
|
+
private stopHeartbeat;
|
|
1305
|
+
private displayTestPhoneNumbers;
|
|
1306
|
+
private scheduleReconnect;
|
|
1307
|
+
disconnect(): void;
|
|
1308
|
+
getTunnelUrl(): string | null;
|
|
1309
|
+
getIsConnected(): boolean;
|
|
1310
|
+
}
|
|
1311
|
+
export declare function getTunnelClient(localPort?: number): TunnelClient;
|
|
1312
|
+
/**
|
|
1313
|
+
* Secrets Loader for Local Development
|
|
1314
|
+
*
|
|
1315
|
+
* Loads secrets from OS keychain (Windows Credential Manager, macOS Keychain, Linux Secret Service)
|
|
1316
|
+
* using the same storage pattern as the Sinch CLI. This enables F5 debugging in VS Code
|
|
1317
|
+
* without needing to run 'sinch functions dev'.
|
|
1318
|
+
*
|
|
1319
|
+
* Security: Only loads secrets that are declared in .env file (empty values)
|
|
1320
|
+
* In production, secrets are injected by the platform, so this is development-only.
|
|
1321
|
+
*/
|
|
1322
|
+
export declare class SecretsLoader {
|
|
1323
|
+
private SERVICE_NAME;
|
|
1324
|
+
private username;
|
|
1325
|
+
/**
|
|
1326
|
+
* Load secrets from OS keychain for variables declared in .env
|
|
1327
|
+
* Only loads secrets that have empty values in .env (security best practice)
|
|
1328
|
+
*/
|
|
1329
|
+
loadFromKeychain(): Promise<boolean>;
|
|
1330
|
+
/**
|
|
1331
|
+
* Helper to get application key from sinch.json
|
|
1332
|
+
*/
|
|
1333
|
+
private getApplicationKeyFromConfig;
|
|
1334
|
+
/**
|
|
1335
|
+
* Helper to get function name from sinch.json
|
|
1336
|
+
*/
|
|
1337
|
+
private getFunctionNameFromConfig;
|
|
1338
|
+
/**
|
|
1339
|
+
* Load custom secrets added via 'sinch functions secrets' command
|
|
1340
|
+
*/
|
|
1341
|
+
loadCustomSecrets(secretNames?: string[]): Promise<Record<string, string>>;
|
|
1342
|
+
/**
|
|
1343
|
+
* Check if keytar is available
|
|
1344
|
+
*/
|
|
1345
|
+
isAvailable(): Promise<boolean>;
|
|
1346
|
+
}
|
|
1347
|
+
export declare const secretsLoader: SecretsLoader;
|
|
1348
|
+
|
|
1349
|
+
export {
|
|
1350
|
+
CamelCaseOptions as ParserCamelCaseOptions,
|
|
1351
|
+
JsonParsingOptions as ParserOptions,
|
|
1352
|
+
createLenientJsonParser as createJsonParser,
|
|
1353
|
+
parseJson as parseJsonLenient,
|
|
1354
|
+
setupJsonParsing as setupJsonMiddleware,
|
|
1355
|
+
toCamelCase as convertToCamelCase,
|
|
1356
|
+
transformKeys as transformKeysToCamelCase,
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
export {};
|