React Native Web View SDK
Prerequisites
Contact Center for React Native displays a chatbox with an agent. Before installation, you need to have wsToken (or your inbox identifier) that is mandatory to be used to connect with your inbox by using this SDK. Also additional credentials for agent and supervisor account start having chat / call interaction.
Install
npm install @squantumengine/react-native-sqecc
yarn add @squantumengine/react-native-sqecc
pnpm install @squantumengine/react-native-sqecc
And also install the peer dependencies:
npm install react-native-webview react-native-permissions react-native-keep-awake @types/react-native-keep-awake
yarn add react-native-webview react-native-permissions react-native-keep-awake @types/react-native-keep-awake
pnpm install react-native-webview react-native-permissions react-native-keep-awake @types/react-native-keep-awake
Usage
Basic
// YourScreen.ts
import React from 'react';
import { SafeAreaView } from 'react-native';
import { ContactCenter } from '@squantumengine/sqecc-react-native';
function App(): JSX.Element {
return (
<SafeAreaView style={{ flex: 1 }}>
<ContactCenter
wsToken="[your wsToken]"
env="staging" // staging | production
/>
</SafeAreaView>
);
}
export default App;
Using the provided utility function
// YourScreen.ts
import React from 'react';
import { SafeAreaView } from 'react-native';
import {
ContactCenter,
useContactCenter,
} from '@squantumengine/sqecc-react-native';
function App(): JSX.Element {
const client = useContactCenter();
const yourHandlerOne = () => client.toggleChat(true);
const yourHandlerTwo = () => client.prefillForm('Sidu', 'sidu@smma.id', '0812889999999');
return (
<SafeAreaView style={{ flex: 1 }}>
<ContactCenter
wsToken="[your wsToken]"
env="staging" // staging | production
client={client} // mandatory to enable utility function
/>
</SafeAreaView>
);
}
export default App;
Custom handler with event listener
// YourScreen.ts
import React from 'react';
import { SafeAreaView } from 'react-native';
import {
ContactCenter,
ContactCenterEvent,
useContactCenter,
} from '@squantumengine/sqecc-react-native';
function App(): JSX.Element {
const client = useContactCenter();
const onEvent = (event: ContactCenterEvent) => {
if (event === ContactCenterEvent.WIDGET_READY) {
/**
* component has been mounted and display
* can be used for prefill form or call other utility function
* e.g client.prefillForm({ name: "Sidu", email: "sidu@smma.id" });
*/
} else if (event === ContactCenterEvent.END_JOURNEY) {
/**
* when customer is finished chat
* can be used for redirect to another screen or closing the screen
* e.g navigation.goBack();
*/
}
};
return (
<KeyboardAvoidingView style={{flex: 1}} behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
<SafeAreaView style={{flex: 1}}>
<ContactCenter
client={client}
wsToken="[your wsToken]"
env="staging"
onEvent={onEvent}
/>
</SafeAreaView>
</KeyboardAvoidingView>
);
}
export default App;
API
Contact Center
| Property | Description | Type | Default | Mandatory |
|---|---|---|---|---|
| wsToken | Inbox identifier to connect chat with your inbox | String | "" | Yes |
| env | Specifies the environment setup for the contact center widget. If set to staging or production, it will use the default host provided by SQECC for the respective environment. Ignored if the host property is provided. | staging | production | production | No |
| host | Self-hosted URL which includes the contact center widget. If provided, env prop will be ignored. | String | undefined | No |
| client | Client instance to enable utility function. Created by useContactCenter() hooks. | Object | undefined | No |
| autoRequestPermissions | Auto-check and display popup permission required when interaction needs specific device access. | boolean | false | No |
| options | Config for particular behavior, currently available: MultipleToken: enable multiple tokens by multiple referenceId; skipForm: not displaying the customer form; showChatWindow: determines whether to show the chatbox window. Default is true (if set to false, toggle show chat during video call will not be shown). | Object | {} | No |
| onEvent | Event listener for specific event activity in contact center | (event: ContactCenterEvent) => void; | undefined | No |
Utility function by useContactCenter() hooks
| Function | Description | Params Type |
|---|---|---|
| toggleChat | Set chat widget to be open or close | boolean |
| prefillForm | Fill customer detail form field: name, email, and phone | CCUserProps |
| prefillAndConnect | Fill customer detail and automatically connect with conversation | CCUserProps |
| setMetadata | Set metadata to be used in conversation (e.g., reference_id, NIK) | Record<string, any> |
| reset | Reset all state stored in the session (e.g., prefilled customer data and conversation) | None |
| setPredefinedItems | Send predefined item to conversation (can be a TEXT or a FILE). For FILE type, two fields are mandatory: content and fileName. For content, we receive and support the following types: URL, Blob, Base64. | PredefinedItem[] |
Device Permissions And Foreground Service Setup
For some action during chat activity might require specific device permission (e.g camera access or microphone). You can utilize the following configuration template for setting up.
Also, you need to add com.sqeccreactnative.MicForegroundService. This service is required to handle microphone operations when the app goes to background, ensuring a seamless user experience.
Android
<manifest xlmns:android...>
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />
<uses-permission android:name="android.permission.AUDIO_CAPTURE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<application ... >
<service android:name="com.sqeccreactnative.MicForegroundService"
android:foregroundServiceType="microphone"
android:enabled="true"
android:exported="true"/>
</application>
</manifest>
IOS
Configure react-native-permissions
to enable autoRequestPermissions need follow installation setup by https://www.npmjs.com/package/react-native-permissions
below is the copy for the react-native-permissions installation setup:
below is the copy for react-native-permissions instalation setup
- with react-native >= 0.72
- Resolve react_native_pods.rb with node to allow for hoisting
- require Pod::Executable.execute_command('node', ['-p',
- 'require.resolve(
- "react-native/scripts/react_native_pods.rb",
- {paths: [process.argv[1]]},
- )', __dir__]).strip
+ def node_require(script)
+ # Resolve script with node to allow for hoisting
+ require Pod::Executable.execute_command('node', ['-p',
+ "require.resolve(
+ '#{script}',
+ {paths: [process.argv[1]]},
+ )", __dir__]).strip
+ end
+ node_require('react-native/scripts/react_native_pods.rb')
+ node_require('react-native-permissions/scripts/setup.rb')
- with react-native < 0.72
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
+ require_relative '../node_modules/react-native-permissions/scripts/setup'
Then in the same file, add a setup_permissions call with the wanted permissions:
platform :ios, min_ios_version_supported
prepare_react_native_project!
# ⬇️ uncomment wanted permissions (don't forget to remove the last comma)
setup_permissions([
# 'AppTrackingTransparency',
# 'BluetoothPeripheral',
# 'Calendars',
# 'Camera',
# 'Contacts',
# 'FaceID',
# 'LocationAccuracy',
# 'LocationAlways',
# 'LocationWhenInUse',
# 'MediaLibrary',
# 'Microphone',
# 'Motion',
# 'Notifications',
# 'PhotoLibrary',
# 'PhotoLibraryAddOnly',
# 'Reminders',
# 'SpeechRecognition',
# 'StoreKit'
])
Additional Setup
to make the permission available during popup request, also add the permission related key and description message in your Info.plist file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
<key>NSCameraUsageDescription</key>
<string>This app requires to access your photo library</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires to access your microphone</string>
</dict>
</plist>
Example Implementation
import { StyleSheet, SafeAreaView } from 'react-native';
import {
ContactCenter,
ContactCenterEvent,
useContactCenter,
PredefinedTypeEnum,
} from '@squantumengine/sqecc-react-native';
import * as React from 'react';
import AudioPicker from '../components/AudioPicker';
const ContactCenterScreen = ({ route }: any) => {
const env = route?.params?.env || 'staging';
const wsToken = route?.params?.wsToken || '';
const prefill: any = route?.params?.prefill || {};
const metadata = route?.params?.metadata || {};
const MultipleToken = route?.params?.isMultipleToken || false;
const client = useContactCenter();
const onEvent = (event: ContactCenterEvent) => {
if (event === ContactCenterEvent.WIDGET_READY) {
metadata && client.setMetadata(metadata);
prefill && client.prefillAndConnect(prefill);
client.setPredefinedItems([
{
type: PredefinedTypeEnum.FILE,
content:
'https://media.suara.com/pictures/653x366/2021/06/12/65310-ktp-valerie-tifanka.jpg',
fileName: 'sample.jpg',
},
]);
}
};
return (
<SafeAreaView style={styles.container}>
<AudioPicker />
<ContactCenter
client={client}
wsToken={wsToken}
env={env}
onEvent={onEvent}
options={{ MultipleToken }}
autorequestPermission={true}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({ container: { flex: 1 } });
export default ContactCenterScreen;
Contact Center Events
The list of events defined in ContactCenterEvent enum, a set of events that are used within the Contact Center SDK to represent various states and actions during the lifecycle of a conversation or call. These events are used for handling and reacting state of user interactions within the chat or call widgets for specific use cases.
| Event | Description |
|---|---|
| WIDGET_READY | Triggered when the chat widget is fully loaded and ready for interaction. Indicates that the widget has been initialized and is displayed on the screen. |
| INIT_CONVERSATION | Fired when the initial conversation is being set up but before it starts. |
| WAITING_AGENT | Occurs when the system is waiting for an agent to join the conversation. |
| START_CONVERSATION | Triggered when the conversation with the agent begins, marking the start of the interactive session. |
| CLOSE_CONVERSATION | Fired when the conversation ends, either by the agent or the user. |
| INIT_CALL | Occurs when a call is initiated. Used to prepare the UI for an upcoming call. |
| WAITING_CALL | Fired when the system is waiting for the call to be connected. |
| START_CALL | Triggered when the call starts, marking the beginning of an audio or video call. |
| CLOSE_CALL | Fired when the call ends by customer itself or Agent. used to redirect to another screen. |
| END_JOURNEY | Indicates the end of the user's journey within the chat or call, used to redirect to another screen because the conversation is ended. |
| OPEN_WIDGET | Fired when the chat widget is opened by click, used to track when the user begins interacting with the widget. |
| CLOSE_WIDGET | Triggered when the widget is closed by click. |
| UPLOAD_FILE | Occurs when a file is being uploaded within the conversation. |
| ON_CAMERA | Fired when the user's camera is turned on during a call. |
| OFF_CAMERA | Triggered when the user's camera is turned off during a call. |
| ON_MIC | Occurs when the user's microphone is turned on. |
| OFF_MIC | Fired when the user's microphone is turned off. |
| CLOSURE_CONVERSATION | Indicates that the conversation is in the closure state which triggered by Agent |
| MESSAGE | Fired whenever a new message is received or sent within the chat. |
| CLICK_ATTACHMENT_CAMERA | Occurs when the user clicks on the camera attachment option within the widget. |
| CLICK_ATTACHMENT_DOCUMENT | Fired when the user clicks on the document attachment option. |
| CLICK_ATTACHMENT_GALLERY | Triggered when the user clicks on the gallery attachment option. |
| WEBSOCKET_ERROR | Indicates an error with the WebSocket connection. Used to display an error message or attempt a reconnection. |
| INVALIDATE_TOKEN | Fired when the conversation token is invalidated. |
| WEBSOCKET_CONNECTION_ERROR | Triggered when there is a connection error with the WebSocket. Used to handle connection failures. |
| WEBSOCKET_RECONNECTING | Occurs when the WebSocket is attempting to reconnect after a disconnection. |
| NETWORK_OFFLINE | Fired when the network is detected to be offline. Used to display an offline message. |
| WEBSOCKET_RECONNECTING_COUNT | Indicates the number of times the WebSocket has attempted to reconnect. |
Compatibility Support
- For supporting lower Android OS Device (e.g OS version 5 and 6) all request to outside origin domain CA should be issued by GTS (Google Trusted Services) due to limited CA listed supported by lower OS version to resolve SSL issue.