@ada-cx/messaging-sdk 1.0.0-setup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +211 -0
  2. package/dist/client/ada-settings-reader.d.ts +10 -0
  3. package/dist/client/client-channel-handlers.d.ts +92 -0
  4. package/dist/client/client-errors.d.ts +7 -0
  5. package/dist/client/client-frame-constants.d.ts +41 -0
  6. package/dist/client/client-frame-runtime.d.ts +54 -0
  7. package/dist/client/client-host-runtime.d.ts +73 -0
  8. package/dist/client/client-types.d.ts +231 -0
  9. package/dist/client/client.d.ts +843 -0
  10. package/dist/client/config-helpers.d.ts +157 -0
  11. package/dist/client/constants.d.ts +61 -0
  12. package/dist/client/core-channel-test-harness.d.ts +47 -0
  13. package/dist/client/embed-interface.d.ts +172 -0
  14. package/dist/client/embed-lifecycle.d.ts +12 -0
  15. package/dist/client/fallback-html.d.ts +1 -0
  16. package/dist/client/frame-manager.d.ts +64 -0
  17. package/dist/client/frame-styles.d.ts +164 -0
  18. package/dist/client/frame-visibility.d.ts +53 -0
  19. package/dist/client/integration-manager.d.ts +73 -0
  20. package/dist/client/legacy-callback-adapter.d.ts +22 -0
  21. package/dist/client/mask-element.d.ts +19 -0
  22. package/dist/client/proactive/index.d.ts +5 -0
  23. package/dist/client/proactive/proactive-channel.d.ts +33 -0
  24. package/dist/client/proactive/proactive-runtime.d.ts +65 -0
  25. package/dist/client/proactive/proactive-utils.d.ts +51 -0
  26. package/dist/client/sdk-error-reporter.d.ts +22 -0
  27. package/dist/client/sdk-event-bus.d.ts +116 -0
  28. package/dist/client/service-worker-notifications.d.ts +1 -0
  29. package/dist/client/url-business-events.d.ts +19 -0
  30. package/dist/frame-channel/frame-channel.d.ts +64 -0
  31. package/dist/frame-channel/frame-child.d.ts +45 -0
  32. package/dist/frame-channel/index.d.ts +3 -0
  33. package/dist/frame-channel/types.d.ts +736 -0
  34. package/dist/helpers/rollout.d.ts +18 -0
  35. package/dist/host-telemetry.d.ts +15 -0
  36. package/dist/index.d.ts +8 -0
  37. package/dist/logger.d.ts +59 -0
  38. package/dist/mobile-webview-runtime.d.ts +122 -0
  39. package/dist/npm/build-info.d.cts +17 -0
  40. package/dist/npm/build-info.d.ts +17 -0
  41. package/dist/npm/index.cjs +276 -0
  42. package/dist/npm/index.cjs.map +1 -0
  43. package/dist/npm/index.d.cts +15 -0
  44. package/dist/npm/index.d.ts +9 -0
  45. package/dist/npm/index.js +270 -0
  46. package/dist/npm/index.js.map +1 -0
  47. package/dist/npm/loader.d.cts +120 -0
  48. package/dist/npm/loader.d.ts +120 -0
  49. package/dist/npm/testing.cjs +155 -0
  50. package/dist/npm/testing.cjs.map +1 -0
  51. package/dist/npm/testing.d.cts +39 -0
  52. package/dist/npm/testing.d.ts +39 -0
  53. package/dist/npm/testing.js +154 -0
  54. package/dist/npm/testing.js.map +1 -0
  55. package/dist/sdk-module-loader.d.ts +1 -0
  56. package/dist/shared-utils/clusters.d.ts +5 -0
  57. package/dist/shared-utils/csat.d.ts +116 -0
  58. package/dist/shared-utils/host-telemetry.d.ts +35 -0
  59. package/dist/shared-utils/index.d.ts +3 -0
  60. package/dist/voice/voice-manager.d.ts +120 -0
  61. package/package.json +77 -0
@@ -0,0 +1,736 @@
1
+ import type { HostTelemetryContext } from "../host-telemetry.js";
2
+ /**
3
+ * Frame channel message format.
4
+ *
5
+ * All postMessage payloads between the SDK and its child iframes
6
+ * are serialized as JSON using this shape.
7
+ */
8
+ export interface FrameMessage<T = unknown> {
9
+ /** Identifies the sender (e.g. "sdk", "core", "button") */
10
+ name: string;
11
+ /** Event type key */
12
+ type: string;
13
+ /** Event-specific data */
14
+ payload: T;
15
+ /** UUID for request/response correlation */
16
+ id?: string;
17
+ }
18
+ export type MetaFieldValue = string | number | boolean | null;
19
+ /** Reload-path response types allowed to acknowledge a durable persistence clear. */
20
+ export type ClearPersistenceAckResponseType = "core.reset.response" | "core.history.delete.response";
21
+ /** Button configuration from server-side client config */
22
+ export interface StartupConfigButton {
23
+ iconType: string;
24
+ iconPath: string;
25
+ textEnabled: boolean;
26
+ text: string;
27
+ /**
28
+ * BCP-47 tag of the language `text` is written in, which the launcher document
29
+ * declares so a reader pronounces it correctly. Absent on a snapshot cached by
30
+ * a native host before this field existed.
31
+ */
32
+ textLanguage?: string;
33
+ size: number;
34
+ backgroundColor: string | null;
35
+ }
36
+ /** Intro popup configuration from server-side client config */
37
+ export interface StartupConfigIntro {
38
+ responseId: string;
39
+ body: string;
40
+ delay: number;
41
+ duration: number | null;
42
+ style: "Text" | "Emoji";
43
+ paths: string[];
44
+ image?: {
45
+ url: string;
46
+ alt: string;
47
+ };
48
+ cta?: {
49
+ label: string;
50
+ url: string;
51
+ openInNewTab: boolean;
52
+ };
53
+ }
54
+ /** Fallback UI shown on outage-style full-page fallback states */
55
+ export interface StartupConfigFallbackUi {
56
+ icon: {
57
+ isDefault: boolean;
58
+ image: string | null;
59
+ };
60
+ message: string | Record<string, string>;
61
+ links: Array<{
62
+ label: string;
63
+ url: string;
64
+ }> | Record<string, Array<{
65
+ label: string;
66
+ url: string;
67
+ }>>;
68
+ }
69
+ /** Proactive conversation entry (URL-triggered, template or direct) */
70
+ export interface StartupConfigProactiveConversation {
71
+ key?: string;
72
+ /** Lowest value wins when several URL-triggered proactives match. */
73
+ order?: number | null;
74
+ messages: Record<string, string[]>;
75
+ is_template: boolean;
76
+ params?: Record<string, string>;
77
+ modality_config?: {
78
+ chat?: {
79
+ active: boolean;
80
+ url_trigger_conditions?: Array<{
81
+ type: string;
82
+ value: string;
83
+ }>;
84
+ delay?: number;
85
+ duration?: number;
86
+ frequency?: "always" | "session" | "user";
87
+ schedule_start?: string | null;
88
+ schedule_end?: string | null;
89
+ };
90
+ };
91
+ /** Per-language branded images for the pre-chat proactive bubble. */
92
+ images?: Record<string, Array<{
93
+ url: string;
94
+ alt: string;
95
+ }>>;
96
+ /** Branded call-to-action buttons for the pre-chat proactive bubble. */
97
+ ctas?: Array<{
98
+ label: string;
99
+ url: string;
100
+ openInNewTab: boolean;
101
+ }>;
102
+ }
103
+ /**
104
+ * Serializable snapshot of client config broadcast from core to SDK
105
+ * immediately after prepare(). Used by the SDK to drive button/intro/proactive
106
+ * behavior without additional API calls.
107
+ */
108
+ export interface StartupConfig {
109
+ chatEnabled: boolean;
110
+ tintColor: string;
111
+ button: StartupConfigButton | null;
112
+ intro: StartupConfigIntro | null;
113
+ fallbackUi: StartupConfigFallbackUi | null;
114
+ advancedColorsEnabled: boolean;
115
+ textOverAccentColor: string | null;
116
+ proactiveConversations: Record<string, StartupConfigProactiveConversation> | null;
117
+ features: Record<string, boolean>;
118
+ /** Server-provided custom schemes the host SDK may authorize for navigation. */
119
+ allowedProtocols: string[];
120
+ }
121
+ /**
122
+ * The **only** keys a native host may write to device storage — the canonical
123
+ * allowlist the iOS and Android persistence hooks enforce.
124
+ *
125
+ * An allowlist, not a denylist: a denylist re-opens the hole the first time a new
126
+ * sensitive key appears upstream, whereas an unrecognized key here simply is not
127
+ * persisted. Today the cached payload is the `core.startup.config` snapshot (branding
128
+ * and feature config, no tokens), so nothing is actually stripped — the point is that
129
+ * widening what gets cached cannot silently start persisting chatter content.
130
+ *
131
+ * `__ada_cached_at__` is load-bearing, not incidental: it is what bounds the hydration
132
+ * snapshot to a 10-minute TTL. Dropping it does not disable rehydration — `bridge-client`
133
+ * accepts an undated snapshot for back-compat — it removes the bound, so stale state
134
+ * hydrates indefinitely. iOS and Android keep their own `cachedAt` timestamp as well, so
135
+ * the real exposure is where the host owns persistence (React Native).
136
+ *
137
+ * The native implementations and React Native host-persistence documentation mirror
138
+ * this list and are pinned to it by `native-persistence-allowlist.test.ts`. Swift and
139
+ * Kotlin cannot import it, while React Native delegates persistence to the host app;
140
+ * silently diverging at any of those boundaries is the failure this prevents.
141
+ */
142
+ export declare const PERSISTABLE_NATIVE_STATE_KEYS: readonly ["advancedColorsEnabled", "allowedProtocols", "button", "chatEnabled", "fallbackUi", "features", "intro", "proactiveConversations", "textOverAccentColor", "tintColor", "__ada_cached_at__"];
143
+ /** Names of the frames the SDK can mount */
144
+ export type FrameName = "core" | "button" | "intro";
145
+ /** Map of frame names to their iframe elements (once mounted) */
146
+ export type FrameRegistry = Partial<Record<FrameName, HTMLIFrameElement>>;
147
+ /**
148
+ * SDK → Frame events.
149
+ * Events sent from the SDK to child iframes.
150
+ */
151
+ export interface SdkToFrameEvents {
152
+ /** Deliver client config to the core frame after mount */
153
+ "sdk.config.set": {
154
+ endpoint: string;
155
+ handle: string;
156
+ cluster?: string | null;
157
+ language?: string;
158
+ greeting?: string;
159
+ /** Legacy adaSettings.greeting Answer id, higher priority than an Intro. */
160
+ configuredGreetingResponseId?: string;
161
+ identityToken?: string;
162
+ greetingResponseId?: string | null;
163
+ /** Customer-hosted app frame URL; core enforces https-only and the per-handle origin allowlist. */
164
+ appUrl?: string;
165
+ /** When false, a failing custom appUrl does not fall back to the default app. */
166
+ appUrlFallback?: boolean;
167
+ metaFields?: Record<string, MetaFieldValue>;
168
+ hostTelemetry?: HostTelemetryContext;
169
+ styles?: Record<string, string>;
170
+ /** Build/runtime mode; customer testMode never changes infrastructure. */
171
+ mode?: "test" | "dev" | "prod";
172
+ /** Prevent cross-session history from being loaded */
173
+ privateMode?: boolean;
174
+ /**
175
+ * Legacy-compatible UA form factor at config-delivery time — the same fixed
176
+ * signal that decides whether the drawer opens full screen. Only the host
177
+ * page can measure this; a desktop widget frame is capped at 375px.
178
+ */
179
+ isMobileViewport?: boolean;
180
+ /** One-shot bootstrap flag to clear persisted chatter state before prepare(). */
181
+ clearPersistenceOnPrepare?: boolean;
182
+ /** Correlate a reset/deleteHistory clear across a replacement core frame. */
183
+ clearPersistenceAckRequestId?: string;
184
+ clearPersistenceAckResponseType?: ClearPersistenceAckResponseType;
185
+ /** Outgoing conversation buckets that the correlated clear must remove. */
186
+ clearPersistenceStorageModes?: Array<"normal" | "session" | "private">;
187
+ };
188
+ /** Request the frame to identify its trusted origin */
189
+ "sdk.origin.request": undefined;
190
+ /** Toggle visibility of the chat UI */
191
+ "sdk.visibility.set": {
192
+ isVisible: boolean;
193
+ /** Why the chat was hidden — drives ada:close_chat vs ada:minimize_chat. */
194
+ reason?: "close" | "minimize";
195
+ /**
196
+ * Internal soft-reset replay. Visibility is restored without granting the
197
+ * ordinary create-capable activation path; sdk.reset owns exact reactivation.
198
+ */
199
+ historyPreservingReset?: true;
200
+ };
201
+ /** Activate chat startup without changing UI visibility */
202
+ "sdk.activate": undefined;
203
+ /** Ask core to discover persisted chatter state after final SDK config is ready. */
204
+ "sdk.session.candidate.request": {
205
+ requestId: number;
206
+ };
207
+ /**
208
+ * Ask core to restore one server-confirmed live persisted chatter without
209
+ * creating or identifying a replacement session.
210
+ */
211
+ "sdk.session.resume": {
212
+ chatterToken: string;
213
+ requestId: number;
214
+ };
215
+ /** Reveal a drawer only for the exact existing-only resume that succeeded. */
216
+ "sdk.session.resume.visibility": {
217
+ chatterToken: string;
218
+ requestId: number;
219
+ isVisible: true;
220
+ };
221
+ /**
222
+ * Web Notification permission as seen from the HOST page origin.
223
+ *
224
+ * The widget runs in its own iframe origin, so `Notification.permission` read
225
+ * inside it is a different value from the one that actually governs the prompt.
226
+ * Only the SDK can report this truthfully.
227
+ */
228
+ "sdk.notifications.permission": {
229
+ permission: "default" | "granted" | "denied";
230
+ supported: boolean;
231
+ };
232
+ /** Reset the client session, optionally with new config */
233
+ "sdk.reset": {
234
+ greeting?: string | null;
235
+ greetingResponseId?: string | null;
236
+ language?: string;
237
+ identityToken?: string;
238
+ metaFields?: Record<string, MetaFieldValue>;
239
+ sensitiveMetaFields?: Record<string, MetaFieldValue>;
240
+ resetChatHistory?: boolean;
241
+ requestId?: string;
242
+ /** Internal reload recovery hint; the SDK always owns this field. */
243
+ reactivate?: boolean;
244
+ /**
245
+ * Internal history-preservation proof; the SDK always owns this field.
246
+ * Core may restore only this exact chatter and must never fall through to
247
+ * create/identify when completing a soft reset.
248
+ */
249
+ expectedChatterToken?: string;
250
+ /**
251
+ * Internal storage-scope proof paired with expectedChatterToken. An
252
+ * identified chatter persists in tab-scoped storage after its one-shot
253
+ * identity token is consumed; replacement Core must reopen that scope
254
+ * without replaying the token or clearing anonymous storage.
255
+ */
256
+ expectedIdentitySession?: boolean;
257
+ } | undefined;
258
+ /** Inject a proactive conversation (SDK → core); URL matches are prevalidated before delay. */
259
+ "sdk.proactive.inject": {
260
+ key: string;
261
+ params?: Record<string, string>;
262
+ triggerMethod: "url" | "programmatic";
263
+ intentId: number;
264
+ };
265
+ /** Confirm that the intro frame actually rendered a proactive display. */
266
+ "sdk.proactive.shown": {
267
+ campaignKey: string;
268
+ surfaceId: number;
269
+ };
270
+ /** Retire only the old display while a replacement remains pending. */
271
+ "sdk.proactive.replaced": {
272
+ surfaceId: number;
273
+ };
274
+ /** Clear all selected/displayed proactives and establish an ordering barrier. */
275
+ "sdk.proactive.clear": {
276
+ requestId: number;
277
+ };
278
+ /** Notify core that user engaged with proactive message (SDK → core) */
279
+ "sdk.proactive.engaged": {
280
+ campaignKey: string;
281
+ surfaceId: number;
282
+ };
283
+ /** Notify core that user dismissed proactive messages (SDK → core) */
284
+ "sdk.proactive.dismissed": {
285
+ campaignKey: string;
286
+ surfaceId: number;
287
+ };
288
+ /** Programmatically trigger a greeting (SDK → core).
289
+ * `responseId` is the `triggerAnswer(answerId)` arm of legacy's
290
+ * `{ response_id } | { handle }` greeting union; it sends unconditionally. */
291
+ "sdk.greeting.trigger": {
292
+ handle?: string;
293
+ responseId?: string;
294
+ };
295
+ /** Deliberately inert ping that unlocks a referrer-stripped intro child. */
296
+ "intro.handshake": undefined;
297
+ /** Display proactive messages in intro frame (SDK → intro).
298
+ * Mirrors the `core.proactive.show` payload, plus `align` — core has no notion of
299
+ * the widget's side, so the SDK stamps it on while forwarding. Without it the
300
+ * frame cannot hug the launcher's edge on a left-aligned bot. */
301
+ "intro.proactive.display": {
302
+ messages: Array<{
303
+ id: string;
304
+ body: string;
305
+ campaignKey: string;
306
+ timestamp: number;
307
+ imageUrl?: string;
308
+ imageAlt?: string;
309
+ cta?: {
310
+ label: string;
311
+ url: string;
312
+ openInNewTab: boolean;
313
+ };
314
+ }>;
315
+ duration: number | null;
316
+ surfaceId: number;
317
+ align?: "left" | "right";
318
+ };
319
+ /** Clear proactive messages in intro frame (SDK → intro) */
320
+ "intro.proactive.clear": undefined;
321
+ /** Voice transcript update from SDK (SDK → Core) */
322
+ "sdk.voice.transcript": {
323
+ transcript: string;
324
+ isFinal: boolean;
325
+ };
326
+ /** Voice error from SDK (SDK → Core) */
327
+ "sdk.voice.error": {
328
+ error: string;
329
+ };
330
+ /** Audio level update for waveform (SDK → Core) */
331
+ "sdk.voice.audioLevel": {
332
+ level: number;
333
+ };
334
+ /** Set the display language (SDK → core) */
335
+ "sdk.language.set": {
336
+ language: string;
337
+ };
338
+ /** Update metafield key/value pairs (SDK → core) */
339
+ "sdk.metaFields.set": {
340
+ metaFields: Record<string, MetaFieldValue>;
341
+ };
342
+ /**
343
+ * Refresh metadata derived from host-page runtime state. These keys are owned
344
+ * by the SDK and are deliberately separate from the public metadata setter.
345
+ */
346
+ "sdk.runtimeMeta.set": {
347
+ initialURL?: string;
348
+ introShown?: boolean;
349
+ };
350
+ /** Show/hide the dashboard test-mode banner (SDK → core); null hides it */
351
+ "sdk.testModeBanner.set": {
352
+ label: string | null;
353
+ };
354
+ "sdk.sensitiveMetaFields.set": {
355
+ sensitiveMetaFields: Record<string, MetaFieldValue>;
356
+ };
357
+ /** Delete chatter history and reset the session (SDK → core). */
358
+ "sdk.history.delete": {
359
+ requestId?: string;
360
+ } | undefined;
361
+ /** Register a device push notification token (SDK → core) */
362
+ "sdk.notifications.deviceToken.set": {
363
+ token: string;
364
+ };
365
+ /** Track an analytics event (SDK → core) */
366
+ "sdk.analytics.trackEvent": {
367
+ key: string;
368
+ value?: number;
369
+ meta?: Record<string, unknown>;
370
+ };
371
+ /** Request current client state info (SDK → core) */
372
+ "sdk.info.get": {
373
+ requestId: string;
374
+ };
375
+ /** Request the current non-sensitive metaFields (SDK → core) */
376
+ "sdk.metaFields.get": {
377
+ requestId: string;
378
+ };
379
+ /** Request conversation + live-agent handoff state (SDK → core) */
380
+ "sdk.conversation.get": {
381
+ requestId: string;
382
+ };
383
+ /** Request the in-memory message transcript (SDK → core) */
384
+ "sdk.messages.get": {
385
+ requestId: string;
386
+ };
387
+ /** Set the visible chat composer text (SDK → core) */
388
+ "sdk.composerText.set": {
389
+ requestId: string;
390
+ text: string;
391
+ };
392
+ /** Create a manually-constructed proactive message in the intro frame */
393
+ "sdk.proactive.custom": {
394
+ id: string;
395
+ body: string;
396
+ duration?: number;
397
+ responseId?: string;
398
+ };
399
+ /**
400
+ * Forward startup config to the button frame so it can render the
401
+ * correct icon/text/size/fallback UI (SDK → button).
402
+ */
403
+ "sdk.button.config": StartupConfig & {
404
+ align: "left" | "right";
405
+ };
406
+ /** Show the button frame with a CSS transition (SDK → button) */
407
+ "sdk.button.show": undefined;
408
+ /** Hide the button frame with a CSS transition (SDK → button) */
409
+ "sdk.button.hide": undefined;
410
+ /** Show an emoji overlay above the button (SDK → button) */
411
+ "sdk.button.emoji.show": {
412
+ emojiUrl: string;
413
+ };
414
+ /** Remove the emoji overlay from the button (SDK → button) */
415
+ "sdk.button.emoji.hide": undefined;
416
+ /** Focus the button element for keyboard accessibility (SDK → button) */
417
+ "sdk.button.focus": undefined;
418
+ /**
419
+ * Update the unread message count badge on the button (SDK → button).
420
+ *
421
+ * `display: "dot"` renders the badge without its digit. It is for a count the
422
+ * SDK cannot vouch for as a message count — see `_seedUnreadCountFromServer`
423
+ * in `client/client.ts`. Omitted means the digit is shown.
424
+ */
425
+ "sdk.unread.count": {
426
+ count: number;
427
+ display?: "count" | "dot";
428
+ };
429
+ /** Show a bot greeting popup in the intro frame (SDK → intro) */
430
+ "intro.greeting.show": {
431
+ body: string;
432
+ duration: number | null;
433
+ style: "Text" | "Emoji";
434
+ displayId: number;
435
+ align?: "left" | "right";
436
+ image?: {
437
+ url: string;
438
+ alt: string;
439
+ };
440
+ cta?: {
441
+ label: string;
442
+ url: string;
443
+ openInNewTab: boolean;
444
+ };
445
+ };
446
+ /** Hide the bot greeting popup in the intro frame (SDK → intro) */
447
+ "intro.greeting.hide": undefined;
448
+ /** Send a user message into the conversation (SDK → core) */
449
+ "sdk.message.send": {
450
+ requestId?: string;
451
+ body: string;
452
+ };
453
+ /** Respond to a Zendesk Chat auth token request (SDK → core) */
454
+ "sdk.zd.auth.response": {
455
+ token: string | null;
456
+ error?: string;
457
+ };
458
+ }
459
+ /**
460
+ * Frame → SDK events.
461
+ * Events sent from child iframes back to the SDK.
462
+ */
463
+ export interface FrameToSdkEvents {
464
+ /** Frame reports its origin for secure targeting */
465
+ "frame.origin.report": {
466
+ origin: string;
467
+ };
468
+ /** Core frame signals it has finished initializing */
469
+ "frame.ready": {
470
+ name: FrameName;
471
+ };
472
+ /** Core requests the SDK to create a browser web notification */
473
+ "frame.notification.create": {
474
+ title: string;
475
+ body?: string;
476
+ icon?: string;
477
+ conversationId?: string;
478
+ messageId?: string;
479
+ };
480
+ /** Core asks the host page to follow a validated same-tab link. */
481
+ "core.host.navigate": {
482
+ url: string;
483
+ /**
484
+ * Compatibility echo for older SDK assets. Current SDKs authorize against the
485
+ * previously accepted StartupConfig and never against this command payload.
486
+ */
487
+ allowedProtocols: string[];
488
+ };
489
+ /** Core asks the unsandboxed web host to print a validated image. */
490
+ "core.host.printImage": {
491
+ url: string;
492
+ };
493
+ /** Core asks the SDK host to expand or restore its viewport surface. */
494
+ "core.host.viewport.set": {
495
+ expanded: boolean;
496
+ };
497
+ /** A frame encountered an error */
498
+ "frame.error": {
499
+ name: FrameName;
500
+ error: string;
501
+ };
502
+ /** Button frame reports its rendered content size so the SDK can resize the iframe to fit */
503
+ "button.resize": {
504
+ width: number;
505
+ height: number;
506
+ };
507
+ /** Core sends proactive messages to show in intro frame (core → SDK) */
508
+ "core.proactive.show": {
509
+ messages: Array<{
510
+ id: string;
511
+ body: string;
512
+ campaignKey: string;
513
+ timestamp: number;
514
+ imageUrl?: string;
515
+ imageAlt?: string;
516
+ cta?: {
517
+ label: string;
518
+ url: string;
519
+ openInNewTab: boolean;
520
+ };
521
+ }>;
522
+ duration: number | null;
523
+ /** Core-owned identity for this selected campaign. */
524
+ surfaceId: number;
525
+ /** SDK-originated display metadata; absent for API-driven campaigns. */
526
+ triggerMethod?: "url" | "programmatic";
527
+ /** Seconds still to wait in the SDK. URL triggers always carry zero. */
528
+ displayDelay?: number;
529
+ frequency?: "always" | "session" | "user";
530
+ /** Echo of the SDK trigger that produced this display. */
531
+ intentId?: number;
532
+ };
533
+ /** Acknowledge an SDK clear barrier. */
534
+ "core.proactive.cleared": {
535
+ requestId: number;
536
+ };
537
+ /** Core-origin lifecycle reset for proactive work only (never a greeting). */
538
+ "core.proactive.clear": undefined;
539
+ /** Core sends rollout fraction after client config is loaded (core → SDK) */
540
+ "core.rollout": {
541
+ value: number | null;
542
+ };
543
+ /** Core reports the storage scope selected for the current session lifecycle. */
544
+ "core.storage.persistence": {
545
+ mode: "normal" | "session" | "private";
546
+ };
547
+ /** Intro frame reports user clicked a proactive message (intro → SDK) */
548
+ "intro.proactive.clicked": {
549
+ campaignKey: string;
550
+ surfaceId: number;
551
+ };
552
+ /** Intro confirms React committed the requested proactive surface. */
553
+ "intro.proactive.shown": {
554
+ campaignKey: string;
555
+ surfaceId: number;
556
+ };
557
+ /** Intro frame reports user dismissed proactive messages (intro → SDK) */
558
+ "intro.proactive.dismissed": {
559
+ campaignKey: string;
560
+ surfaceId: number;
561
+ };
562
+ /** Intro frame reports its rendered content height so the SDK can size the
563
+ * iframe to fit (avoids cropping tall proactive cards with images) (intro → SDK) */
564
+ "intro.resize": {
565
+ height: number;
566
+ };
567
+ /** Intro frame reports user clicked a proactive bubble's branded CTA (intro → SDK).
568
+ * Fire-and-forget navigation — no campaignKey, matching legacy link-click semantics. */
569
+ "intro.proactive.cta.clicked": {
570
+ url: string;
571
+ openInNewTab: boolean;
572
+ kind: "greeting";
573
+ displayId: number;
574
+ } | {
575
+ url: string;
576
+ openInNewTab: boolean;
577
+ kind: "proactive";
578
+ surfaceId: number;
579
+ campaignKey: string;
580
+ };
581
+ /** Core requests SDK to start voice recording (Core → SDK) */
582
+ "core.voice.start": undefined;
583
+ /** Core requests SDK to stop voice recording (Core → SDK) */
584
+ "core.voice.stop": undefined;
585
+ /** Core sets voice language for recognition (Core → SDK) */
586
+ "core.voice.setLanguage": {
587
+ language: string;
588
+ };
589
+ /** Core sets voice recording mode (Core → SDK) */
590
+ "core.voice.setMode": {
591
+ mode: "toggle" | "push-to-talk";
592
+ };
593
+ /** Core requests SDK to speak text via TTS (Core → SDK) */
594
+ "core.tts.speak": {
595
+ text: string;
596
+ };
597
+ /** Core publishes a named event for SDK subscribeEvent routing (core → SDK) */
598
+ "core.event.publish": {
599
+ key: string;
600
+ data: unknown;
601
+ };
602
+ /** Core notifies SDK that a chatter was created — for chatterTokenCallback (core → SDK) */
603
+ "core.chatter.created": {
604
+ chatterId: string;
605
+ chatterToken: string;
606
+ };
607
+ /**
608
+ * Core found a persisted chatter credential. It remains provisional until the
609
+ * SDK confirms a live server state and core reports a successful restore.
610
+ */
611
+ "core.chatter.candidate": {
612
+ chatterToken: string;
613
+ requestId: number;
614
+ };
615
+ /** Result of an existing-only sdk.session.resume request. */
616
+ "core.session.resume.result": {
617
+ chatterToken: string;
618
+ requestId: number;
619
+ resumed: boolean;
620
+ reason?: string;
621
+ };
622
+ /** Result of an exact restore-only drawer visibility request. */
623
+ "core.session.resume.visibility.result": {
624
+ chatterToken: string;
625
+ requestId: number;
626
+ visible: boolean;
627
+ };
628
+ /** Core notifies SDK that a one-shot identity token was successfully exchanged. */
629
+ "core.identityToken.consumed": {
630
+ chatterToken: string;
631
+ };
632
+ /** Core notifies SDK that a one-shot identity token exchange failed. */
633
+ "core.identityToken.failed": {
634
+ reason: string;
635
+ };
636
+ /** Core sends an analytics event (core → SDK) */
637
+ "core.analytics.event": {
638
+ event: string;
639
+ data: Record<string, unknown>;
640
+ };
641
+ /** Core forwards a custom JavaScript event — for legacy eventCallbacks (core → SDK) */
642
+ "core.customJavascript": {
643
+ payload: unknown;
644
+ };
645
+ /** Core completed public-only startup config and can accept deferred commands. */
646
+ "core.ready": undefined;
647
+ /** Core installed its SDK message router and can accept reset-bound commands. */
648
+ "core.protocol.ready": undefined;
649
+ /** Core responds to a programmatic sendMessage request (core → SDK) */
650
+ "core.message.response": {
651
+ requestId: string;
652
+ id?: string;
653
+ error?: string;
654
+ };
655
+ /** Core confirmed an sdk.reset durable clear/reconfiguration barrier. */
656
+ "core.reset.response": {
657
+ requestId: string;
658
+ };
659
+ /** Core confirmed an sdk.history.delete durable clear barrier. */
660
+ "core.history.delete.response": {
661
+ requestId: string;
662
+ };
663
+ /** Core broadcasts its public launcher config snapshot before engaged prepare(). */
664
+ "core.startup.config": StartupConfig;
665
+ /** Button frame notifies SDK that the user opened chat via keyboard (button → SDK) */
666
+ "button.click.keyboard": undefined;
667
+ /** Intro frame notifies SDK that the user clicked a bot greeting (intro → SDK) */
668
+ "intro.greeting.clicked": {
669
+ displayId: number;
670
+ };
671
+ /** Intro frame notifies SDK that the user dismissed the bot greeting (intro → SDK) */
672
+ "intro.greeting.dismissed": {
673
+ displayId: number;
674
+ };
675
+ /** Core notifies SDK of the current unread message count (core → SDK) */
676
+ "core.unread.count": {
677
+ count: number;
678
+ };
679
+ /** Core requests a Zendesk Chat auth token from the host page (core → SDK) */
680
+ "core.zd.auth.request": {
681
+ chatterToken: string;
682
+ };
683
+ /** Core responds to an sdk.info.get request (core → SDK) */
684
+ "core.info.response": {
685
+ requestId: string;
686
+ isChatOpen: boolean;
687
+ isDrawerOpen: boolean;
688
+ hasActiveChatter: boolean;
689
+ hasClosedChat: boolean;
690
+ };
691
+ /** Core responds to an sdk.metaFields.get request (core → SDK) */
692
+ "core.metaFields.response": {
693
+ requestId: string;
694
+ metaFields: Record<string, string | number | boolean | null>;
695
+ };
696
+ /** Core responds to an sdk.conversation.get request (core → SDK) */
697
+ "core.conversation.response": {
698
+ requestId: string;
699
+ error?: string;
700
+ id?: string | null;
701
+ handoff?: {
702
+ inLiveChat: boolean;
703
+ agent?: {
704
+ id: string;
705
+ name: string;
706
+ avatarUrl?: string;
707
+ };
708
+ };
709
+ };
710
+ /** Core responds to an sdk.messages.get request (core → SDK) */
711
+ "core.messages.response": {
712
+ requestId: string;
713
+ error?: string;
714
+ messages?: Array<{
715
+ id: string;
716
+ role: "user" | "bot" | "agent";
717
+ type: string;
718
+ body?: string;
719
+ createdAt: number;
720
+ /** Present whenever the transport message carries agent identity. */
721
+ agent?: {
722
+ id: string;
723
+ name: string;
724
+ avatarUrl?: string;
725
+ };
726
+ data?: Record<string, unknown>;
727
+ origin?: "programmatic";
728
+ }>;
729
+ };
730
+ /** Core responds to an sdk.composerText.set request (core → SDK) */
731
+ "core.composerText.response": {
732
+ requestId: string;
733
+ ok?: true;
734
+ error?: string;
735
+ };
736
+ }