Suggestions

close search

Getting started with the React Native wrapper for Stringee Call SDK

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) 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

  4. Configure answer_url

For more information about answer_url, read Stringee Call API Overview. You can view answer_url sample code here: https://github.com/stringeecom/server-samples/tree/master/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.

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)

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

Step 2: Install stringee-react-native 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 --save

iOS

Note Please make sure to have CocoaPods on your computer.

  1. In you terminal, change into your ios directory.

  2. Now run, pod install

  3. Open XCode

  4. Open <YourProjectName>.xcworkspace file in XCode. This file can be found in the ios folder of your React Native project.

  5. In the "Build Settings" tab -> "Other linker flags" add "$(inherited)" flag.

  6. In the "Build Settings" tab -> "Enable bitcode" select "NO".

  7. Right-click the information property list file (Info.plist) and select Open As -> Source Code.

  8. 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>

Android

Proguard

Open up android/app/proguard-rules.pro and add following lines:

-dontwarn org.webrtc.**
-keep class org.webrtc.** { *; }
-keep class com.stringee.** { *; }

Permissions

The Stringee Android SDK requires some permissions from your AndroidManifest

  1. Open up android/app/src/main/AndroidManifest.xml
  2. Add the following lines:
    // for internet access
    <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" />
    // for audio access
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    // for camera access
    <uses-permission android:name="android.permission.CAMERA" />

Step 3: Connect to Stringee Server

In order to connect to Stringee Server, 3-parties authentication is required as described here: Client authentication

For testing purpose, go to Dashboard -> Tools -> Generate Access token and generates an access_token. In production, the access_token should be generated by your server, sample code generates access token here: https://github.com/stringeecom/server-samples/tree/master/access_token

  1. Import StringeeClient:
import {
  StringeeClient
} from "stringee-react-native";
  1. Initialize StringeeClient
render () {
  return (
    <View>
      ...    
      <StringeeClient
        ref="client"
        eventHandlers = {this.clientEventHandlers}
      />
      ...
    </View>
  )
}
  1. Register the client's events
class App extends Component {
  constructor(props) {
    super(props);

    this.clientEventHandlers = {
      onConnect: this._clientDidConnect,
      onDisConnect: this._clientDidDisConnect,
      onFailWithError: this._clientDidFailWithError,
      onRequestAccessToken: this._clientRequestAccessToken,
      onIncomingCall: this._callIncomingCall,
      onIncomingCall2: this._callIncomingCall2,
      onCustomMessage: this._clientReceiveCustomMessage,
    };
  }

  // The client connects to Stringee server
  _clientDidConnect = ({userId}) => {
    console.log('_clientDidConnect: ' + userId);
  }

  // The client disconnects from Stringee server
  _clientDidDisConnect = () => {
    console.log('_clientDidDisConnect');
  }

  // The client fails to connects to Stringee server
  _clientDidFailWithError = () => {
    console.log('_clientDidFailWithError');
  }

  // Access token is expired. A new access token is required to connect to Stringee server
  _clientRequestAccessToken = () => {
    console.log("_clientRequestAccessToken");
    // this.refs.client.connect('NEW_YOUR_ACCESS_TOKEN');
  }

   // IncomingCall event
  _callIncomingCall = ({callId, from, to, fromAlias, toAlias, callType, isVideoCall}) => {
    console.log('_callIncomingCall: ' + callId);
  }

  // IncomingCall2 event
  _callIncomingCall2 = ({callId, from, to, fromAlias, toAlias, callType, isVideoCall}) => {
    console.log('_callIncomingCall2: ' + callId);
  }

  // Receive custom message
  _clientReceiveCustomMessage = ({data}) => {
    console.log('_clientReceiveCustomMessage: ' + data);
  };

  render() {
    return (
      <View>
        ...
        <StringeeClient
          ref="client"
          eventHandlers = {this.clientEventHandlers}
         /> 
        ...
      </View>
    );
  }
}
  1. Connect
  async componentDidMount() {
    await this.refs.client.connect('YOUR_ACCESS_TOKEN');
  }

Step 4: Make a call

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

  1. Import StringeeCall:
import {
  StringeeCall
} from "stringee-react-native";
  1. Initialize StringeeCall
async componentDidMount() {
    await this.refs.stringeeClient.connect(token);
    this.setState({clientId: this.refs.stringeeClient.getId()});
  }
...
render () {
  return (
    <View>
      ...
      {this.state.clientId !== null && this.state.isStringeeCall && (
            <StringeeCall
              ref="stringeeCall"
              clientId={this.state.clientId}
            />
          )}
      ...
    </View>
  );
}
  1. Register the call's events
class App extends Component {
  constructor(props) {
    super(props);

    this.callEventHandlers = {
      onChangeSignalingState: this._callDidChangeSignalingState,
      onChangeMediaState: this._callDidChangeMediaState,
      onReceiveLocalStream: this._callDidReceiveLocalStream,
      onReceiveRemoteStream: this._callDidReceiveRemoteStream,
      onReceiveDtmfDigit: this._didReceiveDtmfDigit,
      onReceiveCallInfo: this._didReceiveCallInfo,
      onHandleOnAnotherDevice: this._didHandleOnAnotherDevice,
      onAudioDeviceChange: this._didAudioDeviceChange, ///only available on android
    };
  }

    // Invoked when the call signaling state changes
  _callDidChangeSignalingState = ({callId, code, reason, sipCode, sipReason}) => {
    console.log('_callDidChangeSignalingState: ' + code);
  }

  // Invoked when the call media state changes
  _callDidChangeMediaState = ({callId, code, description}) => {
    console.log('_callDidChangeMediaState: ' + code);
  }

  // Invoked when the local stream is available    
  _callDidReceiveLocalStream = ({callId}) => {
    console.log('_callDidReceiveLocalStream: ' + callId);
  }
  // Invoked when the remote stream is available
  _callDidReceiveRemoteStream = ({callId}) => {
    console.log('_callDidReceiveRemoteStream: ' + callId);
  }

  // Invoked when receives a DMTF
  _didReceiveDtmfDigit = ({callId, dtmf}) => {
    console.log('_didReceiveDtmfDigit');
  }

  // Invoked when receives info from other clients
  _didReceiveCallInfo = ({callId, data}) => {
    console.log('_didReceiveCallInfo: ' + data);
  }

  // Invoked when the call is handled on another device
  _didHandleOnAnotherDevice = ({callId, code, description}) => {
    console.log('_didHandleOnAnotherDevice: ' + code);
  }

  // Invoked when audio device has change
  _didAudioDeviceChange = ({selectedAudioDevice, availableAudioDevices}) => {
    console.log(
      '_didHandleOnAnotherDevice: selectedAudioDevice - ' +
        selectedAudioDevice +
        ' availableAudioDevices - ' +
        availableAudioDevices,
    );
  };

  render() {
    return (
      <View style={styles.container}>
        ...    
        {this.state.clientId !== null && this.state.isStringeeCall && (
            <StringeeCall
              ref="stringeeCall"
              clientId={this.state.clientId}
              eventHandlers={this.callEventHandlers}
            />
        )}
      ...
      </View>
    );
  }
}
  1. Make a call
  const myObj = {
    from: 'caller_userId', // caller
    to: 'callee_userId', // callee
    isVideoCall: false, // Cuộc gọi là video call hoặc voice call 
    videoResolution: 'NORMAL' // chất lượng hình ảnh 'NORMAL' hoặc 'HD'. Mặc định là 'NORMAL'.
  };

  const parameters = JSON.stringify(myObj);

  this.refs.stringeeCall.makeCall(parameters, (status, code, message, callId) => {
    console.log('status-' + status + ' code-' + code + ' message-' + message + 'callId-' + callId);
    if (status) {
      // Sucess
    } else {
      // Fail
    }
  })

Step 5: Answer a call

When the client receives an incoming call with callId

   // IncomingCall event
  _callIncomingCall = ({callId, from, to, fromAlias, toAlias, callType, isVideoCall}) => {
    console.log('IncomingCallId: ' + callId);
  }

Initialize a StringeeCall as described in 4.1, 4.2, 4.3. Then follow these steps:

  1. Initialize the answer
  this.refs.stringeeCall.initAnswer(callId, (status, code, message) => {
    console.log(message);
    if (status) {
      // Sucess
    } else {
      // Fail
    }
  });
  1. Answer
  this.refs.stringeeCall.answer(callId, (status, code, message) => {
    console.log(message);
    if (status) {
      // Sucess
    } else {
      // Fail
    }
  });

Step 6: Hang up

When the client wants to hang up:

  this.refs.stringeeCall.hangup(callId, (status, code, message) => {
    console.log(message);
    if (status) {
      // Sucess
    } else {
      // Fail
    }
  });

Step 7: Reject a call

When the client wants to reject a call:

  this.refs.stringeeCall.reject(callId, (status, code, message) => {
    console.log(message);
    if (status) {
      // Sucess
    } else {
      // Fail
    }
  });

Step 8: Make a video call

  1. A Stringee call is a voice call by default. If you want to make a video call, you must assign:
  const myObj = {
    from: 'caller_userId', // caller
    to: 'callee_userId', // callee
    isVideoCall: true, // Must be true
    videoResolution: 'NORMAL' // Set video resolution: 'NORMAL', 'HD'
  };

  const parameters = JSON.stringify(myObj);

  this.refs.stringeeCall.makeCall(parameters, (status, code, message, callId) => {
    console.log('status-' + status + ' code-' + code + ' message-' + message + 'callId-' + callId);
    if (status) {
      // Sucess
    } else {
      // Fail
    }
  })
  1. Display the local video
  _callDidReceiveLocalStream = ({callId}) => {
    console.log('_callDidReceiveLocalStream ' + callId);
    this.setState({hasReceivedLocalStream:true});
  }

  render () {
    return (
      <View>
        ...
        {this.props.isVideoCall &&
          this.props.hasLocalStream &&
          this.props.stringeeCallId != '' && (
            <StringeeVideoView
              style={styles.localView}
              callId={this.props.stringeeCallId}
              local={true}
              overlay={true}
            />
          )}
        ...
        <StringeeCall
            ref="stringeeCall"
            clientId={this.state.clientId}
            eventHandlers={this.callEventHandlers}
        />
        ...
      </View>
    );
  }
}
  1. Receive and display the remote video
  _callDidReceiveRemoteStream = ({callId}) => {
    console.log('_callDidReceiveRemoteStream ' + callId);
    this.setState({hasReceivedRemoteStream:true});
  }

  render () {
    return (
      <View>
        ...
        {this.props.isVideoCall &&
            this.props.hasRemoteStream &&
            this.props.stringeeCallId != '' && (
              <StringeeVideoView
                style={{flex: 1}}
                callId={this.props.stringeeCallId}
                local={false}
              />
            )}
        ...
        <StringeeCall
            ref="stringeeCall"
            clientId={this.state.clientId}
            eventHandlers={this.callEventHandlers}
        />
        ...
      </View>
    );
  }
}

Sample

You can view a full version of this sample app on GitHub: https://github.com/stringeecom/react-native-samples