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

Step 2: Install stringee-react-rative 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. Create a pod file by running: pod init.

  3. Add the following to your pod file:
    platform :ios, '8.0'

    target '<YourProjectName>' do
        node_modules_path = '../node_modules'

        pod 'yoga', path: "#{node_modules_path}/react-native/ReactCommon/yoga/yoga.podspec"
        pod 'React', path: "#{node_modules_path}/react-native", :subspecs => ['DevSupport', 'RCTNetwork']

        pod 'RNStringee', path: "#{node_modules_path}/stringee-react-native/ios"
    end

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        if target.name == "React"
          target.remove_from_project
        end
      end
    end
  1. Now run, pod install

  2. Open XCode

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

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

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

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

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

Manual installation

  1. Open up android/app/src/main/java/[...]/MainApplication.java
    • Add import com.stringeereactnative.RNStringeeReactPackage; to the imports at the top of the file
    • Add new RNStringeeReactPackage() to the list returned by the getPackages() method
  2. Append the following lines to android/settings.gradle:
    include ':stringee-react-native'
    project(':stringee-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/stringee-react-native/android')
  3. Insert the following lines inside the dependencies block in android/app/build.gradle:
      compile project(':stringee-react-native')

    Permissions

    The Stringee Android SDK requires some permissions from your AndroidManifest

  4. Open up android/app/src/main/AndroidManifest.xml
  5. 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,
    };
    }
    
    // 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("IncomingCallId-" + callId + ' from-' + from + ' to-' + to + ' fromAlias-' + fromAlias + ' toAlias-' + toAlias + ' isVideoCall-' + isVideoCall + 'callType-' + callType);
    }
    
    render() {
    return (
      <View>
        ...
        <StringeeClient
          ref="client"
          eventHandlers = {this.clientEventHandlers}
         /> 
        ...
      </View>
    );
    }
    }
  2. 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
render () {
  return (
    <View>
      ...
      <StringeeCall
        ref="stringeeCall"
        eventHandlers = {this.callEventHandlers}
      />
      ...
    </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
    };
  }

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

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

  // 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 ' + callId + "***" + dtmf);
  }

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

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

  render() {
    return (
      <View style={styles.container}>
        ...    
        <StringeeCall
          ref="stringeeCall"
          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 + ' from-' + from + ' to-' + to + ' fromAlias-' + fromAlias + ' toAlias-' + toAlias + ' isVideoCall-' + isVideoCall + 'callType-' + callType);
  }

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.state.hasReceivedLocalStream && this.state.callId != '' && <StringeeVideoView 
        style={{backgroundColor:'black', width:100, height:100}} 
        callId={this.state.callId} 
        streamId='' 
        local = {true}
        />}
        ...
        <StringeeCall
          ref="stringeeCall"
          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.state.hasReceivedRemoteStream && <StringeeRemoteVideoView
        style={styles.remoteView} 
        callId={this.state.callId} 
        streamId='' 
        local = {false}
        />
        }
        ...
        <StringeeCall
          ref="stringeeCall"
          eventHandlers = {this.callEventHandlers}
        />
        ...
      </View>
    );
  }
}

Sample

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