Signed Call React Native for M2P Campaigns
Learn how to integrate Signed Call React Native SDK in your application to avail the Signed Call Machine-to-Person (M2P) feature.
Overview
CleverTap allows In-App Machine-to-Person (M2P) campaign calls via the Signed Call React Native SDK, enabling you to receive calls in any React Native application if the device has an internet connection and Signed Call React Native SDK. This document provides information about:
- Signed Call React Native SDK integration
- Managing Signed Calls from your React Native application
For more information about Signed Call, refer to Signed Call.
Prerequisites
The prerequisites for the integration vary depending on the platforms:
For Android Platform
Here are the requirements for integrating the Signed Call React Native SDK into the Android platform:
- SDK version 21 and above
- Java version 8 and above
- Application permissions for the following:
- Notification (Required for Android 13 and above)
- Read Phone State (Optional)
iOS Platform
CleverTap will soon start iOS Platform Support for M2P campaigns.
Integrate Signed Call React Native SDK
There are four major steps for integrating Signed Call React Native SDK:
- Add CleverTap React Native Package to Project.
- Set Up Signed Call Native SDKs.
- Initialize and Authenticate Signed Call React Native SDK.
- Manage Permissions.
Add CleverTap React Native Package to Project
To integrate the Signed Call React Native SDK, add the CleverTap React Native SDK/Package to your project using Yarn or NPM as shown below:
yarn add @clevertap/[email protected]
npm install @clevertap/[email protected]
Set Up Signed Call Android SDKs
To set up the Signed Call Android SDK, follow these steps:
- Include
mavenCentral
in your project-levelbuild.gradle
file as follows:
allprojects {
repositories {
mavenCentral()
}
}
- Add the following code to the dependencies element of the
build.gradle
file of your application module:
//To integrate Signed Call Android SDK,
implementation "com.clevertap.android:clevertap-signedcall-sdk:0.0.6.2-m2p-beta"
//To enable the socket-based signaling channel
implementation('io.socket:socket.io-client:2.1.0') {
exclude group: 'org.json', module: 'json'
}
//To load the image assets on the call screens
implementation 'com.github.bumptech.glide:glide:4.12.0'
//To process the incoming call push for the receiver
implementation 'androidx.work:work-runtime:2.7.1'
//To build a responsive UI for the call screens
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
The Signed Call Android SDK uses CleverTap Android SDK for analytics. This requires an active CleverTap instance as a parameter during the SDK initialization. To integrate the CleverTap Android SDK, refer to CleverTap Android SDK Integration.
Signed Call React Native SDK Compatibility
The Signed Call React Native SDK v0.0.6-m2p.2 is compatible with Signed Call Android SDK v0.0.6.2-m2p-beta or higher and CleverTap Android SDK v6.2.0 or higher.
The Signed Call Android SDK uses FCM dependency to fetch the device FCM token required for successful SDK initialization. The Signed Call then uses this FCM token to enable calls via the FCM-based call routing channel.
- Add the following code to include the FCM dependency in the application module's dependency element:
implementation 'com.google.firebase:firebase-messaging:21.0.0'
FCM Version
The minimum supported version of FCM must be v21.0.0 or higher to integrate with your Android platform.
Initialize Signed Call React Native SDK
To initialize Signed Call React Native SDK in your JavaScript or TypeScript code, call the init
method on the SignedCall
reference as shown below:
static initialize(initProperties: object): Promise<SignedCallResponse>
This method returns a Promise object. To get the results, use the then()
method as follows:
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
SignedCall.initialize(initProperties)
.then((response: SignedCallResponse) => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
const error = response.error;
const errorCode = error?.errorCode;
const errorMessage = error?.errorMessage;
const errorDescription = error?.errorDescription;
console.log(
'Signed Call initialization failed: \n' +
'error-code: ' + errorCode + '\n' +
'error-message: ' + errorMessage + '\n' +
'error-description: ' + errorDescription
);
}
})
.catch((e: any) => {
console.error(e);
});
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
SignedCall.initialize(initProperties)
.then(response => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
const error = response.error;
const errorCode = error?.errorCode;
const errorMessage = error?.errorMessage;
const errorDescription = error?.errorDescription;
console.log(
'Signed Call initialization failed: \n' +
'error-code: ' + errorCode + '\n' +
'error-message: ' + errorMessage + '\n' +
'error-description: ' + errorDescription
);
}
})
.catch(e => {
console.error(e);
});
The initProperties
is a Map object with the following properties:
Properties | Description | Type | Comments |
---|---|---|---|
accountId | The unique identity of the client account. It is available from the CleverTap dashboard. | String | Required |
apiKey | The unique identity of the client's account. It is available from the CleverTap dashboard. | String | Required |
cuid | The unique identity of the user. | String | Required |
m2pConfiguration | It configures the content of the foreground notification, which SDK uses to preprocess the received campaign calls. For more information, refer to Configure Machine-to-Person (M2P) Feature. | Object | Required |
missedCallActions |
| Object | Optional |
promptReceiverReadPhoneStatePermission | When the receiver answers the call, it prompts the receiver with Read Phone State permission. The SDK uses Read Phone State permission to enable busy handling for PSTN calls. The default value is false. For more information, refer to Read Phone State. | Boolean | Optional |
promptPushPrimer | It enables the Push Primer to support Android 13 changes for the Runtime Notification Permission. For more information, refer to Android 13 Changes. | Object | Optional |
notificationPermissionRequired | It indicates whether notification permission is required for the SDK initialization on Android 13 and onwards. The default value is true. For more information, refer to its usage. | Boolean | Optional |
overrideDefaultBranding | It overrides the call screen branding set from the dashboard. The default branding is the one you set from the dashboard. For more, refer to its usage. | Object | Optional |
CUID Validation Rules
The following are the validation rules for
cuid
:
- The characters must range between 5 to 50. For earlier SDK versions, limit characters to less than 15.
- Start with either alphabet or a number.
- The name is case-sensitive, and only '_' is allowed as a special character.
- Cannot be of type number-number, i.e. a number followed by a special character, which is again followed by another number. For example, org_25 is allowed, but 91_8899555 is not permitted.
- Must be unique for every user.
- Must be unique for every device to allow multiple logins for the user from different devices. In such cases, the user will have multiple
cuid
's.
The syntax for initProperties
is as follows:
import { Platform } from 'react-native';
let initProperties: { [k: string]: any } = {
accountId: <string / required>,
apiKey: <string / required>,
cuid: <string / required>,
promptReceiverReadPhoneStatePermission: <boolean / optional>,
promptPushPrimer: <object / optional>,
notificationPermissionRequired: <boolean / optional>,
overrideDefaultBranding: <object / optional>,
missedCallActions = <object / optional>,
}
import { Platform } from 'react-native';
let initProperties = {
accountId: <string / required>,
cuid: <string / required>,
promptReceiverReadPhoneStatePermission: <boolean / optional>,
promptPushPrimer: <object / optional>,
notificationPermissionRequired: <boolean / optional>,
overrideDefaultBranding: <object / optional>,
missedCallActions = <object / optional>,
}
Configure Machine-to-Person (M2P) Feature
The Signed Call React Native SDK runs a foreground service on the Android platform to communicate with the server before the actual campaign call and fetch information about the campaign meta and flow. During this process, the SDK displays a foreground notification to the user. After processing, the SDK replaces the foreground notification with the incoming call notification.
Note
The foreground service keeps the application in the wake state, reducing the chances of communication failures due to network or device restrictions imposed by the Android OS or OEM.
To configure the foreground notification, use the m2pConfiguration
parameter of the object
type inside the initProperties
as follows.
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let m2pConfiguration = {
title: '<title>', // Required
subTitle: '<subTitle>', // Required
cancelCtaLabel: '<cancelCtaLabel>', // Optional
largeIcon: '<resource_name_in_android_drawable_folder>", // Optional
};
let initProperties = {
....
m2pConfiguration: m2pConfiguration,
....
};
SignedCall.initialize(initProperties)
.then((response: SignedCallResponse) => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch((e: any) => {
console.error(e);
});
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let m2pConfiguration = {
title: '<title>', // Required
subTitle: '<subTitle>', // Required
cancelCtaLabel: '<cancelCtaLabel>', // Optional
largeIcon: '<resource_name_in_android_drawable_folder>", // Optional
};
let initProperties = {
....
m2pConfiguration: m2pConfiguration,
....
};
SignedCall.initialize(initProperties)
.then(response => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch(e => {
console.error(e);
});
The following table provides information about the parameters used in the m2pConfiguration
object:
Method Name | Description | Type | Required/Optional |
---|---|---|---|
title | Denotes the title text. The maximum character limit is 65 characters. | String | Required |
subtitle | Denotes the subtitle text. The maximum character limit is 240 characters. | String | Required |
largeIcon | Denotes the name of the drawable resource under android/app/src/res/drawable folder. | String | Optional |
cancelCtaLabel | Serves as an alternative for manual dismissal of the notification, ensuring users have an option if it does not disappear automatically. | String | Optional |
overrideDefaultBranding
CleverTap dashboard provides a branding tool to alter the look and feel of the call screens. If you have multiple applications to integrate with the Signed Call SDK, all those applications will share the same branding you have set from the CleverTap dashboard. By overriding the dashboard's call screen branding, you can have different branding for each application.
Use an optional overrideDefaultBranding
parameter of the object
type inside the initProperties
to override the dashboard branding for call screens.
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let callScreenBranding = {
bgColor: '<hex color code>', //The background color of the call screens
fontColor: '<hex color code>', //The color of the text displayed on the call screens
logoUrl: '<https url>', //The image URL that renders on the call screens.
buttonTheme: 'light' or "dark", //The theme of the control buttons shown on the ongoing call screen(i.e. Mute, Speaker and Bluetooth)
};
let initProperties = {
....
overrideDefaultBranding: callScreenBranding,
....
};
SignedCall.initialize(initProperties)
.then((response: SignedCallResponse) => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch((e: any) => {
console.error(e);
});
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let callScreenBranding = {
bgColor: '<hex color code>', //The background color of the call screens
fontColor: '<hex color code>', //The color of the text displayed on the call screens
logoUrl: '<https url>', //The image URL that renders on the call screens.
buttonTheme: 'light' or "dark", //The theme of the control buttons shown on the ongoing call screen(i.e. Mute, Speaker and Bluetooth)
};
let initProperties = {
....
overrideDefaultBranding: callScreenBranding,
....
};
SignedCall.initialize(initProperties)
.then(response => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch(e => {
console.error(e);
});
Manage Permission
The following permissions are required for the Signed Call React Native SDK integration:
Read Phone State
This is an optional permission. The Signed Call React Native SDK uses this permission to enable busy handling for Public Switched Telephone Network (PSTN) calls. This permission determines if the receiver is available or engaged on a PSTN call. We recommend you add the required handling to request the Read Phone State permission before initiating a call.
Use the promptReceiverReadPhoneStatePermission
parameter of the boolean
type inside the initProperties
as shown below, allow the Signed Call React Native SDK to prompt the read phone state permission at the receiver's end when the receiver answers the call.
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let initProperties = {
....
promptReceiverReadPhoneStatePermission: true/false,
....
};
SignedCall.initialize(initProperties)
.then((response: SignedCallResponse) => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch((e: any) => {
console.error(e);
});
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let initProperties = {
....
promptReceiverReadPhoneStatePermission: true/false,
....
};
SignedCall.initialize(initProperties)
.then(response => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch(e => {
console.error(e);
});
Notification Permission
This is a required permission. All applications running on Android 13 and above must request Runtime Notification Permission from the user before sending notifications.
For the Android platform, the Signed Call React Native SDK utilizes both local and remote notifications during VoIP calls. Therefore, notification permission is required from the user to initialize the Signed Call Flutter SDK.
Push Primer for Push Notification Permission
The Push Primer is a local In-App notification that educates users about the context of the notification before requesting permission.
To initialize the Signed Call React Native SDK for Android 13 and above, you can enable the Push Primer using any of the following:
Enable Push Primer via CleverTap React Native SDK
CleverTap React Native SDK v1.0.0 and above supports Push Primer. For more information, refer to CleverTap React Native Push Primer.
Enable Push Primer via Signed Call React Native SDK
The Signed Call React Native SDK enables you to display Push Primer using an optional promptPushPrimer
parameter of Object type inside the initProperties
. It ensures that the initialization happens after the notification permission is granted using Push Primer.
To configure the Push Primer:
- Create a Push Primer configuration using the In-App campaign's Half-Interstitial or Alert template.
//Creates push primer config using Half-Interstitial template
const pushPrimerConfig = {
inAppType: 'half-interstitial',
titleText: 'Get Notified',
messageText:'Please enable notifications on your device to use Push Notifications.',
followDeviceOrientation: true,
positiveBtnText: 'Allow',
negativeBtnText: 'Cancel',
backgroundColor: '#FFFFFF',
btnBorderColor: '#0000FF',
titleTextColor: '#0000FF',
messageTextColor: '#000000',
btnTextColor: '#FFFFFF',
btnBackgroundColor: '#0000FF',
btnBorderRadius: '2',
fallbackToSettings: true, //Setting this parameter to true will open an in-App to redirect you to Mobile's OS settings page.
};
//Creates push primer config using Alert template
const pushPrimerConfig = {
inAppType: 'alert',
titleText: 'Get Notified',
messageText: 'Enable Notification permission',
followDeviceOrientation: true,
positiveBtnText: 'Allow',
negativeBtnText: 'Cancel',
fallbackToSettings: true, //Setting this parameter to true will open an in-App to redirect you to Mobile's OS settings page.
};
//Creates push primer config using Half-Interstitial template
const pushPrimerConfig = {
inAppType: 'half-interstitial',
titleText: 'Get Notified',
messageText:'Please enable notifications on your device to use Push Notifications.',
followDeviceOrientation: true,
positiveBtnText: 'Allow',
negativeBtnText: 'Cancel',
backgroundColor: '#FFFFFF',
btnBorderColor: '#0000FF',
titleTextColor: '#0000FF',
messageTextColor: '#000000',
btnTextColor: '#FFFFFF',
btnBackgroundColor: '#0000FF',
btnBorderRadius: '2',
fallbackToSettings: true, //Setting this parameter to true will open an in-App to redirect you to Mobile's OS settings page.
};
//Creates push primer config using Alert template
const pushPrimerConfig = {
inAppType: 'alert',
titleText: 'Get Notified',
messageText: 'Enable Notification permission',
followDeviceOrientation: true,
positiveBtnText: 'Allow',
negativeBtnText: 'Cancel',
fallbackToSettings: true, //Setting this parameter to true will open an in-App to redirect you to Mobile's OS settings page.
};
- Pass the Push Primer configuration inside the
promptPushPrimer
parameter of theinitProperties
. It displays the Push Primer during the SDK initialization.
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let initProperties = {
....
promptPushPrimer: pushPrimerConfig,
....
};
SignedCall.initialize(initProperties)
.then((response: SignedCallResponse) => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch((e: any) => {
console.error(e);
});
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let initProperties = {
....
promptPushPrimer: pushPrimerConfig,
....
};
SignedCall.initialize(initProperties)
.then(response => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch(e => {
console.error(e);
});
Note
- The above configuration enables the Push Primer only if the device and application both target Android 13 (API level 33) or higher.
- During the SDK initialization, Signed Call React Native SDK registers a listener to obtain the result of the push notification permission request. After registration, this listener continues monitoring the permission result, even if the Push Primer prompt is displayed from the CleverTap Flutter SDK.
- If the notification permission is denied, the Signed Call React Native SDK returns an exception within the promise object that is associated to the
SignedCall.initialize(..)
method.
Configure Notification Permission as Optional
Expected SDK Behaviour without Notification Permission
- Avoid making notification permissions optional. Without this permission, the SDK can only display the call screen on Android 13 and above when the app is in the foreground. Otherwise, incoming calls are automatically declined, triggering the
CallStatus.DeclinedDueToNotificationsDisabled
event in theSignedCall.SignedCallOnCallStatusChanged
listener.- If you decide to set notification permissions as optional, implementing the
SignedCall.SignedCallOnCallStatusChanged
listener is essential.
Starting with Android 13, the Signed Call React Native SDK requires notification permission to display call notifications, allowing users to interact with and return to calls.
By default, the SDK needs this permission for initialization. If it is not granted, the SDK returns an exception within the promise
object linked to the SignedCall.initialize(..)
method.
To make notification permission optional during SDK initialization, set the notificationPermissionRequired
parameter of the initProperties
to false, as shown below:
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let initProperties = {
....
notificationPermissionRequired: <true/false>,
....
};
SignedCall.initialize(initProperties)
.then((response: SignedCallResponse) => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch((e: any) => {
console.error(e);
});
import {
SignedCall,
SignedCallResponse,
} from '@clevertap/clevertap-signed-call-react-native';
let initProperties = {
....
notificationPermissionRequired: <true/false>,
....
};
SignedCall.initialize(initProperties)
.then(response => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch(e => {
console.error(e);
});
Log Out Signed Call React Native SDK
When the Signed Call React Native SDK initializes, the init configuration is maintained in a local session. Use the logout()
method to invalidate the active session and disable the Signed Call functionality (receiving the M2P campaigns). To enable it again, repeat the steps listed under Initialize Signed Call React Native SDK.
SignedCall.logout();
SignedCall.logout();
Receive an M2P Campaign Call
Signed Call uses the FCM routing channel to receive M2P campaign calls at the receiver's end:
FCM Version
The minimum supported version of FCM must be v21.0.0 or higher to integrate with your Android platform.
To enable the FCM channel, follow these steps:
- Add your FCM Server Key to the Signed Call section of the CleverTap dashboard. Ignore this step if you have already added it.
- Allow CleverTap Android SDK to process the FCM push of VoIP call by adding the following entries to your
AndroidManifest.xml
file.
<application>
....
....
<service android:name="com.clevertap.android.sdk.pushnotification.fcm.FcmMessageListenerService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
....
</application>
- Add the following code to your Application class:
CleverTapAPI.setSignedCallNotificationHandler(new SignedCallNotificationHandler());
CleverTapAPI.setSignedCallNotificationHandler(SignedCallNotificationHandler())
The setup for campaign calls via the FCM channel is now complete.
Handle Call Events (All Platforms)
To define custom handling for call-related events, you must register the SignedCall.SignedCallOnCallStatusChanged
listener. This listener provides an object - CallStatusDetails
containing information about the call.
Refer to the code below to define custom handling for distinct call events:
import {
SignedCall,
CallDirection,
CallStatus,
CallType,
CallStatusDetails
} from '@clevertap/clevertap-signed-call-react-native';
//To start observing the changes in a call states.
SignedCall.addListener(
SignedCall.SignedCallOnCallStatusChanged,
(result: CallStatusDetails) => {
console.log('SignedCallOnCallStatusChanged', result);
if (result.direction === CallDirection.Incoming) {
console.log('Call direction is Incoming!');
} else if (result.direction === CallDirection.Outgoing) {
console.log('Call direction is Outgoing!');
}
if (result.callType === CallType.M2P) {
if (result.callStatus === CallStatus.DTMFInputReceived) {
const dtmfInput = result.callOptions.getDtmfInput();
if (dtmfInput) {
console.log(`${dtmfInput.inputKey} is pressed!`);
}
} else if (result.callStatus === CallStatus.CallOver) {
const dtmfInputList = result.callOptions.dtmfInputList;
if (dtmfInputList) {
console.log(`Size of DTMF inputs list: ${dtmfInputList.length}`);
}
}
console.log(`${result.callStatus}, ${result.callOptions.campaignId}`);
}
switch (result.callStatus) {
case CallStatus.CallIsPlaced:
// Indicates that the call is successfully placed
console.log('Call is successfully placed');
break;
case CallStatus.Declined:
// Indicates that the call is declined from the receiver's end
console.log('Call is declined from the receiverβs end');
break;
case CallStatus.Missed:
// Indicates that the call is missed at the receiver's end
console.log('Call is missed at the receiverβs end');
break;
case CallStatus.Answered:
// Indicates that the call is picked up by the receiver
console.log('Call is answered by the receiver');
break;
case CallStatus.CallInProgress:
// Indicates that the connection to the receiver is established, and the audio transfer begins at this state
console.log('Call is in progress');
break;
case CallStatus.CallOver:
// Indicates that the call is over
console.log('Call is over');
break;
case CallStatus.CalleeBusyOnAnotherCall:
// Indicates that the receiver is already busy on another call
console.log('Receiver is busy on another call');
break;
case CallStatus.DeclinedDueToLoggedOutCuid:
// Indicates that the call is declined due to the receiver being logged out with the specific CUID
console.log('Call is declined due to logged-out CUID');
break;
case CallStatus.DeclinedDueToNotificationsDisabled:
// Indicates that the call is declined due to notifications being disabled at the receiver's end
console.log('Call is declined due to notifications being disabled');
break;
case CallStatus.CallCancelledDueToTtlExpired:
// Indicates that the campaign call is cancelled due to TTL being expired
console.log('Call is cancelled due to TTL expired');
break;
case CallStatus.CallCancelledDueToCampaignNotificationCancelled:
// Indicates that the M2P call is cancelled by clicking on cancel CTA from campaign's pre-processing notification
console.log(
'Call is cancelled by clicking on cancel CTA from campaignβs notification'
);
break;
case CallStatus.DTMFInputReceived:
// Indicates that a DTMF input is received from M2P keypad screen
console.log('DTMF input is received from M2P keypad screen');
break;
default:
// Handle any unexpected or unhandled statuses
console.log('Unhandled call status:', result.callStatus);
break;
}
});
// To stop observing the changes in a call state.
SignedCall.removeListener(SignedCall.SignedCallOnCallStatusChanged);
import {
SignedCall,
CallDirection,
CallStatus,
CallType,
CallStatusDetails
} from '@clevertap/clevertap-signed-call-react-native';
// To start observing the changes in call states.
SignedCall.addListener(SignedCall.SignedCallOnCallStatusChanged, (result) => {
console.log('SignedCallOnCallStatusChanged', result);
if (result.direction === CallDirection.Incoming) {
console.log('Call direction is Incoming!');
} else if (result.direction === CallDirection.Outgoing) {
console.log('Call direction is Outgoing!');
}
if (result.callType === CallType.M2P) {
if (result.callStatus === CallStatus.DTMFInputReceived) {
const dtmfInput = result.callOptions.getDtmfInput();
if (dtmfInput) {
console.log(`${dtmfInput.inputKey} is pressed!`);
}
} else if (result.callStatus === CallStatus.CallOver) {
const dtmfInputList = result.callOptions.dtmfInputList;
if (dtmfInputList) {
console.log(`Size of DTMF inputs list: ${dtmfInputList.length}`);
}
}
console.log(`${result.callStatus}, ${result.callOptions.campaignId}`);
}
switch (result.callStatus) {
case CallStatus.CallIsPlaced:
// Indicates that the call is successfully placed
console.log('Call is successfully placed');
break;
case CallStatus.Declined:
// Indicates that the call is declined from the receiver's end
console.log('Call is declined from the receiverβs end');
break;
case CallStatus.Missed:
// Indicates that the call is missed at the receiver's end
console.log('Call is missed at the receiverβs end');
break;
case CallStatus.Answered:
// Indicates that the call is picked up by the receiver
console.log('Call is answered by the receiver');
break;
case CallStatus.CallInProgress:
// Indicates that the connection to the receiver is established, and the audio transfer begins at this state
console.log('Call is in progress');
break;
case CallStatus.CallOver:
// Indicates that the call is over
console.log('Call is over');
break;
case CallStatus.CalleeBusyOnAnotherCall:
// Indicates that the receiver is already busy on another call
console.log('Receiver is busy on another call');
break;
case CallStatus.DeclinedDueToLoggedOutCuid:
// Indicates that the call is declined due to the receiver being logged out with the specific CUID
console.log('Call is declined due to logged-out CUID');
break;
case CallStatus.DeclinedDueToNotificationsDisabled:
// Indicates that the call is declined due to notifications being disabled at the receiver's end
console.log('Call is declined due to notifications being disabled');
break;
case CallStatus.CallCancelledDueToTtlExpired:
// Indicates that the campaign call is cancelled due to TTL being expired
console.log('Call is cancelled due to TTL expired');
break;
case CallStatus.CallCancelledDueToCampaignNotificationCancelled:
// Indicates that the M2P call is cancelled by clicking on cancel CTA from campaign's pre-processing notification
console.log(
'Call is cancelled by clicking on cancel CTA from campaignβs notification'
);
break;
case CallStatus.DTMFInputReceived:
// Indicates that a DTMF input is received from M2P keypad screen
console.log('DTMF input is received from M2P keypad screen');
break;
default:
// Handle any unexpected or unhandled statuses
console.log('Unhandled call status:', result.callStatus);
break;
}
});
// To stop observing the changes in a call state.
SignedCall.removeListener(SignedCall.SignedCallOnCallStatusChanged);
Handle Call Events in Killed State
Default Listener Behavior
The
SignedCall.SignedCallOnCallStatusChanged
listener receives updates only when the app is open or running in the background, not when it is in killed state.
To enable the SignedCall.SignedCallOnCallStatusChanged
listener in the killed state, follow these two steps:
- Add the following code to the
onCreate()
method of yourApplication
class:
SignedCallOnCallStatusListener.register(this);
SignedCallOnCallStatusListener.register(this)
- Register the
SignedCall.SignedCallOnCallStatusChanged
listener in theindex.js
file. It is the entry point of the React Native application. For a sample implementation, refer toindex.js
file of the Signed Call React Native Example Project.
The setup is now complete to receive call events in the killed state.
Handle Missed Call
If the receiver misses a call, the Signed Call React Native SDK shows a missed call notification to the receiver. The Signed Call React Native SDK uses action buttons on the missed call notification to display a Call to Action (CTA).
To configure the CTA on the missed call notification, add the following code:
- Create a Map object for
missedCallActions
parameter with a maximum of three entries.
let missedCallActionsMap = {
'<Unique Identifier 1>': '<label on action-button 1>',
'<Unique Identifier 2>': '<label on action-button 2>',
'<Unique Identifier 3>': '<label on action-button 3>',
};
let initProperties = {
....
missedCallActions: missedCallActionsMap,
....
};
SignedCall.initialize(initProperties)
.then((response: SignedCallResponse) => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch((e: any) => {
console.error(e);
});
let missedCallActionsMap = {
'<Unique Identifier 1>': '<label on action-button 1>',
'<Unique Identifier 2>': '<label on action-button 2>',
'<Unique Identifier 3>': '<label on action-button 3>',
};
let initProperties = {
....
missedCallActions: missedCallActionsMap,
....
};
SignedCall.initialize(initProperties)
.then(response => {
if (response.isSuccessful) {
console.log('Signed Call SDK initialized: ', response);
} else {
console.log('Signed Call initialization failed: ', response.error);
}
})
.catch(e => {
console.error(e);
});
- Insert the following code to subscribe to the
MissedCallActionClickResult
event stream, allowing you to listen for CTA click events on missed call notifications:
import {
SignedCall,
MissedCallActionClickResult,
} from '@clevertap/clevertap-signed-call-react-native';
SignedCall.addListener(
SignedCall.SignedCallOnMissedCallActionClicked,
(event: MissedCallActionClickResult) => {
console.log('SignedCallOnMissedCallActionClicked', event);
Alert.alert(
'Missed Call Notification!',
event.action.actionLabel + ' is clicked'
);
}
);
import {
SignedCall,
MissedCallActionClickResult,
} from '@clevertap/clevertap-signed-call-react-native';
//To start observing the CTA click on a missed call notification.
SignedCall.addListener(
SignedCall.SignedCallOnMissedCallActionClicked,
event => {
console.log('SignedCallOnMissedCallActionClicked', event);
}
);
//To stop observing the CTA click on a missed call notification.
SignedCall.removeListener(SignedCall.SignedCallOnMissedCallActionClicked);
Killed state support for
SignedCall.SignedCallOnMissedCallActionClicked
To enable the
SignedCall.SignedCallOnMissedCallActionClicked
listener in killed state, register theSignedCall.SignedCallOnMissedCallActionClicked
listener in theindex.js
file, the entry point of the React Native application. For a sample implementation, refer toindex.js
file of the Signed Call React Native Example Project.
Debugging
Signed Call React Native SDK logs are, by default, set to the LogLevel.info
level. We recommend you set the log level to LogLevel.verbose
mode to log warnings or other important messages during development. If you want to disable the Signed Call React Native SDK logs for the production environment, you can set the debug level to LogLevel.off
.
SignedCall.setDebugLevel(LogLevel.info); //default level, shows minimal SDK integration related logging
SignedCall.setDebugLevel(LogLevel.debug); //shows debug output
SignedCall.setDebugLevel(LogLevel.verbose); //shows verbose output
SignedCall.setDebugLevel(LogLevel.off); //disables all debugging
SignedCall.setDebugLevel(LogLevel.info); //default level, shows minimal SDK integration related logging
SignedCall.setDebugLevel(LogLevel.debug); //shows debug output
SignedCall.setDebugLevel(LogLevel.verbose); //shows verbose output
SignedCall.setDebugLevel(LogLevel.off); //disables all debugging
The log window displays the logs from the Signed Call SDKs. After setting the debug level, search for the following tags:
Platform | TAG |
---|---|
Android | [CT]:[SignedCall] |
React Native | [CT]:[SignedCall]:[RN] |
Sample Project: Implementing Signed Call React Native SDK
For example, for a project integrating Signed Call React Native SDK in your React Native application, refer to Signed Call React Native Example Project.
Note
Ensure you have added valid Signed Call and CleverTap Account credentials for the calling to work.
Error Handling
The Signed Call React Native SDK provides error reporting and handling.
The SignedCall.initialize(..)
method is associated with promise
objects that receive a SignedCallResponse
object. This object contains any initialization that may occur.
The following is the list of the initialization errors:
Error Code | Description |
---|---|
1000 | No internet connection. |
2000 | The application context is missing. |
2001 | The CleverTapApi instance is missing. |
2002 | The initProperties is missing. |
2003 | The Signed Call Android SDK is not initialized. |
2004 | The accountId and apiKey parameters are missing. |
2005 | The cuid is missing. |
2006 | The cuid length is invalid. |
2007 | Invalid cuid due to violation of valid cuid rules. |
2008 | The length of the name parameter is invalid. |
2009 | The appId is invalid. |
2010 | The branding configuration is invalid. |
2011 | The values in initProperties are invalid. |
2012 | The user authentication is not successful. |
2013 | The notification permission was not given during the SDK initialization. |
FAQs
Is Signed Call accountId
and apiKey
the same as CleverTap accountId
and token
?
accountId
and apiKey
the same as CleverTap accountId
and token
?No. Signed Call accountId
and apiKey
differ from CleverTap's accountId
and token
. You can find these details under your dashboard's Signed Call Settings.
Does the Signed Call React Native SDK support In-App calls over Bluetooth?
Yes. The Signed Call React Native SDK has built-in Bluetooth support. However, it requires a runtime BLUETOOTH_CONNECT permission for Android 12 and onwards.
Updated 13 days ago