@sagepilot-ai/react-native-sdk 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -6
- package/android/build.gradle +53 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/ai/sagepilot/reactnativesdk/SagepilotInsetsChangeEvent.java +26 -0
- package/android/src/main/java/ai/sagepilot/reactnativesdk/SagepilotInsetsView.java +78 -0
- package/android/src/main/java/ai/sagepilot/reactnativesdk/SagepilotInsetsViewManager.java +59 -0
- package/android/src/main/java/ai/sagepilot/reactnativesdk/SagepilotReactNativeSdkPackage.java +20 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/SagepilotInsetsViewManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/SagepilotInsetsViewManagerInterface.java +10 -0
- package/dist/{index.d.cts → index.d.mts} +38 -3
- package/dist/index.d.ts +38 -3
- package/dist/index.js +299 -96
- package/dist/{index.cjs → index.mjs} +267 -119
- package/package.json +18 -8
- package/react-native.config.js +5 -1
- package/src/specs/SagepilotInsetsViewNativeComponent.ts +17 -0
- package/android/.gitkeep +0 -1
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ You configure the SDK with:
|
|
|
38
38
|
- `tokenStorage`: secure storage adapter for SDK-created customer session tokens
|
|
39
39
|
- optional request, presentation, and behavior settings
|
|
40
40
|
|
|
41
|
-
For
|
|
41
|
+
For standard Sagepilot cloud usage, omit `host`. The SDK connects to Sagepilot's hosted endpoints automatically. Set `host` only when Sagepilot provides a dedicated endpoint for your workspace.
|
|
42
42
|
|
|
43
43
|
```ts
|
|
44
44
|
await SagepilotChat.configure({
|
|
@@ -46,7 +46,7 @@ await SagepilotChat.configure({
|
|
|
46
46
|
});
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
If your workspace
|
|
49
|
+
If Sagepilot provides a dedicated endpoint for your workspace, pass it as an optional override:
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
await SagepilotChat.configure({
|
|
@@ -64,8 +64,8 @@ These options are part of the supported React Native SDK configuration contract.
|
|
|
64
64
|
| Option | Purpose |
|
|
65
65
|
|---|---|
|
|
66
66
|
| `key` | Public routing key in the format `workspace_id:channel_id`. |
|
|
67
|
-
| `host` | Sagepilot
|
|
68
|
-
| `widgetHost` | Optional hosted widget origin override
|
|
67
|
+
| `host` | Optional Sagepilot host override. Most apps should omit this unless Sagepilot provides a dedicated endpoint. |
|
|
68
|
+
| `widgetHost` | Optional hosted widget origin override. Use only when Sagepilot provides a separate widget endpoint. |
|
|
69
69
|
| `headers` | Additional headers for SDK service requests. Do not pass server API keys or long-lived secrets from a mobile app. |
|
|
70
70
|
| `fetch` | Custom fetch implementation for runtimes that need one. |
|
|
71
71
|
| `tokenStorage` | Secure storage adapter for SDK-created customer session tokens. |
|
|
@@ -83,7 +83,7 @@ These options are part of the supported React Native SDK configuration contract.
|
|
|
83
83
|
| `behavior.enableUnreadPolling` | Starts or disables automatic unread-count polling after configuration. |
|
|
84
84
|
| `behavior.unreadPollIntervalMs` | Sets the unread polling interval in milliseconds. |
|
|
85
85
|
|
|
86
|
-
`SagepilotChatProvider` renders the Sagepilot-hosted chat UI in a React Native WebView. Most
|
|
86
|
+
`SagepilotChatProvider` renders the Sagepilot-hosted chat UI in a React Native WebView. Most apps do not need any host override.
|
|
87
87
|
|
|
88
88
|
### Chat Launcher Theme
|
|
89
89
|
|
|
@@ -312,6 +312,33 @@ Other open helpers:
|
|
|
312
312
|
SagepilotChat.present();
|
|
313
313
|
SagepilotChat.presentMessages();
|
|
314
314
|
SagepilotChat.presentMessageComposer("I need help with my order");
|
|
315
|
+
SagepilotChat.presentMessageComposer("Start a new request", { mode: "new" });
|
|
316
|
+
SagepilotChat.presentMessageComposer("I need help with this order", { chatId: savedChatId });
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
`presentMessageComposer(message)` pre-fills the composer and lets Sagepilot reuse an existing conversation when one is available. If there is no existing conversation, Sagepilot starts a new one when the customer sends the message.
|
|
320
|
+
|
|
321
|
+
Use `{ mode: "new" }` only when the button or workflow should always start a fresh conversation.
|
|
322
|
+
|
|
323
|
+
Pass `{ chatId }` when an app-owned surface should reopen a specific conversation, such as an order help button. The SDK sends this as the hosted widget `chat_id` and keeps the existing no-`chatId` behavior unchanged.
|
|
324
|
+
|
|
325
|
+
To store the chat id when a customer creates a conversation from a screen-specific composer:
|
|
326
|
+
|
|
327
|
+
```ts
|
|
328
|
+
SagepilotChat.presentMessageComposer("I need help with this order", {
|
|
329
|
+
metadata: { orderId: "10212984" },
|
|
330
|
+
onConversationCreated: ({ chat_id, metadata }) => {
|
|
331
|
+
// Store metadata.orderId -> chat_id in your app.
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
You can also subscribe globally:
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
const unsubscribe = SagepilotChat.onConversationCreated(({ chat_id }) => {
|
|
340
|
+
// Persist chat_id for later use.
|
|
341
|
+
});
|
|
315
342
|
```
|
|
316
343
|
|
|
317
344
|
## Identity
|
|
@@ -375,11 +402,12 @@ await SagepilotChat.destroy();
|
|
|
375
402
|
|
|
376
403
|
- `SagepilotChat.present()`: opens the hosted chat home screen.
|
|
377
404
|
- `SagepilotChat.presentMessages()`: opens the hosted conversations/messages screen.
|
|
378
|
-
- `SagepilotChat.presentMessageComposer(message?)`: opens
|
|
405
|
+
- `SagepilotChat.presentMessageComposer(message?, options?)`: opens the message composer and optionally pre-fills the composer text. By default, Sagepilot reuses an existing conversation when one is available. Pass `{ mode: "new" }` to force a fresh conversation, or `{ chatId }` to open a specific conversation. It does not auto-send.
|
|
379
406
|
- `SagepilotChat.dismiss()`: closes the hosted chat modal.
|
|
380
407
|
- `SagepilotChat.hide()`: alias for `dismiss()`.
|
|
381
408
|
- `SagepilotChat.toggle()`: opens the chat when closed and closes it when open.
|
|
382
409
|
- `SagepilotChat.isPresented()`: returns whether the hosted chat modal is open.
|
|
410
|
+
- `SagepilotChat.onConversationCreated(callback)`: subscribes to hosted conversations created from the React Native widget and returns `chat_id` plus any composer metadata.
|
|
383
411
|
- `SagepilotChatProvider`: renders the hosted Sagepilot chat inside a React Native modal WebView.
|
|
384
412
|
|
|
385
413
|
When `SagepilotChatProvider` is mounted, the SDK preloads a hidden hosted WebView after `configure()` so the first visible open can reuse warmed network/cache state. Disable this with `behavior.preloadWebView: false`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
repositories {
|
|
3
|
+
google()
|
|
4
|
+
mavenCentral()
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
plugins {
|
|
9
|
+
id "com.android.library"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
def isNewArchitectureEnabled() {
|
|
13
|
+
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (isNewArchitectureEnabled()) {
|
|
17
|
+
apply plugin: "com.facebook.react"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
def safeExtGet(prop, fallback) {
|
|
21
|
+
return rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
android {
|
|
25
|
+
namespace "ai.sagepilot.reactnativesdk"
|
|
26
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 35)
|
|
27
|
+
|
|
28
|
+
defaultConfig {
|
|
29
|
+
minSdkVersion safeExtGet("minSdkVersion", 24)
|
|
30
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 35)
|
|
31
|
+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
compileOptions {
|
|
35
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
36
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
sourceSets.main {
|
|
40
|
+
java {
|
|
41
|
+
if (isNewArchitectureEnabled()) {
|
|
42
|
+
srcDirs += "${project.buildDir}/generated/source/codegen/java"
|
|
43
|
+
} else {
|
|
44
|
+
srcDirs += "src/paper/java"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
dependencies {
|
|
51
|
+
implementation "com.facebook.react:react-android"
|
|
52
|
+
implementation "androidx.core:core:1.13.1"
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package ai.sagepilot.reactnativesdk;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.Nullable;
|
|
4
|
+
import com.facebook.react.bridge.WritableMap;
|
|
5
|
+
import com.facebook.react.uimanager.events.Event;
|
|
6
|
+
|
|
7
|
+
public class SagepilotInsetsChangeEvent extends Event<SagepilotInsetsChangeEvent> {
|
|
8
|
+
public static final String EVENT_NAME = "topInsetsChange";
|
|
9
|
+
private final WritableMap eventData;
|
|
10
|
+
|
|
11
|
+
public SagepilotInsetsChangeEvent(int surfaceId, int viewTag, WritableMap eventData) {
|
|
12
|
+
super(surfaceId, viewTag);
|
|
13
|
+
this.eventData = eventData;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Override
|
|
17
|
+
public String getEventName() {
|
|
18
|
+
return EVENT_NAME;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Nullable
|
|
22
|
+
@Override
|
|
23
|
+
protected WritableMap getEventData() {
|
|
24
|
+
return eventData;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
package ai.sagepilot.reactnativesdk;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.view.View;
|
|
5
|
+
import android.widget.FrameLayout;
|
|
6
|
+
import com.facebook.react.bridge.Arguments;
|
|
7
|
+
import com.facebook.react.bridge.ReactContext;
|
|
8
|
+
import com.facebook.react.bridge.WritableMap;
|
|
9
|
+
import com.facebook.react.uimanager.PixelUtil;
|
|
10
|
+
import com.facebook.react.uimanager.UIManagerHelper;
|
|
11
|
+
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
12
|
+
import androidx.core.graphics.Insets;
|
|
13
|
+
import androidx.core.view.ViewCompat;
|
|
14
|
+
import androidx.core.view.WindowInsetsCompat;
|
|
15
|
+
|
|
16
|
+
public class SagepilotInsetsView extends FrameLayout {
|
|
17
|
+
private int appliedTopInset;
|
|
18
|
+
private int appliedBottomInset;
|
|
19
|
+
|
|
20
|
+
public SagepilotInsetsView(Context context) {
|
|
21
|
+
super(context);
|
|
22
|
+
installInsetsListener();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@Override
|
|
26
|
+
protected void onAttachedToWindow() {
|
|
27
|
+
super.onAttachedToWindow();
|
|
28
|
+
ViewCompat.requestApplyInsets(this);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private void installInsetsListener() {
|
|
32
|
+
ViewCompat.setOnApplyWindowInsetsListener(this, (view, windowInsets) -> {
|
|
33
|
+
Insets imeInsets = windowInsets.getInsets(WindowInsetsCompat.Type.ime());
|
|
34
|
+
Insets systemBarInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
|
35
|
+
int topInset = systemBarInsets.top;
|
|
36
|
+
int bottomInset = Math.max(imeInsets.bottom, systemBarInsets.bottom);
|
|
37
|
+
updateInsets(topInset, bottomInset, imeInsets.bottom, systemBarInsets.bottom);
|
|
38
|
+
return WindowInsetsCompat.CONSUMED;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private void updateInsets(int topInset, int bottomInset, int imeBottom, int systemBarsBottom) {
|
|
43
|
+
int nextTopInset = Math.max(0, topInset);
|
|
44
|
+
int nextBottomInset = Math.max(0, bottomInset);
|
|
45
|
+
if (nextTopInset == appliedTopInset && nextBottomInset == appliedBottomInset) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
appliedTopInset = nextTopInset;
|
|
50
|
+
appliedBottomInset = nextBottomInset;
|
|
51
|
+
emitInsetsChange(nextTopInset, nextBottomInset, Math.max(0, imeBottom), Math.max(0, systemBarsBottom));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private void emitInsetsChange(int topInset, int bottomInset, int imeBottom, int systemBarsBottom) {
|
|
55
|
+
if (getId() == View.NO_ID || !(getContext() instanceof ReactContext)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
WritableMap event = Arguments.createMap();
|
|
60
|
+
event.putDouble("top", PixelUtil.toDIPFromPixel(topInset));
|
|
61
|
+
event.putDouble("bottom", PixelUtil.toDIPFromPixel(bottomInset));
|
|
62
|
+
event.putDouble("imeBottom", PixelUtil.toDIPFromPixel(imeBottom));
|
|
63
|
+
event.putDouble("systemBarsBottom", PixelUtil.toDIPFromPixel(systemBarsBottom));
|
|
64
|
+
event.putBoolean("keyboardVisible", imeBottom > systemBarsBottom);
|
|
65
|
+
|
|
66
|
+
ReactContext reactContext = (ReactContext) getContext();
|
|
67
|
+
EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, getId());
|
|
68
|
+
if (eventDispatcher == null) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
eventDispatcher.dispatchEvent(new SagepilotInsetsChangeEvent(
|
|
73
|
+
UIManagerHelper.getSurfaceId(this),
|
|
74
|
+
getId(),
|
|
75
|
+
event
|
|
76
|
+
));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
package ai.sagepilot.reactnativesdk;
|
|
2
|
+
|
|
3
|
+
import android.view.View;
|
|
4
|
+
import com.facebook.react.common.MapBuilder;
|
|
5
|
+
import com.facebook.react.uimanager.ViewManagerDelegate;
|
|
6
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
7
|
+
import com.facebook.react.uimanager.ViewGroupManager;
|
|
8
|
+
import com.facebook.react.viewmanagers.SagepilotInsetsViewManagerDelegate;
|
|
9
|
+
import com.facebook.react.viewmanagers.SagepilotInsetsViewManagerInterface;
|
|
10
|
+
import java.util.Map;
|
|
11
|
+
|
|
12
|
+
public class SagepilotInsetsViewManager extends ViewGroupManager<SagepilotInsetsView>
|
|
13
|
+
implements SagepilotInsetsViewManagerInterface<SagepilotInsetsView> {
|
|
14
|
+
public static final String REACT_CLASS = "SagepilotInsetsView";
|
|
15
|
+
private final ViewManagerDelegate<SagepilotInsetsView> delegate = new SagepilotInsetsViewManagerDelegate<>(this);
|
|
16
|
+
|
|
17
|
+
@Override
|
|
18
|
+
protected ViewManagerDelegate<SagepilotInsetsView> getDelegate() {
|
|
19
|
+
return delegate;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Override
|
|
23
|
+
public String getName() {
|
|
24
|
+
return REACT_CLASS;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Override
|
|
28
|
+
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
|
29
|
+
return MapBuilder.of(
|
|
30
|
+
SagepilotInsetsChangeEvent.EVENT_NAME,
|
|
31
|
+
MapBuilder.of("registrationName", "onInsetsChange")
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Override
|
|
36
|
+
protected SagepilotInsetsView createViewInstance(ThemedReactContext reactContext) {
|
|
37
|
+
return new SagepilotInsetsView(reactContext);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
public void addView(SagepilotInsetsView parent, View child, int index) {
|
|
42
|
+
parent.addView(child, index);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Override
|
|
46
|
+
public int getChildCount(SagepilotInsetsView parent) {
|
|
47
|
+
return parent.getChildCount();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@Override
|
|
51
|
+
public View getChildAt(SagepilotInsetsView parent, int index) {
|
|
52
|
+
return parent.getChildAt(index);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@Override
|
|
56
|
+
public void removeViewAt(SagepilotInsetsView parent, int index) {
|
|
57
|
+
parent.removeViewAt(index);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package ai.sagepilot.reactnativesdk;
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage;
|
|
4
|
+
import com.facebook.react.bridge.NativeModule;
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager;
|
|
7
|
+
import java.util.Collections;
|
|
8
|
+
import java.util.List;
|
|
9
|
+
|
|
10
|
+
public class SagepilotReactNativeSdkPackage implements ReactPackage {
|
|
11
|
+
@Override
|
|
12
|
+
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
|
13
|
+
return Collections.emptyList();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Override
|
|
17
|
+
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
18
|
+
return Collections.singletonList(new SagepilotInsetsViewManager());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This code mirrors react-native-codegen output so Paper builds can compile when codegen is off.
|
|
3
|
+
*/
|
|
4
|
+
package com.facebook.react.viewmanagers;
|
|
5
|
+
|
|
6
|
+
import android.view.View;
|
|
7
|
+
import androidx.annotation.Nullable;
|
|
8
|
+
import com.facebook.react.uimanager.BaseViewManager;
|
|
9
|
+
import com.facebook.react.uimanager.BaseViewManagerDelegate;
|
|
10
|
+
import com.facebook.react.uimanager.LayoutShadowNode;
|
|
11
|
+
|
|
12
|
+
public class SagepilotInsetsViewManagerDelegate<
|
|
13
|
+
T extends View,
|
|
14
|
+
U extends
|
|
15
|
+
BaseViewManager<T, ? extends LayoutShadowNode> & SagepilotInsetsViewManagerInterface<T>>
|
|
16
|
+
extends BaseViewManagerDelegate<T, U> {
|
|
17
|
+
public SagepilotInsetsViewManagerDelegate(U viewManager) {
|
|
18
|
+
super(viewManager);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Override
|
|
22
|
+
public void setProperty(T view, String propName, @Nullable Object value) {
|
|
23
|
+
super.setProperty(view, propName, value);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This code mirrors react-native-codegen output so Paper builds can compile when codegen is off.
|
|
3
|
+
*/
|
|
4
|
+
package com.facebook.react.viewmanagers;
|
|
5
|
+
|
|
6
|
+
import android.view.View;
|
|
7
|
+
|
|
8
|
+
public interface SagepilotInsetsViewManagerInterface<T extends View> {
|
|
9
|
+
// No props
|
|
10
|
+
}
|
|
@@ -216,6 +216,39 @@ type SagepilotMobileState = SagepilotLifecycleState & {
|
|
|
216
216
|
theme: SagepilotMobileThemeState;
|
|
217
217
|
};
|
|
218
218
|
type SagepilotMobileSubscription = () => void;
|
|
219
|
+
type SagepilotMessageComposerMode = "auto" | "new";
|
|
220
|
+
type SagepilotConversationCreatedEvent = {
|
|
221
|
+
chat_id: string;
|
|
222
|
+
workspace_id?: string;
|
|
223
|
+
channel_id?: string;
|
|
224
|
+
session_id?: string;
|
|
225
|
+
customer_id?: string;
|
|
226
|
+
message_id?: string;
|
|
227
|
+
created_at?: string;
|
|
228
|
+
metadata?: Record<string, unknown>;
|
|
229
|
+
};
|
|
230
|
+
type SagepilotMessageComposerOptions = {
|
|
231
|
+
/**
|
|
232
|
+
* auto: prefill the composer and let the hosted widget reuse an existing
|
|
233
|
+
* conversation when one is available.
|
|
234
|
+
* new: force the hosted widget to start a fresh conversation.
|
|
235
|
+
*/
|
|
236
|
+
mode?: SagepilotMessageComposerMode;
|
|
237
|
+
/**
|
|
238
|
+
* Opens a specific hosted conversation. This value is treated as an opaque
|
|
239
|
+
* conversation handle and is verified by the hosted customer session.
|
|
240
|
+
*/
|
|
241
|
+
chatId?: string;
|
|
242
|
+
/**
|
|
243
|
+
* App-owned metadata returned to the conversation-created callback so callers
|
|
244
|
+
* can persist mappings such as order_id -> chat_id.
|
|
245
|
+
*/
|
|
246
|
+
metadata?: Record<string, unknown>;
|
|
247
|
+
/**
|
|
248
|
+
* Fires when this composer invocation creates a new conversation.
|
|
249
|
+
*/
|
|
250
|
+
onConversationCreated?: (event: SagepilotConversationCreatedEvent) => void;
|
|
251
|
+
};
|
|
219
252
|
type SagepilotChatHookState = {
|
|
220
253
|
configured: boolean;
|
|
221
254
|
isPresented: boolean;
|
|
@@ -224,13 +257,14 @@ type SagepilotChatHookState = {
|
|
|
224
257
|
theme: SagepilotMobileThemeState;
|
|
225
258
|
present: () => boolean;
|
|
226
259
|
presentMessages: () => boolean;
|
|
227
|
-
presentMessageComposer: (message?: string) => boolean;
|
|
260
|
+
presentMessageComposer: (message?: string, options?: SagepilotMessageComposerOptions) => boolean;
|
|
228
261
|
dismiss: () => boolean;
|
|
229
262
|
hide: () => boolean;
|
|
230
263
|
toggle: () => boolean;
|
|
231
264
|
identify: (identity: SagepilotIdentity) => Promise<SagepilotIdentifyResult>;
|
|
232
265
|
logout: () => Promise<SagepilotLogoutResponse>;
|
|
233
266
|
getUnreadCount: () => Promise<number>;
|
|
267
|
+
onConversationCreated: (callback: (event: SagepilotConversationCreatedEvent) => void) => SagepilotMobileSubscription;
|
|
234
268
|
};
|
|
235
269
|
type SagepilotChatProviderProps = {
|
|
236
270
|
children?: ReactNode;
|
|
@@ -250,13 +284,14 @@ declare const SagepilotChat: {
|
|
|
250
284
|
pending: boolean;
|
|
251
285
|
};
|
|
252
286
|
onIdentify: (callback: Callback<SagepilotIdentifyResult>) => SagepilotMobileSubscription;
|
|
287
|
+
onConversationCreated: (callback: Callback<SagepilotConversationCreatedEvent>) => SagepilotMobileSubscription;
|
|
253
288
|
getUnreadCount: () => Promise<number>;
|
|
254
289
|
onUnreadChange: (callback: Callback<SagepilotUnreadState>) => SagepilotMobileSubscription;
|
|
255
290
|
startUnreadPolling: (intervalMs?: number) => () => void;
|
|
256
291
|
stopUnreadPolling: () => void;
|
|
257
292
|
present: () => boolean;
|
|
258
293
|
presentMessages: () => boolean;
|
|
259
|
-
presentMessageComposer: (message?: string) => boolean;
|
|
294
|
+
presentMessageComposer: (message?: string, options?: SagepilotMessageComposerOptions) => boolean;
|
|
260
295
|
dismiss: () => boolean;
|
|
261
296
|
hide: () => boolean;
|
|
262
297
|
toggle: () => boolean;
|
|
@@ -307,4 +342,4 @@ declare function SagepilotChatProvider({ children, closeLabel, loadingLabel }: S
|
|
|
307
342
|
|
|
308
343
|
declare function useSagepilotChat(): SagepilotChatHookState;
|
|
309
344
|
|
|
310
|
-
export { type SagepilotBiometricsAdapter, type SagepilotBootstrapChannelResponse, type SagepilotCacheStorage, SagepilotChat, SagepilotChatError, type SagepilotChatErrorCode, type SagepilotChatHookState, SagepilotChatProvider, type SagepilotChatProviderProps, type SagepilotDeviceInfo, type SagepilotDeviceInfoAdapter, type SagepilotIdentifyResult, type SagepilotIdentity, type SagepilotIdentityState, type SagepilotLifecycleState, type SagepilotLogoutResponse, type SagepilotMobileBehaviorConfig, type SagepilotMobileColorScheme, type SagepilotMobileConfig, type SagepilotMobileConfigureResult, type SagepilotMobileLauncherConfig, type SagepilotMobilePresentationConfig, type SagepilotMobilePresentationStyle, type SagepilotMobileResolvedLauncherConfig, type SagepilotMobileState, type SagepilotMobileSubscription, type SagepilotMobileThemeConfig, type SagepilotMobileThemeState, type SagepilotSessionState, type SagepilotTokenStorage, type SagepilotUnreadState, createAsyncStorageCacheStorage, createKeychainTokenStorage, useSagepilotChat };
|
|
345
|
+
export { type SagepilotBiometricsAdapter, type SagepilotBootstrapChannelResponse, type SagepilotCacheStorage, SagepilotChat, SagepilotChatError, type SagepilotChatErrorCode, type SagepilotChatHookState, SagepilotChatProvider, type SagepilotChatProviderProps, type SagepilotConversationCreatedEvent, type SagepilotDeviceInfo, type SagepilotDeviceInfoAdapter, type SagepilotIdentifyResult, type SagepilotIdentity, type SagepilotIdentityState, type SagepilotLifecycleState, type SagepilotLogoutResponse, type SagepilotMessageComposerOptions, type SagepilotMobileBehaviorConfig, type SagepilotMobileColorScheme, type SagepilotMobileConfig, type SagepilotMobileConfigureResult, type SagepilotMobileLauncherConfig, type SagepilotMobilePresentationConfig, type SagepilotMobilePresentationStyle, type SagepilotMobileResolvedLauncherConfig, type SagepilotMobileState, type SagepilotMobileSubscription, type SagepilotMobileThemeConfig, type SagepilotMobileThemeState, type SagepilotSessionState, type SagepilotTokenStorage, type SagepilotUnreadState, createAsyncStorageCacheStorage, createKeychainTokenStorage, useSagepilotChat };
|
package/dist/index.d.ts
CHANGED
|
@@ -216,6 +216,39 @@ type SagepilotMobileState = SagepilotLifecycleState & {
|
|
|
216
216
|
theme: SagepilotMobileThemeState;
|
|
217
217
|
};
|
|
218
218
|
type SagepilotMobileSubscription = () => void;
|
|
219
|
+
type SagepilotMessageComposerMode = "auto" | "new";
|
|
220
|
+
type SagepilotConversationCreatedEvent = {
|
|
221
|
+
chat_id: string;
|
|
222
|
+
workspace_id?: string;
|
|
223
|
+
channel_id?: string;
|
|
224
|
+
session_id?: string;
|
|
225
|
+
customer_id?: string;
|
|
226
|
+
message_id?: string;
|
|
227
|
+
created_at?: string;
|
|
228
|
+
metadata?: Record<string, unknown>;
|
|
229
|
+
};
|
|
230
|
+
type SagepilotMessageComposerOptions = {
|
|
231
|
+
/**
|
|
232
|
+
* auto: prefill the composer and let the hosted widget reuse an existing
|
|
233
|
+
* conversation when one is available.
|
|
234
|
+
* new: force the hosted widget to start a fresh conversation.
|
|
235
|
+
*/
|
|
236
|
+
mode?: SagepilotMessageComposerMode;
|
|
237
|
+
/**
|
|
238
|
+
* Opens a specific hosted conversation. This value is treated as an opaque
|
|
239
|
+
* conversation handle and is verified by the hosted customer session.
|
|
240
|
+
*/
|
|
241
|
+
chatId?: string;
|
|
242
|
+
/**
|
|
243
|
+
* App-owned metadata returned to the conversation-created callback so callers
|
|
244
|
+
* can persist mappings such as order_id -> chat_id.
|
|
245
|
+
*/
|
|
246
|
+
metadata?: Record<string, unknown>;
|
|
247
|
+
/**
|
|
248
|
+
* Fires when this composer invocation creates a new conversation.
|
|
249
|
+
*/
|
|
250
|
+
onConversationCreated?: (event: SagepilotConversationCreatedEvent) => void;
|
|
251
|
+
};
|
|
219
252
|
type SagepilotChatHookState = {
|
|
220
253
|
configured: boolean;
|
|
221
254
|
isPresented: boolean;
|
|
@@ -224,13 +257,14 @@ type SagepilotChatHookState = {
|
|
|
224
257
|
theme: SagepilotMobileThemeState;
|
|
225
258
|
present: () => boolean;
|
|
226
259
|
presentMessages: () => boolean;
|
|
227
|
-
presentMessageComposer: (message?: string) => boolean;
|
|
260
|
+
presentMessageComposer: (message?: string, options?: SagepilotMessageComposerOptions) => boolean;
|
|
228
261
|
dismiss: () => boolean;
|
|
229
262
|
hide: () => boolean;
|
|
230
263
|
toggle: () => boolean;
|
|
231
264
|
identify: (identity: SagepilotIdentity) => Promise<SagepilotIdentifyResult>;
|
|
232
265
|
logout: () => Promise<SagepilotLogoutResponse>;
|
|
233
266
|
getUnreadCount: () => Promise<number>;
|
|
267
|
+
onConversationCreated: (callback: (event: SagepilotConversationCreatedEvent) => void) => SagepilotMobileSubscription;
|
|
234
268
|
};
|
|
235
269
|
type SagepilotChatProviderProps = {
|
|
236
270
|
children?: ReactNode;
|
|
@@ -250,13 +284,14 @@ declare const SagepilotChat: {
|
|
|
250
284
|
pending: boolean;
|
|
251
285
|
};
|
|
252
286
|
onIdentify: (callback: Callback<SagepilotIdentifyResult>) => SagepilotMobileSubscription;
|
|
287
|
+
onConversationCreated: (callback: Callback<SagepilotConversationCreatedEvent>) => SagepilotMobileSubscription;
|
|
253
288
|
getUnreadCount: () => Promise<number>;
|
|
254
289
|
onUnreadChange: (callback: Callback<SagepilotUnreadState>) => SagepilotMobileSubscription;
|
|
255
290
|
startUnreadPolling: (intervalMs?: number) => () => void;
|
|
256
291
|
stopUnreadPolling: () => void;
|
|
257
292
|
present: () => boolean;
|
|
258
293
|
presentMessages: () => boolean;
|
|
259
|
-
presentMessageComposer: (message?: string) => boolean;
|
|
294
|
+
presentMessageComposer: (message?: string, options?: SagepilotMessageComposerOptions) => boolean;
|
|
260
295
|
dismiss: () => boolean;
|
|
261
296
|
hide: () => boolean;
|
|
262
297
|
toggle: () => boolean;
|
|
@@ -307,4 +342,4 @@ declare function SagepilotChatProvider({ children, closeLabel, loadingLabel }: S
|
|
|
307
342
|
|
|
308
343
|
declare function useSagepilotChat(): SagepilotChatHookState;
|
|
309
344
|
|
|
310
|
-
export { type SagepilotBiometricsAdapter, type SagepilotBootstrapChannelResponse, type SagepilotCacheStorage, SagepilotChat, SagepilotChatError, type SagepilotChatErrorCode, type SagepilotChatHookState, SagepilotChatProvider, type SagepilotChatProviderProps, type SagepilotDeviceInfo, type SagepilotDeviceInfoAdapter, type SagepilotIdentifyResult, type SagepilotIdentity, type SagepilotIdentityState, type SagepilotLifecycleState, type SagepilotLogoutResponse, type SagepilotMobileBehaviorConfig, type SagepilotMobileColorScheme, type SagepilotMobileConfig, type SagepilotMobileConfigureResult, type SagepilotMobileLauncherConfig, type SagepilotMobilePresentationConfig, type SagepilotMobilePresentationStyle, type SagepilotMobileResolvedLauncherConfig, type SagepilotMobileState, type SagepilotMobileSubscription, type SagepilotMobileThemeConfig, type SagepilotMobileThemeState, type SagepilotSessionState, type SagepilotTokenStorage, type SagepilotUnreadState, createAsyncStorageCacheStorage, createKeychainTokenStorage, useSagepilotChat };
|
|
345
|
+
export { type SagepilotBiometricsAdapter, type SagepilotBootstrapChannelResponse, type SagepilotCacheStorage, SagepilotChat, SagepilotChatError, type SagepilotChatErrorCode, type SagepilotChatHookState, SagepilotChatProvider, type SagepilotChatProviderProps, type SagepilotConversationCreatedEvent, type SagepilotDeviceInfo, type SagepilotDeviceInfoAdapter, type SagepilotIdentifyResult, type SagepilotIdentity, type SagepilotIdentityState, type SagepilotLifecycleState, type SagepilotLogoutResponse, type SagepilotMessageComposerOptions, type SagepilotMobileBehaviorConfig, type SagepilotMobileColorScheme, type SagepilotMobileConfig, type SagepilotMobileConfigureResult, type SagepilotMobileLauncherConfig, type SagepilotMobilePresentationConfig, type SagepilotMobilePresentationStyle, type SagepilotMobileResolvedLauncherConfig, type SagepilotMobileState, type SagepilotMobileSubscription, type SagepilotMobileThemeConfig, type SagepilotMobileThemeState, type SagepilotSessionState, type SagepilotTokenStorage, type SagepilotUnreadState, createAsyncStorageCacheStorage, createKeychainTokenStorage, useSagepilotChat };
|