@sinch/functions-runtime 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { ConversationService } from '@sinch/conversation';
4
4
  import { NumbersService } from '@sinch/numbers';
5
+ import { Conversation, ConversationService } from '@sinch/sdk-core';
5
6
  import { SmsService } from '@sinch/sms';
6
7
  import { Voice, VoiceService } from '@sinch/voice';
7
8
  import { Express as Express$1, NextFunction, Request as Request$1, Response as Response$1 } from 'express';
@@ -377,7 +378,15 @@ export declare const MenuTemplates: {
377
378
  */
378
379
  readonly numericInput: (prompt: string, digits?: number) => MenuStructure;
379
380
  };
380
- declare enum AgentProvider {
381
+ /**
382
+ * Connect Agent Action for SVAML Builders
383
+ *
384
+ * Provides the ability to connect voice calls to AI agents via SIP.
385
+ */
386
+ /**
387
+ * Supported AI agent providers
388
+ */
389
+ export declare enum AgentProvider {
381
390
  ElevenLabs = "elevenlabs"
382
391
  }
383
392
  /**
@@ -557,6 +566,21 @@ export declare class IceSvamlBuilder extends BaseSvamlBuilder<IceSvamlBuilder> {
557
566
  *
558
567
  * @param number - E.164 formatted phone number (e.g., '+15551234567')
559
568
  * @param options - Connection options
569
+ *
570
+ * @example
571
+ * ```typescript
572
+ * // Simple connect
573
+ * new IceSvamlBuilder().connectPstn('+15551234567').build();
574
+ *
575
+ * // With options: caller ID, timeout, and AMD
576
+ * new IceSvamlBuilder()
577
+ * .connectPstn('+15551234567', {
578
+ * cli: '+15559876543',
579
+ * timeout: 30,
580
+ * amd: { enabled: true },
581
+ * })
582
+ * .build();
583
+ * ```
560
584
  */
561
585
  connectPstn(number: string, options?: ConnectPstnOptions): this;
562
586
  /**
@@ -585,6 +609,22 @@ export declare class IceSvamlBuilder extends BaseSvamlBuilder<IceSvamlBuilder> {
585
609
  *
586
610
  * @param menus - Array of menu definitions or MenuStructure from createMenu().build()
587
611
  * @param options - Menu options
612
+ *
613
+ * @example
614
+ * ```typescript
615
+ * // Using MenuTemplates
616
+ * new IceSvamlBuilder()
617
+ * .runMenu(MenuTemplates.business('Acme Corp'))
618
+ * .build();
619
+ *
620
+ * // Using createMenu builder
621
+ * const menu = createMenu()
622
+ * .prompt('Press 1 for sales, 2 for support.')
623
+ * .option('1', 'return(sales)')
624
+ * .option('2', 'return(support)')
625
+ * .build();
626
+ * new IceSvamlBuilder().runMenu(menu).build();
627
+ * ```
588
628
  */
589
629
  runMenu(menus: Menu[] | MenuStructure, options?: RunMenuOptions): this;
590
630
  /**
@@ -592,6 +632,14 @@ export declare class IceSvamlBuilder extends BaseSvamlBuilder<IceSvamlBuilder> {
592
632
  *
593
633
  * @param holdPrompt - Prompt to play while on hold
594
634
  * @param options - Park options
635
+ *
636
+ * @example
637
+ * ```typescript
638
+ * // Park with hold music prompt
639
+ * new IceSvamlBuilder()
640
+ * .park('Please hold while we connect you.', { maxDuration: 120 })
641
+ * .build();
642
+ * ```
595
643
  */
596
644
  park(holdPrompt?: string, options?: ParkOptions): this;
597
645
  /**
@@ -719,8 +767,23 @@ export declare function createPieBuilder(): PieSvamlBuilder;
719
767
  * Function cache interface
720
768
  *
721
769
  * Provides key-value storage with TTL support.
722
- * In development, uses in-memory storage.
723
- * In production, uses Dapr state store.
770
+ * In development, uses in-memory storage (data lost on restart).
771
+ * In production, uses persistent shared storage across instances.
772
+ *
773
+ * Access via `context.cache` — do not construct directly.
774
+ *
775
+ * @example
776
+ * ```typescript
777
+ * // Store a session with 30-minute TTL
778
+ * await context.cache.set('session:abc', { userId: 'u1' }, 1800);
779
+ *
780
+ * // Retrieve it later
781
+ * const session = await context.cache.get<{ userId: string }>('session:abc');
782
+ *
783
+ * // List and batch retrieve
784
+ * const keys = await context.cache.keys('session:*');
785
+ * const all = await context.cache.getMany(keys);
786
+ * ```
724
787
  */
725
788
  export interface IFunctionCache {
726
789
  /**
@@ -729,6 +792,11 @@ export interface IFunctionCache {
729
792
  * @param key - Cache key
730
793
  * @param value - Value to store (will be JSON serialized)
731
794
  * @param ttlSeconds - Time to live in seconds (default: 3600)
795
+ *
796
+ * @example
797
+ * ```typescript
798
+ * await context.cache.set('user:123', { name: 'Alice' }, 3600);
799
+ * ```
732
800
  */
733
801
  set<T = unknown>(key: string, value: T, ttlSeconds?: number): Promise<void>;
734
802
  /**
@@ -736,6 +804,12 @@ export interface IFunctionCache {
736
804
  *
737
805
  * @param key - Cache key
738
806
  * @returns The stored value or null if not found/expired
807
+ *
808
+ * @example
809
+ * ```typescript
810
+ * const user = await context.cache.get<{ name: string }>('user:123');
811
+ * if (user) console.log(user.name);
812
+ * ```
739
813
  */
740
814
  get<T = unknown>(key: string): Promise<T | null>;
741
815
  /**
@@ -757,6 +831,12 @@ export interface IFunctionCache {
757
831
  * @param key - Cache key
758
832
  * @param additionalSeconds - Additional seconds to add to TTL
759
833
  * @returns true if the key exists and TTL was extended
834
+ *
835
+ * @example
836
+ * ```typescript
837
+ * // Keep session alive for another 10 minutes
838
+ * await context.cache.extend('session:abc', 600);
839
+ * ```
760
840
  */
761
841
  extend(key: string, additionalSeconds: number): Promise<boolean>;
762
842
  /**
@@ -764,6 +844,11 @@ export interface IFunctionCache {
764
844
  *
765
845
  * @param pattern - Pattern with * wildcard (default: '*')
766
846
  * @returns Array of matching keys
847
+ *
848
+ * @example
849
+ * ```typescript
850
+ * const sessionKeys = await context.cache.keys('session:*');
851
+ * ```
767
852
  */
768
853
  keys(pattern?: string): Promise<string[]>;
769
854
  /**
@@ -771,6 +856,12 @@ export interface IFunctionCache {
771
856
  *
772
857
  * @param keys - Array of keys to retrieve
773
858
  * @returns Object with keys and their values (or null if not found)
859
+ *
860
+ * @example
861
+ * ```typescript
862
+ * const keys = await context.cache.keys('user:*');
863
+ * const users = await context.cache.getMany<User>(keys);
864
+ * ```
774
865
  */
775
866
  getMany<T = unknown>(keys: string[]): Promise<Record<string, T | null>>;
776
867
  }
@@ -790,13 +881,30 @@ export interface FunctionConfig {
790
881
  /**
791
882
  * Main function context object passed to all handlers
792
883
  *
793
- * Note: Call-specific data like callId is available on the callback event data,
884
+ * Every handler receives this as its first argument. It provides access to
885
+ * configuration, cache, SDK clients, and environment variables.
886
+ *
887
+ * @remarks
888
+ * Call-specific data like callId is available on the callback event data,
794
889
  * not on the context object.
890
+ *
891
+ * @example
892
+ * ```typescript
893
+ * export async function ice(context, event) {
894
+ * const greeting = context.config.variables?.GREETING ?? 'Hello!';
895
+ * await context.cache.set('lastCaller', event.cli, 3600);
896
+ * return new IceSvamlBuilder().say(greeting).hangup().build();
897
+ * }
898
+ * ```
795
899
  */
796
900
  export interface FunctionContext {
797
901
  /** Configuration including environment variables */
798
902
  config: FunctionConfig;
799
- /** Cache client for persistent data */
903
+ /**
904
+ * Key-value cache with TTL support.
905
+ * In-memory during development, persistent and shared in production.
906
+ * @see {@link IFunctionCache} for available methods
907
+ */
800
908
  cache: IFunctionCache;
801
909
  /** Request ID for tracing */
802
910
  requestId?: string;
@@ -804,13 +912,25 @@ export interface FunctionContext {
804
912
  timestamp?: string;
805
913
  /** Environment variables */
806
914
  env?: Record<string, string | undefined>;
807
- /** Sinch Voice SDK client (if available) */
915
+ /**
916
+ * Sinch Voice SDK client.
917
+ * Available when `VOICE_APPLICATION_KEY` and `VOICE_APPLICATION_SECRET` are set.
918
+ */
808
919
  voice?: VoiceService;
809
- /** Sinch Conversation SDK client (if available) */
920
+ /**
921
+ * Sinch Conversation SDK client.
922
+ * Available when `CONVERSATION_APP_ID` is set.
923
+ */
810
924
  conversation?: ConversationService;
811
- /** Sinch SMS SDK client (if available) */
925
+ /**
926
+ * Sinch SMS SDK client.
927
+ * Available when `SMS_SERVICE_PLAN_ID` is set.
928
+ */
812
929
  sms?: SmsService;
813
- /** Sinch Numbers SDK client (if available) */
930
+ /**
931
+ * Sinch Numbers SDK client.
932
+ * Available when `ENABLE_NUMBERS_API=true` is set.
933
+ */
814
934
  numbers?: NumbersService;
815
935
  /** Read a file from the assets/ directory (private, not served over HTTP) */
816
936
  assets(filename: string): Promise<string>;
@@ -1041,6 +1161,7 @@ export interface VoiceFunction {
1041
1161
  export type SinchFunction = VoiceFunction;
1042
1162
  /**
1043
1163
  * Options for camelCase key transformation
1164
+ * @internal
1044
1165
  */
1045
1166
  export interface CamelCaseOptions {
1046
1167
  /** Transform nested objects */
@@ -1052,6 +1173,7 @@ export interface CamelCaseOptions {
1052
1173
  }
1053
1174
  /**
1054
1175
  * Options for JSON parsing middleware
1176
+ * @internal
1055
1177
  */
1056
1178
  export interface JsonParsingOptions {
1057
1179
  /** Maximum body size (default: '10mb') */
@@ -1063,6 +1185,7 @@ export interface JsonParsingOptions {
1063
1185
  }
1064
1186
  /**
1065
1187
  * Extended Express Request with rawBody for signature validation
1188
+ * @internal
1066
1189
  */
1067
1190
  export interface SinchRequest extends Request {
1068
1191
  rawBody?: string;
@@ -1075,26 +1198,44 @@ export interface SinchRequest extends Request {
1075
1198
  * - snake_case: call_id -> callId
1076
1199
  * - kebab-case: call-id -> callId
1077
1200
  * - lowercase concatenated: callid -> callId
1201
+ * @internal
1078
1202
  */
1079
1203
  export declare function toCamelCase(str: string): string;
1080
1204
  /**
1081
1205
  * Deep transform object keys to camelCase
1206
+ * @internal
1082
1207
  */
1083
1208
  export declare function transformKeys<T>(obj: T, options?: CamelCaseOptions): T;
1084
1209
  /**
1085
1210
  * Parse JSON with fallback to basic JSON5 support
1211
+ * @internal
1086
1212
  */
1087
1213
  export declare function parseJson(text: string, allowJson5?: boolean): unknown;
1088
1214
  /**
1089
1215
  * Create Express middleware for lenient JSON parsing with camelCase transformation
1216
+ * @internal
1090
1217
  */
1091
1218
  export declare function createLenientJsonParser(options?: JsonParsingOptions): (req: SinchRequest, res: Response, next: NextFunction) => void;
1092
1219
  /**
1093
1220
  * Setup Express app with JSON parsing middleware
1221
+ * @internal
1094
1222
  */
1095
1223
  export declare function setupJsonParsing(app: Express, options?: JsonParsingOptions): Express;
1224
+ /**
1225
+ * Get the landing page HTML content
1226
+ * Exported so production runtime can also use it
1227
+ * @internal
1228
+ */
1229
+ export declare function getLandingPageHtml(): string;
1230
+ /**
1231
+ * Get the favicon SVG content
1232
+ * Exported so production runtime can also use it
1233
+ * @internal
1234
+ */
1235
+ export declare function getFaviconSvg(): string;
1096
1236
  /**
1097
1237
  * Options for creating the Express app
1238
+ * @internal
1098
1239
  */
1099
1240
  export interface AppOptions {
1100
1241
  /** JSON parsing options */
@@ -1106,6 +1247,7 @@ export interface AppOptions {
1106
1247
  }
1107
1248
  /**
1108
1249
  * Options for setting up the request handler
1250
+ * @internal
1109
1251
  */
1110
1252
  export interface RequestHandlerOptions {
1111
1253
  /** Function to load user code module (can be sync or async for ESM) */
@@ -1133,13 +1275,14 @@ export interface RequestHandlerOptions {
1133
1275
  }
1134
1276
  /**
1135
1277
  * Formatted response structure
1278
+ * @internal
1136
1279
  */
1137
1280
  export interface FormattedResponse {
1138
1281
  statusCode: number;
1139
1282
  headers?: Record<string, string>;
1140
1283
  body?: unknown;
1141
1284
  }
1142
- /** Voice callback function names */
1285
+ /** Voice callback function names @internal */
1143
1286
  export declare const VOICE_CALLBACKS: readonly [
1144
1287
  "ice",
1145
1288
  "ace",
@@ -1147,7 +1290,7 @@ export declare const VOICE_CALLBACKS: readonly [
1147
1290
  "dice",
1148
1291
  "notify"
1149
1292
  ];
1150
- /** Notification-only events (don't require SVAML response) */
1293
+ /** Notification-only events (don't require SVAML response) @internal */
1151
1294
  export declare const NOTIFICATION_EVENTS: readonly [
1152
1295
  "dice",
1153
1296
  "notify"
@@ -1156,32 +1299,39 @@ export type VoiceCallback = (typeof VOICE_CALLBACKS)[number];
1156
1299
  export type NotificationEvent = (typeof NOTIFICATION_EVENTS)[number];
1157
1300
  /**
1158
1301
  * Check if a function name is a voice callback
1302
+ * @internal
1159
1303
  */
1160
1304
  export declare function isVoiceCallback(functionName: string): functionName is VoiceCallback;
1161
1305
  /**
1162
1306
  * Check if a function is a notification-only event
1307
+ * @internal
1163
1308
  */
1164
1309
  export declare function isNotificationEvent(functionName: string): functionName is NotificationEvent;
1165
1310
  /**
1166
1311
  * Extract function name from request path or body
1312
+ * @internal
1167
1313
  */
1168
1314
  export declare function extractFunctionName(path: string, body?: {
1169
1315
  event?: string;
1170
1316
  }): string;
1171
1317
  /**
1172
1318
  * Generate unique request ID
1319
+ * @internal
1173
1320
  */
1174
1321
  export declare function generateRequestId(): string;
1175
1322
  /**
1176
1323
  * Format SVAML response for voice callbacks
1324
+ * @internal
1177
1325
  */
1178
1326
  export declare function formatSvamlResponse(result: unknown, functionName: string): FormattedResponse;
1179
1327
  /**
1180
1328
  * Format custom endpoint response
1329
+ * @internal
1181
1330
  */
1182
1331
  export declare function formatCustomResponse(result: unknown): FormattedResponse;
1183
1332
  /**
1184
1333
  * Validate voice callback request
1334
+ * @internal
1185
1335
  */
1186
1336
  export declare function validateVoiceRequest(body: unknown): {
1187
1337
  valid: boolean;
@@ -1193,22 +1343,27 @@ export declare function validateVoiceRequest(body: unknown): {
1193
1343
  *
1194
1344
  * Note: Call-specific data like callId is available on the callback event data,
1195
1345
  * not on the context object.
1346
+ * @internal
1196
1347
  */
1197
1348
  export declare function buildBaseContext(req: Request, config?: Partial<FunctionConfig>): FunctionContext;
1198
1349
  /**
1199
1350
  * Handle voice callback execution
1351
+ * @internal
1200
1352
  */
1201
1353
  export declare function handleVoiceCallback(functionName: string, userFunction: SinchFunction, context: FunctionContext, callbackData: unknown, logger?: (...args: unknown[]) => void): Promise<FormattedResponse>;
1202
1354
  /**
1203
1355
  * Handle custom endpoint execution
1356
+ * @internal
1204
1357
  */
1205
1358
  export declare function handleCustomEndpoint(functionName: string, userFunction: SinchFunction, context: FunctionContext, request: FunctionRequest, logger?: (...args: unknown[]) => void): Promise<FormattedResponse>;
1206
1359
  /**
1207
1360
  * Create and configure Express app with standard middleware
1361
+ * @internal
1208
1362
  */
1209
1363
  export declare function createApp(options?: AppOptions): Express;
1210
1364
  /**
1211
1365
  * Setup the main request handler
1366
+ * @internal
1212
1367
  */
1213
1368
  export declare function setupRequestHandler(app: Express, options?: RequestHandlerOptions): void;
1214
1369
  export interface SinchClients {
@@ -1233,83 +1388,868 @@ export declare function getSinchClients(): SinchClients;
1233
1388
  */
1234
1389
  export declare function resetSinchClients(): void;
1235
1390
  /**
1236
- * Simple template renderer for HTML files
1237
- * Replaces {{variableName}} placeholders with actual values
1391
+ * ElevenLabs API Models for Sinch Functions
1392
+ *
1393
+ * TypeScript interfaces matching the C# models for ElevenLabs integration.
1394
+ */
1395
+ /**
1396
+ * Options for initiating an outbound call via ElevenLabs
1397
+ */
1398
+ export interface ElevenLabsCallOptions {
1399
+ /** The ElevenLabs agent ID to use for the call */
1400
+ agentId: string;
1401
+ /** The phone number to call (E.164 format) */
1402
+ toNumber: string;
1403
+ /** The caller ID to display (E.164 format) */
1404
+ fromNumber: string;
1405
+ /** Dynamic variables to pass to the agent */
1406
+ dynamicVariables?: Record<string, string>;
1407
+ }
1408
+ /**
1409
+ * Response from ElevenLabs outbound call API
1410
+ */
1411
+ export interface ElevenLabsOutboundCallResponse {
1412
+ call_id: string;
1413
+ agent_id: string;
1414
+ customer_phone_number: string;
1415
+ agent_phone_number?: string;
1416
+ status: string;
1417
+ }
1418
+ /**
1419
+ * Conversation details from ElevenLabs
1420
+ */
1421
+ export interface ElevenLabsConversationDetails {
1422
+ conversationId: string;
1423
+ agentId: string;
1424
+ status: string;
1425
+ metadata?: ConversationMetadata;
1426
+ transcript?: TranscriptMessage[];
1427
+ analysis?: ConversationAnalysis;
1428
+ }
1429
+ /**
1430
+ * Call metadata
1431
+ */
1432
+ export interface ConversationMetadata {
1433
+ callDurationSeconds?: number;
1434
+ startTime?: Date;
1435
+ endTime?: Date;
1436
+ }
1437
+ /**
1438
+ * A single transcript message
1439
+ */
1440
+ export interface TranscriptMessage {
1441
+ role: "user" | "agent";
1442
+ message: string;
1443
+ timeInCallSeconds?: number;
1444
+ }
1445
+ /**
1446
+ * Conversation analysis results
1447
+ */
1448
+ export interface ConversationAnalysis {
1449
+ summary?: string;
1450
+ customData?: Record<string, unknown>;
1451
+ }
1452
+ /**
1453
+ * Options for auto-configuring ElevenLabs with Sinch SIP trunk.
1454
+ * Matches the C# ElevenLabsAutoConfigOptions.
1455
+ */
1456
+ export interface ElevenLabsAutoConfigOptions {
1457
+ /** The ElevenLabs agent ID to configure */
1458
+ agentId: string;
1459
+ /** Sinch phone number in E.164 format (e.g. +15551234567) */
1460
+ phoneNumber: string;
1461
+ /** SIP trunk address (e.g. "use1.vp.sip.sinch.com") */
1462
+ sipAddress: string;
1463
+ /** SIP trunk username (VOICE_APPLICATION_KEY) */
1464
+ sipUsername: string;
1465
+ /** SIP trunk password (VOICE_APPLICATION_SECRET) */
1466
+ sipPassword: string;
1467
+ /** Base URL for webhook callbacks. If not provided, webhooks won't be configured */
1468
+ webhookBaseUrl?: string;
1469
+ /** Function name used as label in ElevenLabs (default: "Sinch Function") */
1470
+ functionName?: string;
1471
+ }
1472
+ /**
1473
+ * Result of auto-configuration
1238
1474
  */
1239
- export declare class TemplateRender {
1475
+ export interface ElevenLabsAutoConfigResult {
1476
+ success: boolean;
1477
+ phoneNumberId?: string;
1478
+ phoneNumber?: string;
1479
+ sipAddress?: string;
1480
+ agentId?: string;
1481
+ error?: string;
1482
+ }
1483
+ /**
1484
+ * Client for interacting with ElevenLabs Conversational AI
1485
+ */
1486
+ export declare class ElevenLabsClient {
1487
+ private readonly apiKey;
1488
+ constructor(apiKey?: string);
1489
+ private get authHeaders();
1490
+ /**
1491
+ * Initiate an outbound call to a phone number using an ElevenLabs agent
1492
+ */
1493
+ makeCall(options: ElevenLabsCallOptions): Promise<ElevenLabsOutboundCallResponse>;
1494
+ /**
1495
+ * Get conversation details including transcript and analysis
1496
+ */
1497
+ getConversationDetails(conversationId: string): Promise<ElevenLabsConversationDetails>;
1498
+ /**
1499
+ * Auto-configure ElevenLabs with Sinch SIP trunk.
1500
+ *
1501
+ * Step 1: Get or import phone number with SIP trunk config
1502
+ * Step 2: Configure agent conversation-init webhook
1503
+ *
1504
+ * Called by tryAutoConfigureAsync (the orchestrator that reads env vars).
1505
+ */
1506
+ autoConfigureAsync(options: ElevenLabsAutoConfigOptions): Promise<ElevenLabsAutoConfigResult>;
1507
+ /**
1508
+ * Check if phone number already exists in ElevenLabs; create or update it.
1509
+ * Matches C# GetOrImportPhoneNumberAsync.
1510
+ */
1511
+ private getOrImportPhoneNumber;
1512
+ /**
1513
+ * Update phone number with agent association and SIP trunk config.
1514
+ * Matches C# UpdatePhoneNumberConfigAsync.
1515
+ */
1516
+ private updatePhoneNumberConfig;
1517
+ /**
1518
+ * Configure agent webhook for conversation-init events.
1519
+ * Matches C# ConfigureAgentWebhooksAsync.
1520
+ */
1521
+ private configureAgentWebhooks;
1522
+ /**
1523
+ * Map API response to our interface
1524
+ */
1525
+ private mapConversationResponse;
1526
+ }
1527
+ /**
1528
+ * Create an ElevenLabs client with the default API key
1529
+ */
1530
+ export declare function createElevenLabsClient(apiKey?: string): ElevenLabsClient;
1531
+ /**
1532
+ * ElevenLabs Webhook Models for Sinch Functions
1533
+ *
1534
+ * TypeScript interfaces for ElevenLabs webhook payloads.
1535
+ */
1536
+ /**
1537
+ * Conversation initialization request from ElevenLabs
1538
+ * Sent when an inbound call is received
1539
+ */
1540
+ export interface ConversationInitRequest {
1541
+ /** The agent ID handling the call */
1542
+ agent_id: string;
1543
+ /** The caller's phone number */
1544
+ caller_id?: string;
1545
+ /** The called number */
1546
+ called_number?: string;
1547
+ /** SIP call ID */
1548
+ call_sid?: string;
1549
+ }
1550
+ /**
1551
+ * Response for conversation initialization
1552
+ * Allows customizing the conversation for this specific caller
1553
+ */
1554
+ export interface ConversationInitResponse {
1555
+ /** Dynamic variables to use in the conversation */
1556
+ dynamic_variables?: Record<string, string>;
1557
+ /** Override agent configuration for this call */
1558
+ conversation_config_override?: ConversationConfigOverride;
1559
+ }
1560
+ /**
1561
+ * Configuration override for a specific conversation
1562
+ */
1563
+ export interface ConversationConfigOverride {
1564
+ agent?: AgentOverride;
1565
+ tts?: TtsOverride;
1566
+ turn?: TurnOverride;
1567
+ }
1568
+ /**
1569
+ * Agent-level configuration override
1570
+ */
1571
+ export interface AgentOverride {
1572
+ /** Custom first message for this call */
1573
+ first_message?: string;
1574
+ /** Language override (e.g., "en", "es") */
1575
+ language?: string;
1576
+ /** Custom prompt override */
1577
+ prompt?: string;
1578
+ }
1579
+ /**
1580
+ * Text-to-speech configuration override
1581
+ */
1582
+ export interface TtsOverride {
1583
+ /** Voice ID to use */
1584
+ voice_id?: string;
1585
+ /** Voice settings */
1586
+ voice_settings?: {
1587
+ stability?: number;
1588
+ similarity_boost?: number;
1589
+ };
1590
+ }
1591
+ /**
1592
+ * Turn-taking configuration override
1593
+ */
1594
+ export interface TurnOverride {
1595
+ /** Silence threshold in milliseconds */
1596
+ silence_threshold_ms?: number;
1597
+ }
1598
+ /**
1599
+ * Post-call webhook payload from ElevenLabs
1600
+ */
1601
+ export interface ElevenLabsPostCallWebhook {
1602
+ type: "post_call_transcription";
1603
+ event_timestamp: string;
1604
+ data: ConversationData;
1605
+ }
1606
+ /**
1607
+ * Conversation data in post-call webhook
1608
+ */
1609
+ export interface ConversationData {
1610
+ agent_id: string;
1611
+ conversation_id: string;
1612
+ status: string;
1613
+ user_id?: string;
1614
+ transcript: TranscriptTurn[];
1615
+ metadata: WebhookConversationMetadata;
1616
+ analysis?: WebhookConversationAnalysis;
1617
+ }
1618
+ /**
1619
+ * A single turn in the transcript
1620
+ */
1621
+ export interface TranscriptTurn {
1622
+ role: "user" | "agent";
1623
+ message: string;
1624
+ time_in_call_secs: number;
1625
+ }
1626
+ /**
1627
+ * Conversation metadata in webhook
1628
+ */
1629
+ export interface WebhookConversationMetadata {
1630
+ start_time_unix_secs: number;
1631
+ call_duration_secs: number;
1632
+ cost?: number;
1633
+ termination_reason?: string;
1634
+ }
1635
+ /**
1636
+ * Conversation analysis in webhook
1637
+ */
1638
+ export interface WebhookConversationAnalysis {
1639
+ evaluation_criteria_results?: EvaluationCriteriaResult[];
1640
+ data_collection_results?: DataCollectionResult[];
1641
+ call_successful?: boolean;
1642
+ transcript_summary?: string;
1643
+ }
1644
+ /**
1645
+ * Result of an evaluation criteria check
1646
+ */
1647
+ export interface EvaluationCriteriaResult {
1648
+ criteria_id: string;
1649
+ result: "success" | "failure" | "unknown";
1650
+ rationale?: string;
1651
+ }
1652
+ /**
1653
+ * Result of data collection
1654
+ */
1655
+ export interface DataCollectionResult {
1656
+ data_collection_id: string;
1657
+ value: string;
1658
+ json_schema?: Record<string, unknown>;
1659
+ rationale?: string;
1660
+ }
1661
+ /**
1662
+ * Post-call audio webhook payload
1663
+ */
1664
+ export interface ElevenLabsPostCallAudioWebhook {
1665
+ type: "post_call_audio";
1666
+ event_timestamp: string;
1667
+ data: {
1668
+ conversation_id: string;
1669
+ agent_id: string;
1670
+ /** Base64-encoded MP3 audio */
1671
+ audio_base64: string;
1672
+ };
1673
+ }
1674
+ /**
1675
+ * Call initiation failure webhook
1676
+ */
1677
+ export interface ElevenLabsCallInitiationFailureWebhook {
1678
+ type: "call_initiation_failure";
1679
+ event_timestamp: string;
1680
+ data: {
1681
+ agent_id: string;
1682
+ customer_phone_number: string;
1683
+ failure_reason: string;
1684
+ metadata?: Record<string, unknown>;
1685
+ };
1686
+ }
1687
+ /**
1688
+ * Union type for all ElevenLabs webhook types
1689
+ */
1690
+ export type ElevenLabsWebhook = ElevenLabsPostCallWebhook | ElevenLabsPostCallAudioWebhook | ElevenLabsCallInitiationFailureWebhook;
1691
+ /**
1692
+ * Base controller for handling ElevenLabs webhooks
1693
+ *
1694
+ * @example
1695
+ * ```typescript
1696
+ * class MyElevenLabsHandler extends ElevenLabsController {
1697
+ * async handleConversationInit(request: ConversationInitRequest): Promise<ConversationInitResponse> {
1698
+ * // Customize the conversation based on caller
1699
+ * return {
1700
+ * dynamic_variables: {
1701
+ * customerName: await lookupCustomer(request.caller_id)
1702
+ * }
1703
+ * };
1704
+ * }
1705
+ *
1706
+ * async handlePostCall(webhook: ElevenLabsPostCallWebhook): Promise<void> {
1707
+ * // Save transcript to database
1708
+ * await saveTranscript(webhook.data);
1709
+ * }
1710
+ * }
1711
+ * ```
1712
+ */
1713
+ export declare abstract class ElevenLabsController {
1714
+ /**
1715
+ * Handle conversation initialization webhook
1716
+ * Called when an inbound call is received - allows customizing the conversation
1717
+ *
1718
+ * @param request - The conversation init request with caller info
1719
+ * @returns Response with dynamic variables and/or config overrides
1720
+ */
1721
+ handleConversationInit(request: ConversationInitRequest): Promise<ConversationInitResponse>;
1722
+ /**
1723
+ * Handle post-call webhook with transcript and analysis
1724
+ *
1725
+ * @param webhook - The post-call webhook payload
1726
+ */
1727
+ handlePostCall(webhook: ElevenLabsPostCallWebhook): Promise<void>;
1728
+ /**
1729
+ * Handle post-call audio webhook with recording
1730
+ *
1731
+ * @param webhook - The audio webhook with base64-encoded MP3
1732
+ */
1733
+ handlePostCallAudio(webhook: ElevenLabsPostCallAudioWebhook): Promise<void>;
1734
+ /**
1735
+ * Handle call initiation failure webhook
1736
+ *
1737
+ * @param webhook - The failure webhook with error details
1738
+ */
1739
+ handleCallInitiationFailure(webhook: ElevenLabsCallInitiationFailureWebhook): Promise<void>;
1240
1740
  /**
1241
- * Load and render an HTML template with variables
1242
- * @param templatePath - Path to the HTML template file
1243
- * @param variables - Object containing variables to replace in template
1244
- * @returns Rendered HTML string
1741
+ * Express route handler for conversation init endpoint
1742
+ * Mount at: POST /elevenlabs/conversation-init
1245
1743
  */
1246
- static render(templatePath: string, variables?: Record<string, any>): string;
1744
+ getConversationInitHandler(): (req: Request, res: Response) => Promise<void>;
1247
1745
  /**
1248
- * Get the absolute path to a template file relative to the current directory
1249
- * @param templateName - Name of the template file (e.g., 'index.html')
1250
- * @param baseDir - Base directory to search from (defaults to cwd)
1251
- * @returns Absolute path to the template file
1746
+ * Express route handler for webhook endpoint
1747
+ * Mount at: POST /elevenlabs/webhook
1748
+ * Handles all webhook types based on the 'type' field
1252
1749
  */
1253
- static getTemplatePath(templateName: string, baseDir?: string): string;
1750
+ getWebhookHandler(): (req: Request, res: Response) => Promise<void>;
1254
1751
  }
1255
1752
  /**
1256
- * Version extractor utility for reading template versions from README.md files
1753
+ * Try to auto-configure ElevenLabs from environment variables.
1754
+ * Returns null if ELEVENLABS_AUTO_CONFIGURE is not "true".
1755
+ *
1756
+ * @param webhookUrl - Base URL for webhook callbacks (must be HTTPS in production)
1757
+ * @param functionName - Optional name for labeling in ElevenLabs (max 100 chars)
1758
+ * @param sinchPhoneNumber - Optional phone number override (skips auto-discovery)
1257
1759
  */
1258
- export declare class VersionExtractor {
1760
+ export declare function tryAutoConfigureAsync(webhookUrl: string, functionName?: string, sinchPhoneNumber?: string): Promise<ElevenLabsAutoConfigResult | null>;
1761
+ /**
1762
+ * @deprecated Use `tryAutoConfigureAsync` directly. This class wrapper is kept for backwards compatibility.
1763
+ */
1764
+ export declare class ElevenLabsAutoConfigurator {
1765
+ static tryAutoConfigureAsync: typeof tryAutoConfigureAsync;
1766
+ }
1767
+ /**
1768
+ * ElevenLabs State Management for Sinch Functions
1769
+ *
1770
+ * Singleton to store auto-configuration results for subsequent calls.
1771
+ */
1772
+ /**
1773
+ * State for ElevenLabs configuration
1774
+ */
1775
+ export interface ElevenLabsStateData {
1776
+ /** Phone number ID from Sinch */
1777
+ phoneNumberId?: string;
1778
+ /** The phone number (E.164 format) */
1779
+ phoneNumber?: string;
1780
+ /** The ElevenLabs agent ID */
1781
+ agentId?: string;
1782
+ /** SIP address for the agent */
1783
+ sipAddress?: string;
1784
+ /** Whether auto-configuration has been completed */
1785
+ isConfigured: boolean;
1786
+ /** Timestamp of last configuration */
1787
+ configuredAt?: Date;
1788
+ }
1789
+ declare class ElevenLabsStateManager {
1790
+ private state;
1259
1791
  /**
1260
- * Extract version from README.md file in the template directory
1261
- * Looks for "Template Version: X.X.X" pattern in the last few lines
1262
- * @param templateDir - Path to the template directory containing README.md
1263
- * @returns Version string or default fallback
1792
+ * Get the current state
1264
1793
  */
1265
- static getTemplateVersion(templateDir?: string): string;
1794
+ getState(): Readonly<ElevenLabsStateData>;
1795
+ /**
1796
+ * Check if ElevenLabs is configured
1797
+ */
1798
+ isConfigured(): boolean;
1799
+ /**
1800
+ * Update state with auto-configuration results
1801
+ */
1802
+ setConfigured(data: Omit<ElevenLabsStateData, "isConfigured" | "configuredAt">): void;
1803
+ /**
1804
+ * Clear the configuration state
1805
+ */
1806
+ clear(): void;
1807
+ /**
1808
+ * Get the phone number ID for making calls
1809
+ */
1810
+ getPhoneNumberId(): string | undefined;
1811
+ /**
1812
+ * Get the SIP address for connecting to the agent
1813
+ */
1814
+ getSipAddress(): string | undefined;
1815
+ /**
1816
+ * Get the configured agent ID
1817
+ */
1818
+ getAgentId(): string | undefined;
1266
1819
  }
1267
- export interface DefaultEndpointOptions {
1268
- serviceName?: string;
1269
- companyName?: string;
1270
- templateVersion?: string;
1271
- availableEndpoints?: Record<string, string>;
1820
+ /**
1821
+ * Singleton instance of ElevenLabs state
1822
+ */
1823
+ export declare const ElevenLabsState: ElevenLabsStateManager;
1824
+ /**
1825
+ * Message inbound event from Conversation API
1826
+ */
1827
+ export type MessageInboundEvent = Conversation.MessageInboundEvent;
1828
+ /**
1829
+ * Contact message content
1830
+ */
1831
+ export type ContactMessage = Conversation.ContactMessage;
1832
+ /**
1833
+ * Media properties type (URL, thumbnail, filename)
1834
+ */
1835
+ export type MediaProperties = Conversation.MediaProperties;
1836
+ /**
1837
+ * Location message item type (coordinates, title, label)
1838
+ */
1839
+ export type LocationMessageItem = Conversation.LocationMessageItem;
1840
+ /**
1841
+ * Get the text content from an inbound message
1842
+ */
1843
+ export declare function getText(event: MessageInboundEvent): string | undefined;
1844
+ /**
1845
+ * Get media content from an inbound message (images, videos, files)
1846
+ */
1847
+ export declare function getMedia(event: MessageInboundEvent): MediaProperties | undefined;
1848
+ /**
1849
+ * Get postback data from a button/quick reply click
1850
+ */
1851
+ export declare function getPostbackData(event: MessageInboundEvent): string | undefined;
1852
+ /**
1853
+ * Get the contact ID of the sender
1854
+ */
1855
+ export declare function getContactId(event: MessageInboundEvent): string | undefined;
1856
+ /**
1857
+ * Get the conversation ID (for non-DISPATCH mode apps)
1858
+ */
1859
+ export declare function getConversationId(event: MessageInboundEvent): string | undefined;
1860
+ /**
1861
+ * Get the channel name (SMS, WHATSAPP, MESSENGER, etc.)
1862
+ */
1863
+ export declare function getChannel(event: MessageInboundEvent): string | undefined;
1864
+ /**
1865
+ * Get the channel-specific identity (phone number, PSID, etc.)
1866
+ * This is the sender's identity (FROM)
1867
+ */
1868
+ export declare function getIdentity(event: MessageInboundEvent): string | undefined;
1869
+ /**
1870
+ * Get the destination number that the contact sent the message TO.
1871
+ * For SMS/MMS, this is your Sinch number that received the message.
1872
+ * Used automatically by reply() to set SMS_SENDER when replying.
1873
+ */
1874
+ export declare function getTo(event: MessageInboundEvent): string | undefined;
1875
+ /**
1876
+ * Get location data if the message contains a location
1877
+ */
1878
+ export declare function getLocation(event: MessageInboundEvent): LocationMessageItem | undefined;
1879
+ /**
1880
+ * Check if the message is a text message
1881
+ */
1882
+ export declare function isTextMessage(event: MessageInboundEvent): boolean;
1883
+ /**
1884
+ * Check if the message is a media message
1885
+ */
1886
+ export declare function isMediaMessage(event: MessageInboundEvent): boolean;
1887
+ /**
1888
+ * Check if the message is a button/quick reply response
1889
+ */
1890
+ export declare function isPostback(event: MessageInboundEvent): boolean;
1891
+ /**
1892
+ * Extension helper object with all methods bound to an event
1893
+ */
1894
+ export declare function createMessageHelper(event: MessageInboundEvent): {
1895
+ getText: () => string | undefined;
1896
+ getMedia: () => Conversation.MediaProperties | undefined;
1897
+ getPostbackData: () => string | undefined;
1898
+ getContactId: () => string | undefined;
1899
+ getConversationId: () => string | undefined;
1900
+ getChannel: () => string | undefined;
1901
+ getIdentity: () => string | undefined;
1902
+ getTo: () => string | undefined;
1903
+ getLocation: () => Conversation.LocationMessageItem | undefined;
1904
+ isTextMessage: () => boolean;
1905
+ isMediaMessage: () => boolean;
1906
+ isPostback: () => boolean;
1907
+ };
1908
+ /**
1909
+ * Channel type for Conversation API
1910
+ */
1911
+ export type ConversationChannel = "SMS" | "WHATSAPP" | "MESSENGER" | "VIBER" | "RCS" | "INSTAGRAM" | "MMS" | "LINE" | "KAKAOTALK" | "TELEGRAM" | "WECHAT" | "APPLEBC" | "GOOGLEBM" | string;
1912
+ /**
1913
+ * Simplified send message request type that works with SDK
1914
+ */
1915
+ export interface SendMessageRequest {
1916
+ app_id: string;
1917
+ message: {
1918
+ text_message?: {
1919
+ text: string;
1920
+ };
1921
+ };
1922
+ recipient: {
1923
+ identified_by: {
1924
+ channel_identities: Array<{
1925
+ channel: ConversationChannel;
1926
+ identity: string;
1927
+ }>;
1928
+ };
1929
+ };
1930
+ channel_properties?: Record<string, string>;
1272
1931
  }
1273
- export interface HttpRequest {
1274
- method: string;
1275
- path: string;
1276
- query?: Record<string, any>;
1277
- headers?: Record<string, string>;
1278
- body?: any;
1279
- params?: Record<string, string>;
1932
+ /**
1933
+ * Create a text reply to an inbound message (replies on same channel).
1934
+ * Automatically sets SMS_SENDER channel property if sending to SMS.
1935
+ *
1936
+ * @param inbound - The inbound message event to reply to
1937
+ * @param text - The reply text
1938
+ * @param smsSender - Optional SMS sender number
1939
+ * @returns A SendMessageRequest ready to send
1940
+ *
1941
+ * @example
1942
+ * ```typescript
1943
+ * await context.conversation.messages.send(
1944
+ * textReply(inbound, "Thanks for your message!", config.FROM_NUMBER)
1945
+ * );
1946
+ * ```
1947
+ */
1948
+ export declare function textReply(inbound: MessageInboundEvent, text: string, smsSender?: string): SendMessageRequest;
1949
+ /**
1950
+ * Create an SMS message to a phone number.
1951
+ *
1952
+ * @param appId - The Conversation API app ID
1953
+ * @param phoneNumber - Phone number in E.164 format (e.g., +15551234567)
1954
+ * @param text - Message text
1955
+ * @param smsSender - SMS sender number (required for SMS channel)
1956
+ */
1957
+ export declare function createSms(appId: string, phoneNumber: string, text: string, smsSender?: string): SendMessageRequest;
1958
+ /**
1959
+ * Create a WhatsApp message to a phone number.
1960
+ *
1961
+ * @param appId - The Conversation API app ID
1962
+ * @param phoneNumber - Phone number in E.164 format (e.g., +15551234567)
1963
+ * @param text - Message text
1964
+ */
1965
+ export declare function createWhatsApp(appId: string, phoneNumber: string, text: string): SendMessageRequest;
1966
+ /**
1967
+ * Create a Facebook Messenger message.
1968
+ *
1969
+ * @param appId - The Conversation API app ID
1970
+ * @param psid - The Page-Scoped ID of the user
1971
+ * @param text - Message text
1972
+ */
1973
+ export declare function createMessenger(appId: string, psid: string, text: string): SendMessageRequest;
1974
+ /**
1975
+ * Create a message for any channel.
1976
+ *
1977
+ * @param appId - The Conversation API app ID
1978
+ * @param channel - Channel name (SMS, WHATSAPP, MESSENGER, VIBER, etc.)
1979
+ * @param identity - Channel-specific identity (phone number, PSID, etc.)
1980
+ * @param text - Message text
1981
+ * @param smsSender - SMS sender number (only used for SMS channel)
1982
+ */
1983
+ export declare function createChannelMessage(appId: string, channel: string, identity: string, text: string, smsSender?: string): SendMessageRequest;
1984
+ /**
1985
+ * ConversationMessage namespace for static helpers
1986
+ */
1987
+ export declare const ConversationMessage: {
1988
+ textReply: typeof textReply;
1989
+ createSms: typeof createSms;
1990
+ createWhatsApp: typeof createWhatsApp;
1991
+ createMessenger: typeof createMessenger;
1992
+ createChannelMessage: typeof createChannelMessage;
1993
+ };
1994
+ /**
1995
+ * Configuration interface for the message builder
1996
+ */
1997
+ export interface MessageBuilderConfig {
1998
+ CONVERSATION_APP_ID?: string;
1999
+ FROM_NUMBER?: string;
1280
2000
  }
1281
- export interface HttpResponse {
1282
- statusCode: number;
1283
- headers: Record<string, string>;
1284
- body: any;
2001
+ /**
2002
+ * Fluent builder for creating Conversation API messages.
2003
+ *
2004
+ * @example
2005
+ * ```typescript
2006
+ * // Simple case - use static helper
2007
+ * await context.conversation.messages.send(
2008
+ * ConversationMessage.textReply(inbound, "Hello!")
2009
+ * );
2010
+ *
2011
+ * // Complex case - use builder
2012
+ * const msg = new ConversationMessageBuilder(config)
2013
+ * .fromInbound(inbound)
2014
+ * .text("Hello!")
2015
+ * .build();
2016
+ * await context.conversation.messages.send(msg);
2017
+ * ```
2018
+ */
2019
+ export declare class ConversationMessageBuilder {
2020
+ private config;
2021
+ private appId?;
2022
+ private channel?;
2023
+ private identity?;
2024
+ private conversationId?;
2025
+ private messageText?;
2026
+ /**
2027
+ * Create a new builder with configuration
2028
+ */
2029
+ constructor(config?: MessageBuilderConfig);
2030
+ /**
2031
+ * Pre-fill builder from an inbound message (for replies)
2032
+ */
2033
+ fromInbound(inbound: MessageInboundEvent): this;
2034
+ /**
2035
+ * Set the app ID (defaults to CONVERSATION_APP_ID from config)
2036
+ */
2037
+ setAppId(appId: string): this;
2038
+ /**
2039
+ * Set the recipient channel and identity
2040
+ *
2041
+ * @param channel - Channel name (SMS, WHATSAPP, MESSENGER, etc.)
2042
+ * @param identity - Channel-specific identity (phone number, PSID, etc.)
2043
+ */
2044
+ to(channel: string, identity: string): this;
2045
+ /**
2046
+ * Set the conversation ID (for non-DISPATCH mode apps)
2047
+ */
2048
+ setConversationId(conversationId: string): this;
2049
+ /**
2050
+ * Set a text message
2051
+ */
2052
+ text(text: string): this;
2053
+ /**
2054
+ * Build the SendMessageRequest.
2055
+ * Automatically sets SMS_SENDER from config if sending to SMS channel.
2056
+ *
2057
+ * @returns A SendMessageRequest ready to send via context.conversation.messages.send()
2058
+ */
2059
+ build(): SendMessageRequest;
2060
+ }
2061
+ /**
2062
+ * Create a new conversation message builder
2063
+ */
2064
+ export declare function createMessageBuilder(config?: MessageBuilderConfig): ConversationMessageBuilder;
2065
+ /**
2066
+ * Conversation API event types
2067
+ */
2068
+ export type MessageDeliveryEvent = Conversation.MessageDeliveryReceiptEvent;
2069
+ export type EventInboundEvent = Conversation.EventInbound;
2070
+ export type ConversationStartEvent = Conversation.ConversationStartEvent;
2071
+ export type ConversationStopEvent = Conversation.ConversationStopEvent;
2072
+ /**
2073
+ * Configuration for the conversation controller
2074
+ */
2075
+ export interface ConversationControllerConfig {
2076
+ CONVERSATION_APP_ID?: string;
2077
+ FROM_NUMBER?: string;
2078
+ VERBOSE?: string;
1285
2079
  }
1286
- export declare class DefaultEndpointHandler {
2080
+ /**
2081
+ * Base controller for handling Sinch Conversation API webhooks.
2082
+ *
2083
+ * Derived classes override the virtual handlers they need.
2084
+ *
2085
+ * @example
2086
+ * ```typescript
2087
+ * class MyConversationHandler extends ConversationController {
2088
+ * constructor(conversation: ConversationService, config: ConversationControllerConfig) {
2089
+ * super(conversation, config);
2090
+ * }
2091
+ *
2092
+ * async handleMessageInbound(event: MessageInboundEvent): Promise<void> {
2093
+ * const text = getText(event);
2094
+ * if (!text) return;
2095
+ *
2096
+ * // Reply using helper method
2097
+ * await this.conversation.messages.send({
2098
+ * sendMessageRequestBody: this.reply(event, "Thanks for your message!")
2099
+ * });
2100
+ * }
2101
+ * }
2102
+ * ```
2103
+ */
2104
+ export declare abstract class ConversationController {
2105
+ protected conversation?: ConversationService;
2106
+ protected config: ConversationControllerConfig;
2107
+ constructor(conversation: ConversationService | undefined, config?: ConversationControllerConfig);
2108
+ /**
2109
+ * MESSAGE_INBOUND - Called when a user sends a message.
2110
+ * Override this to handle incoming messages from users.
2111
+ */
2112
+ handleMessageInbound(event: MessageInboundEvent): Promise<void>;
2113
+ /**
2114
+ * MESSAGE_DELIVERY - Called when message delivery status updates.
2115
+ * Override this to track delivery receipts.
2116
+ */
2117
+ handleMessageDelivery(event: MessageDeliveryEvent): Promise<void>;
2118
+ /**
2119
+ * EVENT_INBOUND - Called for events like composing indicators.
2120
+ * Override this to handle typing indicators, read receipts, etc.
2121
+ */
2122
+ handleEventInbound(event: EventInboundEvent): Promise<void>;
2123
+ /**
2124
+ * CONVERSATION_START - Called when a conversation begins.
2125
+ * Override this to handle conversation initialization.
2126
+ */
2127
+ handleConversationStart(event: ConversationStartEvent): Promise<void>;
1287
2128
  /**
1288
- * Handle the default endpoint with content negotiation
1289
- * @param context - Function context with config and cache
1290
- * @param request - HTTP request object with method, path, query, headers, body, params
1291
- * @param options - Configuration options for the response
1292
- * @returns HTTP response object with statusCode, headers, and body
2129
+ * CONVERSATION_STOP - Called when a conversation ends.
2130
+ * Override this to handle conversation cleanup.
1293
2131
  */
1294
- static handle(context: FunctionContext, request: HttpRequest, options?: DefaultEndpointOptions): Promise<HttpResponse>;
2132
+ handleConversationStop(event: ConversationStopEvent): Promise<void>;
2133
+ /**
2134
+ * Gets the sender number from configuration (FROM_NUMBER).
2135
+ * Used for setting SMS_SENDER channel property when sending to SMS channel.
2136
+ */
2137
+ get fromNumber(): string | undefined;
2138
+ /**
2139
+ * Create a text reply to an inbound message.
2140
+ * Automatically sets SMS_SENDER from FROM_NUMBER config.
2141
+ */
2142
+ reply(inbound: MessageInboundEvent, text: string): SendMessageRequest;
2143
+ /**
2144
+ * Create a ConversationMessageBuilder for building messages with full control.
2145
+ */
2146
+ createMessage(): ConversationMessageBuilder;
2147
+ /**
2148
+ * Create a ConversationMessageBuilder pre-filled from an inbound message.
2149
+ */
2150
+ createReply(inbound: MessageInboundEvent): ConversationMessageBuilder;
2151
+ /**
2152
+ * Express route handler for the webhook endpoint.
2153
+ * Mount at: POST /conversation
2154
+ *
2155
+ * Routes to appropriate handler based on event type.
2156
+ * Uses manual JSON parsing as workaround for SDK issues with extra fields.
2157
+ */
2158
+ getWebhookHandler(): (req: Request, res: Response) => Promise<void>;
1295
2159
  }
1296
- /** @deprecated Import from '@sinch/voice' instead: `import type { Voice } from '@sinch/voice'` then use `Voice.IceRequest` */
2160
+ /**
2161
+ * Converts an E.164 phone number to local/national format.
2162
+ *
2163
+ * @param phoneNumber - The phone number in E.164 format (e.g., "+15551234567")
2164
+ * @param defaultRegion - The default region code (default: "US")
2165
+ * @returns The phone number in national format, or the original if conversion fails
2166
+ *
2167
+ * @example
2168
+ * ```typescript
2169
+ * toLocalPhoneNumber('+15551234567'); // Returns "(555) 123-4567"
2170
+ * toLocalPhoneNumber('+442071234567'); // Returns "020 7123 4567"
2171
+ * ```
2172
+ */
2173
+ export declare function toLocalPhoneNumber(phoneNumber: string, defaultRegion?: string): string;
2174
+ /**
2175
+ * Formats a phone number for display (adds dashes/spaces for readability)
2176
+ *
2177
+ * @param phoneNumber - Phone number in any format
2178
+ * @returns Formatted phone number
2179
+ */
2180
+ export declare function formatPhoneNumber(phoneNumber: string): string;
2181
+ /**
2182
+ * Helper methods for creating common error responses
2183
+ */
2184
+ export declare const VoiceErrorHelper: {
2185
+ /**
2186
+ * Create a standard error response that plays a message and hangs up
2187
+ *
2188
+ * @param message - Error message to speak
2189
+ * @param locale - Language locale (default: "en-US")
2190
+ * @returns SVAML response object
2191
+ */
2192
+ createErrorResponse(message: string, locale?: string): ReturnType<IceSvamlBuilder["build"]>;
2193
+ /**
2194
+ * Create a service unavailable response
2195
+ *
2196
+ * @param locale - Language locale (default: "en-US")
2197
+ * @returns SVAML response object
2198
+ */
2199
+ serviceUnavailable(locale?: string): ReturnType<IceSvamlBuilder["build"]>;
2200
+ /**
2201
+ * Create an invalid input response for PIE handlers
2202
+ *
2203
+ * @param locale - Language locale (default: "en-US")
2204
+ * @returns SVAML response object
2205
+ */
2206
+ invalidInput(locale?: string): ReturnType<PieSvamlBuilder["build"]>;
2207
+ /**
2208
+ * Create a timeout response for PIE handlers
2209
+ *
2210
+ * @param locale - Language locale (default: "en-US")
2211
+ * @returns SVAML response object
2212
+ */
2213
+ timeout(locale?: string): ReturnType<PieSvamlBuilder["build"]>;
2214
+ /**
2215
+ * Create a goodbye response that thanks the caller and hangs up
2216
+ *
2217
+ * @param locale - Language locale (default: "en-US")
2218
+ * @returns SVAML response object
2219
+ */
2220
+ goodbye(locale?: string): ReturnType<IceSvamlBuilder["build"]>;
2221
+ };
2222
+ /**
2223
+ * Formats duration in seconds to human-readable format
2224
+ *
2225
+ * @param seconds - Duration in seconds
2226
+ * @returns Formatted duration string (e.g., "2m 30s")
2227
+ */
2228
+ export declare function formatDuration(seconds: number): string;
2229
+ /**
2230
+ * Extracts the caller's phone number from CLI (Caller ID)
2231
+ *
2232
+ * @param cli - Caller ID string
2233
+ * @returns Normalized phone number
2234
+ */
2235
+ export declare function extractCallerNumber(cli: string | undefined): string | undefined;
2236
+ /** @deprecated Import from '@sinch/voice' instead: `import type { Voice } from '@sinch/voice'` then use `Voice.IceRequest` @internal */
1297
2237
  export type IceCallbackData = Voice.IceRequest;
1298
- /** @deprecated Import from '@sinch/voice' instead */
2238
+ /** @deprecated Import from '@sinch/voice' instead @internal */
1299
2239
  export type AceCallbackData = Voice.AceRequest;
1300
- /** @deprecated Import from '@sinch/voice' instead */
2240
+ /** @deprecated Import from '@sinch/voice' instead @internal */
1301
2241
  export type PieCallbackData = Voice.PieRequest;
1302
- /** @deprecated Import from '@sinch/voice' instead */
2242
+ /** @deprecated Import from '@sinch/voice' instead @internal */
1303
2243
  export type DiceCallbackData = Voice.DiceRequest;
1304
- /** @deprecated Import from '@sinch/voice' instead */
2244
+ /** @deprecated Import from '@sinch/voice' instead @internal */
1305
2245
  export type NotifyCallbackData = Voice.NotifyRequest;
1306
- /** @deprecated Import from '@sinch/voice' instead */
2246
+ /** @deprecated Import from '@sinch/voice' instead @internal */
1307
2247
  export type MenuResult = Voice.MenuResult;
1308
- /** @deprecated Import from '@sinch/voice' instead */
2248
+ /** @deprecated Import from '@sinch/voice' instead @internal */
1309
2249
  export type AmdResult = Voice.AnsweringMachineDetection;
1310
- /** @deprecated Import from '@sinch/voice' instead */
2250
+ /** @deprecated Import from '@sinch/voice' instead @internal */
1311
2251
  export type DisconnectReason = Voice.DiceReasonEnum;
1312
- /** @deprecated Import from '@sinch/voice' instead */
2252
+ /** @deprecated Import from '@sinch/voice' instead @internal */
1313
2253
  export type CallResult = Voice.ResultEnum;
1314
2254
  /**
1315
2255
  * Union type for all voice callback data
@@ -1320,6 +2260,8 @@ export type VoiceCallbackData = Voice.IceRequest | Voice.AceRequest | Voice.PieR
1320
2260
  *
1321
2261
  * Implements IFunctionCache using an in-memory Map with TTL support.
1322
2262
  * Data is lost when the process restarts.
2263
+ *
2264
+ * @internal Dev-only implementation — access cache via `context.cache`
1323
2265
  */
1324
2266
  export declare class LocalCache implements IFunctionCache {
1325
2267
  private cache;
@@ -1347,6 +2289,7 @@ export declare class LocalCache implements IFunctionCache {
1347
2289
  *
1348
2290
  * @param _projectId - Project ID (unused in local development)
1349
2291
  * @param _functionName - Function name (unused in local development)
2292
+ * @internal Dev-only factory — access cache via `context.cache`
1350
2293
  */
1351
2294
  export declare function createCacheClient(_projectId?: string, _functionName?: string): IFunctionCache;
1352
2295
  /**
@@ -1361,7 +2304,10 @@ export declare function createCacheClient(_projectId?: string, _functionName?: s
1361
2304
  * - ElevenLabs auto-configuration (when enabled)
1362
2305
  * - Stale webhook cleanup on connect
1363
2306
  * - Webhook cleanup on disconnect
2307
+ *
2308
+ * @internal Dev-only — used by `sinch functions dev`, not by user code
1364
2309
  */
2310
+ /** @internal */
1365
2311
  export declare class TunnelClient {
1366
2312
  private ws;
1367
2313
  private tunnelUrl;
@@ -1398,6 +2344,7 @@ export declare class TunnelClient {
1398
2344
  getTunnelUrl(): string | null;
1399
2345
  getIsConnected(): boolean;
1400
2346
  }
2347
+ /** @internal */
1401
2348
  export declare function getTunnelClient(localPort?: number): TunnelClient;
1402
2349
  /**
1403
2350
  * Secrets Loader for Local Development
@@ -1408,7 +2355,10 @@ export declare function getTunnelClient(localPort?: number): TunnelClient;
1408
2355
  *
1409
2356
  * Security: Only loads secrets that are declared in .env file (empty values)
1410
2357
  * In production, secrets are injected by the platform, so this is development-only.
2358
+ *
2359
+ * @internal Dev-only — used by the runtime dev server, not by user code
1411
2360
  */
2361
+ /** @internal */
1412
2362
  export declare class SecretsLoader {
1413
2363
  private SERVICE_NAME;
1414
2364
  private username;