@kindly-ai/react-native 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/KindlyReactNative.podspec +36 -0
- package/LICENSE +20 -0
- package/README.md +127 -0
- package/android/build.gradle +113 -0
- package/android/maven-repo/ai/kindly/sdk/1.0.93/sdk-1.0.93.aar +0 -0
- package/android/maven-repo/ai/kindly/sdk/1.0.93/sdk-1.0.93.pom +125 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/kindlyai/reactnative/KindlyReactNativeModule.kt +445 -0
- package/android/src/main/java/com/kindlyai/reactnative/KindlyReactNativePackage.kt +38 -0
- package/ios/Frameworks/Kindly.xcframework/Info.plist +44 -0
- package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeDirectory +0 -0
- package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeRequirements +0 -0
- package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
- package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeResources +578 -0
- package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeSignature +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Assets.car +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Config.plist +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/ConfirmationWindow.nib +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Headers/Kindly-Swift.h +331 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Headers/Kindly.h +18 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Info.plist +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Kindly +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios.abi.json +28769 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios.private.swiftinterface +547 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios.swiftinterface +543 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/module.modulemap +11 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/PrivacyInfo.xcprivacy +83 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/_CodeSignature/CodeResources +223 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Assets.car +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Config.plist +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/ConfirmationWindow.nib +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Headers/Kindly-Swift.h +658 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Headers/Kindly.h +18 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Info.plist +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Kindly +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios-simulator.abi.json +28769 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +547 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios-simulator.swiftinterface +543 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/x86_64-apple-ios-simulator.abi.json +28769 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +547 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +543 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/module.modulemap +11 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/PrivacyInfo.xcprivacy +83 -0
- package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/_CodeSignature/CodeResources +267 -0
- package/ios/KindlyReactNative.h +18 -0
- package/ios/KindlyReactNative.mm +234 -0
- package/ios/KindlyReactNativeImpl.swift +410 -0
- package/lib/module/NativeKindlyReactNative.js +22 -0
- package/lib/module/NativeKindlyReactNative.js.map +1 -0
- package/lib/module/index.js +280 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeKindlyReactNative.d.ts +47 -0
- package/lib/typescript/src/NativeKindlyReactNative.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +150 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +121 -0
- package/src/NativeKindlyReactNative.ts +80 -0
- package/src/index.tsx +353 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// TurboModule spec for the @kindly-ai/react-native package.
|
|
2
|
+
//
|
|
3
|
+
// Codegen INPUT — `react-native` reads this at build time and generates the
|
|
4
|
+
// abstract Spec class on iOS (Obj-C++ header) and Android (Kotlin abstract
|
|
5
|
+
// class). The native module classes extend those.
|
|
6
|
+
//
|
|
7
|
+
// Convention used here: every method takes flat primitive parameters and
|
|
8
|
+
// returns either a primitive or a Promise. We deliberately avoid nested
|
|
9
|
+
// struct args (`(args: { ... })`) because codegen generates JS::Native*Args
|
|
10
|
+
// C++ structs for those, which add fragility without buying anything for
|
|
11
|
+
// our use case. This matches the scaffolded `multiply()` example pattern.
|
|
12
|
+
//
|
|
13
|
+
// Filename MUST match `Native<ModuleName>.ts`. ModuleName here is
|
|
14
|
+
// `KindlyReactNative` — this becomes the native module name returned by
|
|
15
|
+
// `getName()` and the registry key. Customer-facing imports come from the
|
|
16
|
+
// package, not the module name.
|
|
17
|
+
import type { TurboModule } from 'react-native';
|
|
18
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
19
|
+
|
|
20
|
+
export interface Spec extends TurboModule {
|
|
21
|
+
// Lifecycle
|
|
22
|
+
start(botKey: string, languageCode: string | null, hasAuthCallback: boolean): void;
|
|
23
|
+
displayChat(languageCode: string | null, triggerDialogueId: string | null): void;
|
|
24
|
+
launchChat(triggerDialogueId: string | null): void;
|
|
25
|
+
closeChat(): void;
|
|
26
|
+
endChat(): Promise<void>;
|
|
27
|
+
kill(): Promise<void>;
|
|
28
|
+
setLanguage(languageCode: string): Promise<void>;
|
|
29
|
+
|
|
30
|
+
// Messaging — newContext map shape: { [key: string]: string }
|
|
31
|
+
sendMessage(
|
|
32
|
+
message: string,
|
|
33
|
+
newContext: { [key: string]: string } | null
|
|
34
|
+
): Promise<{ [key: string]: unknown } | null>;
|
|
35
|
+
setNewContext(context: { [key: string]: string }): void;
|
|
36
|
+
clearNewContext(): void;
|
|
37
|
+
triggerDialogue(dialogueId: string): void;
|
|
38
|
+
clearTriggerDialogue(): void;
|
|
39
|
+
handleUrl(url: string): Promise<boolean>;
|
|
40
|
+
|
|
41
|
+
// Theme — colors map shape: { [key: string]: number | null }
|
|
42
|
+
setCustomTheme(colors: { [key: string]: number | null }): void;
|
|
43
|
+
clearCustomTheme(): void;
|
|
44
|
+
|
|
45
|
+
// Push
|
|
46
|
+
setAPNSDeviceToken(token: string): void;
|
|
47
|
+
saveNotificationToken(token: string): void;
|
|
48
|
+
handleNotification(data: { [key: string]: unknown }): void;
|
|
49
|
+
isKindlyNotification(data: { [key: string]: unknown }): boolean;
|
|
50
|
+
|
|
51
|
+
// State / settings
|
|
52
|
+
saveAuthToken(token: string): Promise<boolean>;
|
|
53
|
+
isChatDisplayed(): Promise<boolean>;
|
|
54
|
+
setVerboseLogging(enabled: boolean): void;
|
|
55
|
+
setCrashReporting(enabled: boolean): void;
|
|
56
|
+
|
|
57
|
+
// Round-trips for sync-style native→JS→native callbacks.
|
|
58
|
+
// Native fires events ('KindlyGetAuthToken', 'KindlyShouldHandle*') with
|
|
59
|
+
// a requestId; JS replies via these methods. Native blocks on a
|
|
60
|
+
// Map<requestId, Deferred> with a 5-second timeout, falling back to a
|
|
61
|
+
// safe default if JS is silent.
|
|
62
|
+
respondToAuthToken(requestId: string, token: string | null): void;
|
|
63
|
+
respondToShouldHandle(requestId: string, value: boolean): void;
|
|
64
|
+
|
|
65
|
+
// Delegate gating — flips on/off the bridge-level routing for each callback.
|
|
66
|
+
setDelegate(
|
|
67
|
+
onButtonPressed: boolean,
|
|
68
|
+
shouldHandleLink: boolean,
|
|
69
|
+
shouldHandleNotification: boolean,
|
|
70
|
+
onHandover: boolean
|
|
71
|
+
): void;
|
|
72
|
+
callHandover(): void;
|
|
73
|
+
|
|
74
|
+
// RN bridge bookkeeping — required when the module emits events (iOS only
|
|
75
|
+
// looks at this; on Android RCTDeviceEventEmitter manages itself).
|
|
76
|
+
addListener(eventName: string): void;
|
|
77
|
+
removeListeners(count: number): void;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('KindlyReactNative');
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
// Kindly Chat SDK — public React Native surface.
|
|
2
|
+
//
|
|
3
|
+
// Thin TS facade over the native TurboModule (`KindlyReactNative`). Mirrors
|
|
4
|
+
// the Flutter SDK's public API 1:1. Each method delegates to one or more
|
|
5
|
+
// methods on the spec, plus a tiny amount of bookkeeping in JS for the
|
|
6
|
+
// auth-token + delegate round-trips (the native side has no way to call
|
|
7
|
+
// JS synchronously, so we pair `*Request` events with a `respondTo*` method).
|
|
8
|
+
//
|
|
9
|
+
// Customers do `import { KindlySDK } from '@kindly-ai/react-native'`. The
|
|
10
|
+
// internal native-module name `KindlyReactNative` is intentionally not
|
|
11
|
+
// exported — it's an implementation detail.
|
|
12
|
+
import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
|
|
13
|
+
import NativeKindly from './NativeKindlyReactNative';
|
|
14
|
+
|
|
15
|
+
/** Callback invoked by the SDK when it needs a fresh JWT auth token. */
|
|
16
|
+
export type AuthTokenCallback = () => Promise<string | null>;
|
|
17
|
+
|
|
18
|
+
/** Callback invoked when a handover to a human agent is initiated. */
|
|
19
|
+
export type HandoverCallback = () => void;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Fired by the SDK when the user taps a chat button.
|
|
23
|
+
*
|
|
24
|
+
* `button` keys: `id`, `type`, `label`, `value`, `index`, `hasBeenSelected`.
|
|
25
|
+
* `chatLog` is the full conversation up to this point.
|
|
26
|
+
*/
|
|
27
|
+
export type KindlyButtonPressedCallback = (
|
|
28
|
+
button: { [key: string]: unknown },
|
|
29
|
+
chatLog: Array<{ [key: string]: unknown }>
|
|
30
|
+
) => void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Asked by the SDK before opening a link the user tapped inside chat.
|
|
34
|
+
*
|
|
35
|
+
* Return `true` to let the SDK open it (default), or `false` to take over.
|
|
36
|
+
*/
|
|
37
|
+
export type KindlyLinkInterceptCallback = (url: string) => boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Asked by the SDK before presenting an incoming Kindly silent push.
|
|
41
|
+
*
|
|
42
|
+
* Return `true` to let the SDK present it (default), or `false` to take over.
|
|
43
|
+
*/
|
|
44
|
+
export type KindlyNotificationInterceptCallback = (notification: {
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
}) => boolean;
|
|
47
|
+
|
|
48
|
+
/** Typed bag of theme colors (ARGB ints — use the helpers below). */
|
|
49
|
+
export interface KindlyTheme {
|
|
50
|
+
background?: number;
|
|
51
|
+
botMessageBackground?: number;
|
|
52
|
+
botMessageText?: number;
|
|
53
|
+
buttonBackground?: number;
|
|
54
|
+
buttonOutline?: number;
|
|
55
|
+
buttonSelectedBackground?: number;
|
|
56
|
+
buttonText?: number;
|
|
57
|
+
defaultShadow?: number;
|
|
58
|
+
inputBackground?: number;
|
|
59
|
+
inputCursor?: number;
|
|
60
|
+
inputText?: number;
|
|
61
|
+
navBarBackground?: number;
|
|
62
|
+
navBarText?: number;
|
|
63
|
+
userMessageBackground?: number;
|
|
64
|
+
userMessageText?: number;
|
|
65
|
+
chatLogElements?: number;
|
|
66
|
+
maintenanceHeaderBackground?: number;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Convert a `#RRGGBB` or `#AARRGGBB` hex string to the ARGB int form the
|
|
71
|
+
* SDK expects. Equivalent to Flutter's `Color.value`.
|
|
72
|
+
*/
|
|
73
|
+
export function hexColor(hex: string): number {
|
|
74
|
+
const cleaned = hex.replace(/^#/, '');
|
|
75
|
+
const v = parseInt(cleaned, 16);
|
|
76
|
+
if (cleaned.length === 6) {
|
|
77
|
+
return (0xff000000 | v) >>> 0;
|
|
78
|
+
}
|
|
79
|
+
if (cleaned.length === 8) {
|
|
80
|
+
return v >>> 0;
|
|
81
|
+
}
|
|
82
|
+
throw new Error(`hexColor: expected #RRGGBB or #AARRGGBB, got "${hex}"`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
86
|
+
// Native-event wiring for native→JS callbacks.
|
|
87
|
+
//
|
|
88
|
+
// Native fires events via RCTDeviceEventEmitter; JS attaches once on first use
|
|
89
|
+
// and dispatches to the registered callbacks. Sync-bool answers
|
|
90
|
+
// (`shouldHandleLink` / `shouldHandleNotification`) are returned via a
|
|
91
|
+
// `respondToShouldHandle` round-trip — native blocks on a Map<requestId,
|
|
92
|
+
// Deferred> with a 5s timeout, falling back to `true` if JS is slow or
|
|
93
|
+
// silent. Same semantics as the Flutter SDK's blocking-bool pattern.
|
|
94
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
95
|
+
const eventEmitter = new NativeEventEmitter(
|
|
96
|
+
Platform.OS === 'ios'
|
|
97
|
+
? (NativeModules.KindlyReactNative as unknown as undefined)
|
|
98
|
+
: undefined
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
let authTokenCallback: AuthTokenCallback | null = null;
|
|
102
|
+
let handoverCallback: HandoverCallback | null = null;
|
|
103
|
+
let onButtonPressed: KindlyButtonPressedCallback | null = null;
|
|
104
|
+
let shouldHandleLink: KindlyLinkInterceptCallback | null = null;
|
|
105
|
+
let shouldHandleNotification: KindlyNotificationInterceptCallback | null = null;
|
|
106
|
+
|
|
107
|
+
let listenersAttached = false;
|
|
108
|
+
|
|
109
|
+
function attachListeners(): void {
|
|
110
|
+
if (listenersAttached) return;
|
|
111
|
+
listenersAttached = true;
|
|
112
|
+
|
|
113
|
+
// RN's NativeEventEmitter.addListener types its callback as
|
|
114
|
+
// `(...args: readonly Object[]) => unknown` — we widen each event-shape
|
|
115
|
+
// type inside the handler instead of trying to fight the parameter type.
|
|
116
|
+
eventEmitter.addListener('KindlyGetAuthToken', async (raw: unknown) => {
|
|
117
|
+
const event = raw as { requestId: string };
|
|
118
|
+
if (authTokenCallback == null) {
|
|
119
|
+
NativeKindly.respondToAuthToken(event.requestId, null);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const token = await authTokenCallback();
|
|
124
|
+
NativeKindly.respondToAuthToken(event.requestId, token);
|
|
125
|
+
} catch {
|
|
126
|
+
NativeKindly.respondToAuthToken(event.requestId, null);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
eventEmitter.addListener('KindlyOnHandover', () => {
|
|
131
|
+
handoverCallback?.();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
eventEmitter.addListener('KindlyOnButtonPressed', (raw: unknown) => {
|
|
135
|
+
const event = raw as {
|
|
136
|
+
button: { [key: string]: unknown };
|
|
137
|
+
chatLog: Array<{ [key: string]: unknown }>;
|
|
138
|
+
};
|
|
139
|
+
onButtonPressed?.(event.button, event.chatLog);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
eventEmitter.addListener('KindlyShouldHandleLink', (raw: unknown) => {
|
|
143
|
+
const event = raw as { requestId: string; url: string };
|
|
144
|
+
const value = shouldHandleLink ? shouldHandleLink(event.url) : true;
|
|
145
|
+
NativeKindly.respondToShouldHandle(event.requestId, value);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
eventEmitter.addListener(
|
|
149
|
+
'KindlyShouldHandleNotification',
|
|
150
|
+
(raw: unknown) => {
|
|
151
|
+
const event = raw as {
|
|
152
|
+
requestId: string;
|
|
153
|
+
notification: { [key: string]: unknown };
|
|
154
|
+
};
|
|
155
|
+
const value = shouldHandleNotification
|
|
156
|
+
? shouldHandleNotification(event.notification)
|
|
157
|
+
: true;
|
|
158
|
+
NativeKindly.respondToShouldHandle(event.requestId, value);
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Main Kindly SDK entry point.
|
|
165
|
+
*
|
|
166
|
+
* Thin facade over the public `EntryPoint` API of the native iOS
|
|
167
|
+
* (`KindlyChatClient`) and Android (`ChatKindlySDK`) SDKs.
|
|
168
|
+
*/
|
|
169
|
+
export class KindlySDK {
|
|
170
|
+
/** Initialize the SDK. Must be called before any other method. */
|
|
171
|
+
static start(args: {
|
|
172
|
+
botKey: string;
|
|
173
|
+
languageCode?: string;
|
|
174
|
+
authTokenCallback?: AuthTokenCallback;
|
|
175
|
+
}): void {
|
|
176
|
+
attachListeners();
|
|
177
|
+
authTokenCallback = args.authTokenCallback ?? null;
|
|
178
|
+
NativeKindly.start(
|
|
179
|
+
args.botKey,
|
|
180
|
+
args.languageCode ?? null,
|
|
181
|
+
args.authTokenCallback != null
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Show the chat UI. */
|
|
186
|
+
static displayChat(
|
|
187
|
+
args: { languageCode?: string; triggerDialogueId?: string } = {}
|
|
188
|
+
): void {
|
|
189
|
+
NativeKindly.displayChat(
|
|
190
|
+
args.languageCode ?? null,
|
|
191
|
+
args.triggerDialogueId ?? null
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Connect (if needed) and show chat. Recommended on Android. */
|
|
196
|
+
static launchChat(args: { triggerDialogueId?: string } = {}): void {
|
|
197
|
+
NativeKindly.launchChat(args.triggerDialogueId ?? null);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Dismiss the chat UI without ending the session. */
|
|
201
|
+
static closeChat(): void {
|
|
202
|
+
NativeKindly.closeChat();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** End the chat session: clears messages, token, dismisses UI. */
|
|
206
|
+
static endChat(): Promise<void> {
|
|
207
|
+
return NativeKindly.endChat();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Tear the SDK down completely; call start() again before reuse. */
|
|
211
|
+
static kill(): Promise<void> {
|
|
212
|
+
return NativeKindly.kill();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Update the language for the current session. */
|
|
216
|
+
static setLanguage(languageCode: string): Promise<void> {
|
|
217
|
+
return NativeKindly.setLanguage(languageCode);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Send a message programmatically. Returns the reconciled message map
|
|
222
|
+
* (id, text, created, sender, …) or rejects on failure.
|
|
223
|
+
*/
|
|
224
|
+
static sendMessage(
|
|
225
|
+
text: string,
|
|
226
|
+
options?: { newContext?: { [key: string]: string } }
|
|
227
|
+
): Promise<{ [key: string]: unknown } | null> {
|
|
228
|
+
return NativeKindly.sendMessage(text, options?.newContext ?? null);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Apply a custom theme. Pass undefined fields to keep the default. */
|
|
232
|
+
static setCustomTheme(theme: KindlyTheme): void {
|
|
233
|
+
const colors: { [key: string]: number | null } = {};
|
|
234
|
+
(Object.keys(theme) as Array<keyof KindlyTheme>).forEach((k) => {
|
|
235
|
+
colors[k] = theme[k] ?? null;
|
|
236
|
+
});
|
|
237
|
+
NativeKindly.setCustomTheme(colors);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** Clear custom theme; revert to default / API-supplied theme. */
|
|
241
|
+
static clearCustomTheme(): void {
|
|
242
|
+
NativeKindly.clearCustomTheme();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Stage context attached to the next message or button click. */
|
|
246
|
+
static setNewContext(context: { [key: string]: string }): void {
|
|
247
|
+
NativeKindly.setNewContext(context);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Clear any context staged via setNewContext. */
|
|
251
|
+
static clearNewContext(): void {
|
|
252
|
+
NativeKindly.clearNewContext();
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** Save a JWT auth token (iOS keychain). On Android always returns true. */
|
|
256
|
+
static saveAuthToken(token: string): Promise<boolean> {
|
|
257
|
+
return NativeKindly.saveAuthToken(token);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/** Register the APNS device token. iOS only — no-op on Android. */
|
|
261
|
+
static setAPNSDeviceToken(token: string): void {
|
|
262
|
+
if (Platform.OS === 'ios') {
|
|
263
|
+
NativeKindly.setAPNSDeviceToken(token);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** Register the FCM token. Android only — no-op on iOS. */
|
|
268
|
+
static saveNotificationToken(token: string): void {
|
|
269
|
+
if (Platform.OS === 'android') {
|
|
270
|
+
NativeKindly.saveNotificationToken(token);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Forward an incoming push notification to the SDK. */
|
|
275
|
+
static handleNotification(data: { [key: string]: unknown }): void {
|
|
276
|
+
NativeKindly.handleNotification(data);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** Returns true if the given push payload originated from Kindly. */
|
|
280
|
+
static isKindlyNotification(data: { [key: string]: unknown }): boolean {
|
|
281
|
+
return NativeKindly.isKindlyNotification(data);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** Trigger a specific dialogue by id. The SDK must be connected. */
|
|
285
|
+
static triggerDialogue(dialogueId: string): void {
|
|
286
|
+
NativeKindly.triggerDialogue(dialogueId);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** Clear any pending trigger-dialogue request (Android only). */
|
|
290
|
+
static clearTriggerDialogue(): void {
|
|
291
|
+
NativeKindly.clearTriggerDialogue();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** Handle a Kindly deep-link URL (e.g. `kindly://chat/dialogue/{id}`). */
|
|
295
|
+
static handleUrl(url: string): Promise<boolean> {
|
|
296
|
+
return NativeKindly.handleUrl(url);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/** Initiate a handover to a human agent. */
|
|
300
|
+
static callHandover(callback: HandoverCallback): void {
|
|
301
|
+
attachListeners();
|
|
302
|
+
handoverCallback = callback;
|
|
303
|
+
NativeKindly.callHandover();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Whether the chat UI is currently displayed (iOS only — Android always false). */
|
|
307
|
+
static isChatDisplayed(): Promise<boolean> {
|
|
308
|
+
return NativeKindly.isChatDisplayed();
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** Toggle verbose SDK logging. */
|
|
312
|
+
static setVerboseLogging(enabled: boolean): void {
|
|
313
|
+
NativeKindly.setVerboseLogging(enabled);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/** Toggle Sentry crash reporting from inside the SDK. */
|
|
317
|
+
static setCrashReporting(enabled: boolean): void {
|
|
318
|
+
NativeKindly.setCrashReporting(enabled);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Register host-app callbacks for chat-button presses, link interception,
|
|
323
|
+
* and notification interception. Mirrors the native delegate protocols.
|
|
324
|
+
*
|
|
325
|
+
* `shouldHandleLink` / `shouldHandleNotification` have a 5-second native
|
|
326
|
+
* timeout — return quickly. After timeout the SDK falls back to its
|
|
327
|
+
* default `true` so the UI doesn't hang on a slow JS callback.
|
|
328
|
+
*/
|
|
329
|
+
static setDelegate(args: {
|
|
330
|
+
onButtonPressed?: KindlyButtonPressedCallback;
|
|
331
|
+
shouldHandleLink?: KindlyLinkInterceptCallback;
|
|
332
|
+
shouldHandleNotification?: KindlyNotificationInterceptCallback;
|
|
333
|
+
}): void {
|
|
334
|
+
attachListeners();
|
|
335
|
+
onButtonPressed = args.onButtonPressed ?? null;
|
|
336
|
+
shouldHandleLink = args.shouldHandleLink ?? null;
|
|
337
|
+
shouldHandleNotification = args.shouldHandleNotification ?? null;
|
|
338
|
+
NativeKindly.setDelegate(
|
|
339
|
+
onButtonPressed != null,
|
|
340
|
+
shouldHandleLink != null,
|
|
341
|
+
shouldHandleNotification != null,
|
|
342
|
+
handoverCallback != null
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** Clear all delegate callbacks set via setDelegate. */
|
|
347
|
+
static clearDelegate(): void {
|
|
348
|
+
onButtonPressed = null;
|
|
349
|
+
shouldHandleLink = null;
|
|
350
|
+
shouldHandleNotification = null;
|
|
351
|
+
NativeKindly.setDelegate(false, false, false, handoverCallback != null);
|
|
352
|
+
}
|
|
353
|
+
}
|