Suggestions

close search

Getting started with Stringee Call API using React native

Step 1: Prepare

  1. Before using Stringee Call API for the first time, you must have a Stringee account.

    If you do not have a Stringee account, sign up for free here: https://developer.stringee.com/account/register

  2. Create a Project on Stringee Dashboard

    Stringee create Project

  3. Buy a Number (optional)

  4. For app-to-phone, phone-to-app calling, buy a Number from Dashboard. If you only need app-to-app calling, skip this step.

    Stringee buy Number

  5. Configure answer_url

    For more information about answer_url, read Stringee Call API Overview. You can view the answer_url sample code.

    • Configure Project's answer_url: To make an app-to-app, app-to-phone call, configure your Project's answer_url

    Stringee Project answer_url

    If you do not have answer_url, you can use the following Project's answer_url to accelerate the process:

    Project's answer_url for App-to-App call:

    https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=false

    Project's answer_url for App-to-Phone call:

    https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=true

    (Source code: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/project_answer_url.php)

    When building an application, you should use your own answer_url.

    • Configure Number's answer_url: To receive a phone-to-app call, configure your Number's answer_url

    Stringee Number answer_url

    If you do not have answer_url, you can use the following Number's answer_url to accelerate the process:

    Number's answer_url for Phone-to-App call (The call is routed to Your App which authenticated by USER_ID):

    https://developer.stringee.com/scco_helper/simple_number_answer_url?record=true&phoneToPhone=false&to_number=USER_ID

    Number's answer_url for Phone-to-Phone call (The call is routed to TO_NUMBER):

    https://developer.stringee.com/scco_helper/simple_number_answer_url?record=true&phoneToPhone=true&stringeeNumber=STRINGEE_NUMBER&to_number=TO_NUMBER

    (Source code: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/number_answer_url.php)

Step 2: stringee-react-native-v2 package

  1. In your terminal (Command Prompt in Windows), change into your React Native project's directory

  2. In your terminal (Command Prompt in Windows), run $ npm install stringee-react-native-v2@^1.1.0

The latest package requires React Native 0.60 or later, JDK 17, Android minSdk 21 or later, and iOS 13.0 or later. Because the package contains native modules, Expo projects must use a development or production build; Expo Go is not supported.

Step 3: Setup

Android

  1. Permissions

    The Stringee Android SDK requires some permissions from your AndroidManifest

    • Open up android/app/src/main/AndroidManifest.xml
    • Add the following lines:
    <!--Internet-->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!--Record-->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <!--Audio-->
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <!--Camera-->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="false" />
    <!--Bluetooth-->
    <uses-permission
        android:name="android.permission.BLUETOOTH"
        android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!--Require for android 12 or higher-->
    <uses-feature
        android:name="android.hardware.bluetooth"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.bluetooth_le"
        android:required="false" />
    <!-- Graphic -->
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="false" />

    Request camera, microphone, and BLUETOOTH_CONNECT at runtime on Android versions where they are dangerous permissions. The package already resolves Stringee Android SDK 2.1.13 and WebRTC 144.7559.09, so do not add separate Stringee or WebRTC dependencies to the host app.

  2. ProGuard/R8 rules for Stringee and WebRTC are included in the package. Keep your application's existing minification configuration; you do not need to enable minification specifically for Stringee.

iOS

  1. In your terminal, change into your iOS directory and run the following command:

    pod install --repo-update
  2. After running CocoaPods, open the generated .xcworkspace file instead of .xcodeproj.

  3. Right-click the information property list file (Info.plist) and select Open As -> Source Code. Then insert the following XML snippet into the body of your file just before the final element:

    <key>NSCameraUsageDescription</key>
    <string>$(PRODUCT_NAME) uses Camera</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>$(PRODUCT_NAME) uses Microphone</string>

Step 4: Connect to Stringee Server

To connect to Stringee Server, third-party authentication is required as described in Client authentication.

For testing, go to Dashboard -> Tools -> Generate Access token and generate an access_token. In production, the access_token should be generated by your server. See the access token examples.

  1. Initialize StringeeClient:

    import {StringeeCall, StringeeClient, StringeeClientListener} from 'stringee-react-native-v2';
    ...
    const stringeeClient: StringeeClient = new StringeeClient();
    let incomingCall: StringeeCall | null = null;
  2. Register the client's events

    // Listen for the StringeeClient event
    const stringeeClientListener: StringeeClientListener = new StringeeClientListener();
    // Invoked when the StringeeClient is connected
    stringeeClientListener.onConnect = (stringeeClient, userId) => {
      console.log('onConnect: ', userId);
    }
    // Invoked when the StringeeClient is disconnected
    stringeeClientListener.onDisConnect = (stringeeClient) => {
      console.log('onDisConnect');
    }
    // Invoked when the StringeeClient connection fails
    stringeeClientListener.onFailWithError = (stringeeClient, code, message) => {
      console.log('onFailWithError: ', message);
    }
    // Invoked when your token is expired
    stringeeClientListener.onRequestAccessToken = (stringeeClient) => {
      console.log('onRequestAccessToken');
    }
    // Invoked when an incoming StringeeCall is received
    stringeeClientListener.onIncomingCall = (stringeeClient, stringeeCall) => {
      incomingCall = stringeeCall;
      console.log('onIncomingCall: ', JSON.stringify(stringeeCall));
    }
    // Invoked when an incoming StringeeCall2 is received
    stringeeClientListener.onIncomingCall2 = (stringeeClient, stringeeCall2) => {
      console.log('onIncomingCall2: ', JSON.stringify(stringeeCall2));
    }
    stringeeClient.setListener(stringeeClientListener);
  3. Connect

    ...
    const token: string = 'PUT YOUR TOKEN HERE';
    ...
    stringeeClient.connect(token);

Step 5: Make a call

After the client connects to Stringee server, follows these steps to make a call:

  1. Initialize StringeeCall

    import {StringeeCallListener} from 'stringee-react-native-v2';
    ...
    const stringeeCall = new StringeeCall({
      stringeeClient: stringeeClient, /// stringeeClient using to connect
      from: 'caller_userId', /// caller identifier
      to: 'callee_userId', /// callee identifier
    });
  2. Register the call's events

    // Listen for the StringeeCall event
    const stringeeCallListener: StringeeCallListener = new StringeeCallListener();
    // Invoked when the call's signaling state changes
    stringeeCallListener.onChangeSignalingState = (stringeeCall, signalingState, reason, sipCode, sipReason) => {
      console.log('onChangeSignalingState', signalingState);
    }
    // Invoked when the call's media state changes
    stringeeCallListener.onChangeMediaState = (stringeeCall, mediaState, description) => {
      console.log('onChangeMediaState', mediaState);
    }
    // Invoked when receive call info
    stringeeCallListener.onReceiveCallInfo = (stringeeCall, callInfo) => {
      console.log('onReceiveCallInfo', callInfo);
    }
    // Invoked when an incoming call is handle on another device
    stringeeCallListener.onHandleOnAnotherDevice = (stringeeCall, signalingState, description) => {
      console.log('onHandleOnAnotherDevice', signalingState);
    }
    // Invoked when local stream in video call is ready to play
    stringeeCallListener.onReceiveLocalStream = (stringeeCall) => {
      console.log('onReceiveLocalStream');
    }
    // Invoked when remote stream in video call is ready to play
    stringeeCallListener.onReceiveRemoteStream = (stringeeCall) => {
      console.log('onReceiveRemoteStream');
    }
    // Invoked when the current audio device changes in android
    stringeeCallListener.onAudioDeviceChange = (stringeeCall, selectedAudioDevice, availableAudioDevices) => {
      console.log('onAudioDeviceChange', selectedAudioDevice);
    }
    stringeeCall.setListener(stringeeCallListener);
  3. Make a call

    stringeeCall.makeCall()
      .then(() => {
         console.log('makeCall success');
      })
      .catch(console.error);

Step 6: Answer a call

After stringeeClientListener.onIncomingCall receives an incoming StringeeCall object and saves it to incomingCall, follow these steps:

  1. Initialize the answer

    if (!incomingCall) {
       return;
    }
    incomingCall.setListener(stringeeCallListener);
    incomingCall.initAnswer()
      .then(() => {
         console.log('initAnswer success');
      })
      .catch(console.error);
  2. Answer

    if (!incomingCall) {
       return;
    }
    incomingCall.answer()
      .then(() => {
         console.log('answer success');
      })
      .catch(console.error);

Step 7: Make a video call

  1. A StringeeCall is a voice call by default. If you want to make a video call, set the isVideoCall property to true before calling makeCall().
    stringeeCall.isVideoCall = true;
  2. Receive and display the local video and the remote video

    Using our StringeeVideoView to display the video

    import {StringeeVideoView} from 'stringee-react-native-v2';
    ...
    // Invoked when local stream in video call is ready to play
    stringeeCallListener.onReceiveLocalStream = (stringeeCall) => {
      console.log('onReceiveLocalStream');
      this.setState({hasReceivedLocalStream: true});
    }
    // Invoked when remote stream in video call is ready to play
    stringeeCallListener.onReceiveRemoteStream = (stringeeCall) => {
      console.log('onReceiveRemoteStream');
      this.setState({hasReceivedRemoteStream: true});
    }
    ...
    render () {
      return (
        <View>
        ...
        {stringeeCall.isVideoCall &&
          this.state.hasReceivedLocalStream && (
            <StringeeVideoView
              style={styles.localView}
              uuid={stringeeCall.uuid}
              local={true}
            />
          )
        }
        {stringeeCall.isVideoCall &&
          this.state.hasReceivedRemoteStream && (
            <StringeeVideoView
              style={{flex: 1}}
              uuid={stringeeCall.uuid}
              local={false}
            />
          )
        }
        ...
        </View>
      );
    }

Step 8: Hang up

In Steps 8-13, invoke the methods on the active StringeeCall object. The snippets use the outgoing stringeeCall created in Step 5; for an incoming call, invoke the same methods on incomingCall.

Hang up a call:

   stringeeCall.hangup()
      .then(() => {
         console.log('hangup success');
      })
      .catch(console.error);

Step 9: Reject

Reject a call:

   stringeeCall.reject()
      .then(() => {
         console.log('reject success');
      })
      .catch(console.error);

Step 10: Mute

Mute the local sound:

   const mute = true; // true: mute, false: unmute
   stringeeCall.mute(mute)
      .then(() => {
         console.log('mute success');
      })
      .catch(console.error);

Step 11: Switch speaker or bluetooth device

Switch to speakerphone or earpiece:

   const isSpeaker = true; // true: speakerphone, false: earpiece
   stringeeCall.setSpeakerphoneOn(isSpeaker)
      .then(() => {
         console.log('setSpeakerphoneOn success');
      })
      .catch(console.error);

Step 12: Switch camera

Switch the local camera:

   stringeeCall.switchCamera()
      .then(() => {
         console.log('switchCamera success');
      })
      .catch(console.error);

Step 13: Turn on/off video

Turn on/off video:

   const enableVideo = true; // true: turn on, false: turn off
   stringeeCall.enableVideo(enableVideo)
      .then(() => {
         console.log('enableVideo success');
      })
      .catch(console.error);

Sample

You can view a full version of this sample app on GitHub: CallSampleHook