Create a Twilio VoIP calls in a React Native app

Dmitriy Kovtun
4 min readOct 13, 2018

--

Hello. Today we will learn how to create react-native app, where you can call a TwiML service using Twilio. You can check results here:

In this tutorial we are going to use this library to work with Twilio SDK:

Also, we should fire up the basic server which will be used to create access tokens:

Finally, we need to use Firebase to get Twilio’s notifications about calls:

Let’s begin our journey into mobile voip world. First of all, we should install react-native-cli:

$ npm install -g react-native-cli

Then, init react-native project by doing:

$ react-native init ReactNativeTwilioExampleApp

Now we can run our app on real device/simulator (you need the Android Studio to run app on Android emulator):

$ cd ReactNativeTwilioExampleApp
$ react-native run-android

Finally, you should see welcome screen:

I don’t want to overwhelm this tutorial with Redux, so we will stick to KISS (keep it simple, stupid) principle.

So, you want to create basic call.

Let’s create the plan of our work (as the base, we can use iOS quickstart guide https://github.com/twilio/voice-quickstart-objc#quickstart):

  1. Install react-native-twilio-programmable-voice library and run voice-quickstart-server-node:
$ yarn add react-native-twilio-programmable-voice

Use instructions from the repo to run server (https://github.com/twilio/voice-quickstart-server-node)

At the end you should see:

$ Express server running on *:3000

2. Install Cocoapods (if you want to work with iOS):

$ sudo gem install cocoapods
$ cd ios
$ pod init

Change your Podfile:

platform :ios, '9.0'target 'ReactNativeTwilioExampleApp' do
pod 'TwilioVoice', '~> 2.0.0'
end

This allows us to automatically link Twilio library to our project.

From an ios folder:

$ pod install

3. Install Firebase (https://rnfirebase.io/docs/v5.x.x/installation/initial-setup). When you are done, add this in the end of android/app/build.gradle (see https://github.com/invertase/react-native-firebase/issues/1155#issuecomment-395944013)

com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true

4. Complete steps 2, 3, 4, 5 from https://github.com/twilio/voice-quickstart-objc#quickstart guide;

5. Write some code to create call to a TwiML app.

According to Twilio manual, we should obtain access token first. Let’s do this:

...getAuthToken = () => {
return fetch(‘http://c2a19b17.ngrok.io/accessToken', { //replace c2a19b17.ngrok.io with your link (from Step 1), localhost won't work
method: ‘get’,
})
.then(response => response.text())
.catch((error) => console.error(error));
}
...

We are using Fetch API to make request to our backend, but you can use special library (like axios, for example).

If you are working with Android, you must ask for microphone access pemission (https://github.com/hoxfon/react-native-twilio-programmable-voice/issues/47):

import { Platform, StyleSheet, Text, View, TouchableOpacity, PermissionsAndroid } from 'react-native';...getMicrophonePermission = () => {
const audioPermission = PermissionsAndroid.PERMISSIONS.RECORD_AUDIO;

return PermissionsAndroid.check(audioPermission).then(async result => {
if (!result) {
const granted = await PermissionsAndroid.request(audioPermission, {
title: 'Microphone Permission',
message: 'App needs access to you microphone ' + 'so you can talk with other users.',
});
}
});
}
...

Now we should disable default Twilio check for microphone access (android/app/src/main/java/com/reactnativetwilioexampleapp/MainApplication.java):

...protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new TwilioVoicePackage(false),
...

Our victory is near. Now we only need to initialize Twilio SDK and create call function:

...import TwilioVoice from 'react-native-twilio-programmable-voice';...state = {
twilioInited: false
};
...initTwilio = async () => {
const token = await this.getAuthToken();
if (Platform.OS === 'android') {
await this.getMicrophonePermission();
}
await TwilioVoice.initWithToken(token); TwilioVoice.addEventListener('deviceReady', () => {
this.setState({ twilioInited: true });
});
if (Platform.OS === 'ios') { //required for ios
TwilioVoice.configureCallKit({
appName: 'ReactNativeTwilioExampleApp',
});
}
};
makeCall = () => TwilioVoice.connect({ To: 'Alice' }); //took it from Twilio example repo. In real call you will change Alice with a real number...

Now we are ready to add layout and create a call:

...render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => this.initTwilio()}>
<View>
<Text>Init Twilio</Text>
</View>
</TouchableOpacity>
<TouchableOpacity disabled={!this.state.twilioInited} onPress={() => this.makeCall()}>
<View>
<Text>Make call ({this.state.twilioInited ? 'ready' : 'not ready'})</Text>
</View>
</TouchableOpacity>
</View>
);
}
...

This is how it should look like:

Tap ‘init Twilio’, and when ‘not ready’ changes to ‘ready’ tap Make call. You should hear an conglatulary message.

P.S.

Don’t forget, that after this step you should follow https://github.com/twilio/voice-quickstart-objc#quickstart to receive/make real calls. Also, without this guide, Twilio won’t work on iOS, because it needs special VoIP sertificate.

--

--