https://d226lax1qjow5r.cloudfront.net/blog/blogposts/how-to-make-phone-calls-using-android-and-react-native/react_inapp-call_android_1200x600.png

Cómo hacer llamadas telefónicas usando Android y React Native

Tiempo de lectura: 11 minutos

Esta entrada de blog le llevará a través de un proyecto, que le mostrará cómo utilizar el Vonage Client SDK para crear una aplicación React Native Android que llamará a un número de teléfono. Si deseas explorar el uso del Client SDK con iOS, consulta esta entrada de blog.

Requisitos previos

  • Android Studiocon JDK 8 o posterior para crear y ejecutar la aplicación en un emulador.

  • A GitHub Account.

  • Nuestra interfaz de línea de comandos, que puede instalar con npm install @vonage/cli -g.

  • Homebrew para instalar las dependencias de React Native.

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.

Configuración de React Native

Para construir y ejecutar una aplicación React Native, primero necesitas instalar las dependencias, Node y Watchman. Puedes hacerlo usando Homebrew. En tu terminal ejecuta:

brew install node brew install watchman

Si ya tienes Node instalado, asegúrate de que es Node 12 o más reciente. Puedes encontrar más información sobre cómo configurar tu entorno en la documentación de React Native.

Clonar el proyecto

Puedes clonar el proyecto en tu máquina local ejecutando el siguiente comando en tu terminal:

git clone git@github.com:Vonage-Community/sample-voice-react-native-app.git

Luego, en tu Terminal, cambia de directorio a la nueva carpeta con el siguiente comando:

cd sample-voice-react-native-app

Ahora que el proyecto ha sido clonado, puedes instalar las dependencias del proyecto. Puedes instalar las dependencias específicas de React Native ejecutando npm install. Este comando instalará las dependencias listadas en el archivo package.json del proyecto. Una dependencia que debes tener en cuenta es react-native-permissionsun proyecto de código abierto que proporciona una forma unificada de solicitar permisos tanto en iOS como en Android. Puede inspeccionar las dependencias de iOS mirando el archivo Podfile.

La aplicación de Vonage

Para crear la aplicación, utilizaremos nuestra interfaz de línea de comandos. Si aún no ha configurado la CLI, hágalo ejecutando el comando vonage config:set --apiKey=API_KEY --apiSecret=API_SECRET en su terminal, donde la clave de API y el secreto son la clave de API y el secreto que se encuentra en su Account de tu cuenta.

Comprar un número de Vonage

Necesitaremos un número de Vonage para la aplicación, puedes comprar uno usando la CLI de Vonage. El siguiente comando busca un número disponible en los EE. UU. Especifica un código de país alternativo de dos caracteres para buscar un número en otro país.

vonage numbers:search US

Una vez que hayas encontrado un número, utiliza este comando para comprarlo:

vonage numbers:buy $NUMBER US

Crear un servidor Webhook

Cuando se recibe una llamada entrante, Vonage realiza una solicitud a una URL de acceso público de tu elección, que denominamos answer_url. Debes crear un servidor de webhook que sea capaz de recibir esta solicitud y devolver un archivo NCCO que contenga una connect acción que reenviará la llamada al número de teléfono PSTN. Para ello, extraiga el número de destino del parámetro de consulta to y devolviéndolo en la respuesta.

Crea una nueva carpeta:

mkdir vonageapp

cd vonageapp

Instale las dependencias:

npm init -y

npm install express localtunnel --save

Cree un archivo llamado server.js que contenga el siguiente código:

'use strict';

const subdomain = 'SUBDOMAIN';
const vonageNumber = 'NUMBER';

const express = require('express');
const app = express();
app.use(express.json());

app.get('/voice/answer', (req, res) => {
  console.log('NCCO request:');
  console.log(`  - callee: ${req.query.to}`);
  console.log('---');
  res.json([ 
    { 
      "action": "talk", 
      "text": "Please wait while we connect you."
    },
    { 
      "action": "connect",
      "from": vonageNumber,
      "endpoint": [ 
        { "type": "phone", "number": req.query.to } 
      ]
    }
  ]);
});

app.all('/voice/event', (req, res) => {
  console.log('EVENT:');
  console.dir(req.body);
  console.log('---');
  res.sendStatus(200);
});

if(vonageNumber == "NUMBER") {
  console.log('\n\t🚨🚨🚨 Please change the NUMBER value');
  return false;
}

if(subdomain == "SUBDOMAIN") {
  console.log('\n\t🚨🚨🚨 Please change the SUBDOMAIN value');
  return false;
}
app.listen(3000);

const localtunnel = require('localtunnel');
(async () => {
  const tunnel = await localtunnel({ 
      subdomain: subdomain, 
      port: 3000
    });
  console.log(`App available at: ${tunnel.url}`);
})();

Asegúrate de reemplazar NUMBER por tu número de Vonage (en formato E.164), así como SUBDOMAIN con un valor real. El valor SUBDOMAIN utilizado formará parte de las URL que establecerás como webhooks en el siguiente paso. A continuación, inicia el servidor:

node server.js

El terminal imprimirá la URL de tu servidor, por ejemplo:

App available at: https://SUBDOMAIN.loca.lt

Crear una aplicación de Vonage

A continuación, crearás una Vonage copiando y pegando el siguiente comando en el terminal. Asegúrate de cambiar los valores de --voice_answer_url y --voice_event_url sustituyendo SUBDOMAIN por el valor real utilizado en el paso anterior:

vonage apps:create "Vonage Tutorial" --voice_answer_url=https://SUBDOMAIN.loca.lt/voice/answer --voice_event_url=https://SUBDOMAIN.loca.lt/voice/event

Se crea un archivo llamado vonage_app.json en el directorio de tu proyecto y contiene el nuevo ID de aplicación de Vonage y la clave privada. También se crea un archivo de clave privada llamado vonage_tutorial.key también se crea.

Por último, vincula el número que compraste anteriormente a tu aplicación de Vonage:

vonage apps:link APPLICATION_ID --number=YOUR_VONAGE_NUMBER

Crear un JWT

El Client SDK utiliza JWTs para la autenticación. El JWT identifica el nombre de usuario, el ID de la aplicación asociada y los permisos concedidos al usuario. Se firma utilizando su clave privada para demostrar que se trata de un token válido. Crea un usuario para tu aplicación, puedes hacerlo en tu Terminal ejecutando el siguiente comando: vonage apps:users:create Alice para crear un usuario llamado Alice. Luego crea un JWT para el usuario Alice ejecutando el siguiente comando reemplazando APP_ID por el ID de tu aplicación:

vonage jwt \ --app_id=APP_ID \ --subject=Alice \ --key_file=./phone_to_app_tutorial.key \ --acl='{ "paths": { "/*/users/**": {}, "/*/conversations/**": {}, "/*/sessions/**": {}, "/*/devices/**": {}, "/*/image/**": {}, "/*/media/**": {}, "/*/push/**": {}, "/*/knocking/**": {}, "/*/legs/**": {} } }'

Ejecutar el proyecto

En primer lugar, tendrá que preparar un dispositivo Android para ejecutar el proyecto. Abra el directorio android en Android Studio. El proyecto comenzará a cargar y descargar las dependencias, incluyendo el Client SDK, a través de Gradle Sync. Puedes ver las dependencias en el archivo build.gradle de la aplicación Android (android/app/build.gradle). En la barra de herramientas de la parte superior, busca el botón AVD Manager:

avd manager button

Si ya tienes configurado un emulador, ejecútalo. Si no, haga clic en el botón Crear dispositivo virtual y sigue las instrucciones del asistente. Asegúrate de crear un dispositivo con un nivel de API 29 o superior, tal y como requiere React Native.

emulator

Con todas las dependencias instaladas y el emulador en marcha, ya puedes ejecutar el proyecto. Iniciar Metro con npx react-native start. Una vez en marcha, abre una nueva ventana de terminal en el mismo directorio y ejecuta npx react-native run-android. Este comando construirá y ejecutará el proyecto Android para el emulador que has preparado. La aplicación consiste en una etiqueta que muestra el estado de la conexión, una etiqueta para mostrar el estado de la llamada y un botón de acción.

android app UI

Si abre la carpeta App.tsx puedes echar un vistazo a cómo se construye en la función render función:

render() {
    return (
      <SafeAreaView>
        <View style={styles.status}>
          <Text>
            {this.state.status}
          </Text>

          <View style={styles.container}>
            <Text style={styles.callState}>
              Call Status: {this.state.callState}
            </Text>
            <Pressable
              style={styles.button}
              onPress={this.state.callAction}>
              <Text style={styles.buttonText}>{this.state.button}</Text>
            </Pressable>
          </View>
        </View>
      </SafeAreaView>
    );
}

Si has utilizado React antes, esta sintaxis te resultará familiar. A Text para las etiquetas, un componente Pressable para el botón, junto con el CSS de estilo en la parte superior. Los tres componentes hacen uso de estado. Los datos de estado son parámetros para los componentes que cambiarán con el tiempo. El estado se inicializa en la parte superior de la clase App en el constructor con la información por defecto. Puedes pegar el JWT que creaste en el paso anterior y guardar el archivo (CMD + S). El simulador se recargará, y ahora cuando presiones el botón de login, el Client SDK se conectará. Ahora podrás realizar una llamada telefónica.

android app UI logged in

Cómo comunicarse con el código nativo

Permisos

Como se mencionó anteriormente, el proyecto utiliza la biblioteca react-native-permissions para facilitar el trabajo con permisos en distintas plataformas. En la función componentDidMount puede ver la extensión del código necesario en JavaScript para solicitar permisos, junto con la adición del permiso al archivo AndroidManifest.xml archivo :

if (Platform.OS === 'ios') {
  request(PERMISSIONS.IOS.MICROPHONE);
} else if (Platform.OS === 'android') {
  requestMultiple([PERMISSIONS.ANDROID.RECORD_AUDIO, PERMISSIONS.ANDROID.READ_PHONE_STATE]);
}

El Client SDK

El Client SDK es una dependencia nativa, por lo que tiene que haber una manera de comunicarse entre el código JavaScript en App.tsx y el código nativo de Android. Hay dos maneras de hacer esto dependiendo de la dirección de la información. NativeModules exponer clases nativas a JavaScript para permitir ejecutar código nativo. La NativeEventEmitter API permite al código nativo enviar señales al código JavaScript. Mira la función componentDidMount en la clase App . Puedes ver que el código JavaScript está escuchando dos señales diferentes, onStatusChange y onCallStateChangeque actualizarán la interfaz de usuario y la acción que realiza el botón.

eventEmitter.addListener('onStatusChange', (data) => {
...
});

eventEmitter.addListener('onCallStateChange', (data) => {
...
});

diagram showing the flow between javascript code and native code

Si abre el directorio android del proyecto verá una clase llamada EventEmitter (android/app/src/main/java/com/rnapptophone/EventEmitter.java). La clase EventEmitter tiene una función que envía las señales al código JavaScript.

public void sendEvent(String eventName, @Nullable WritableMap params) {
    this.context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
}

Estas funciones se llaman desde la clase ClientManager clase (android/app/src/main/java/com/rnapptophone/ClientManager.java). La clase ClientManager es una envoltura alrededor del Client SDK. Ambas clases extienden la clase ReactContextBaseJavaModule que requiere que ambas subclases devuelvan un nombre como String que se utiliza como NativeModules nombre. ClientManager.java hace uso de una anotación, ReactMethod. Esta anotación marca el método para ser expuesto a JavaScript. Por ejemplo, aquí está la función de inicio de sesión que habrías utilizado antes:

@ReactMethod
public void login(String jwt) {
    client.createSession(jwt, null, (error, sessionId) -> {
        if (error != null) {
            this.sendEvent("onStatusChange", "status", "Error");
        }
        if (sessionId != null) {
            this.sendEvent("onStatusChange", "status", "Connected");
        }
        return null;
    });
}

Así es como se llamaría en JavaScript:

ClientManager.login("ALICE_JWT")

¿Y ahora qué?

En este tutorial, hemos aprendido a crear una aplicación Android con el framework React Native. También hemos añadido una funcionalidad para realizar una llamada telefónica a un número de teléfono físico. Puedes encontrar el proyecto completo en GitHuby la versión iOS de este blog en learn.vonage.com.

A continuación encontrará otros tutoriales o documentación que hacen referencia al Client SDK:

Como siempre, si tienes alguna pregunta, consejo o idea que quieras compartir con la comunidad, no dudes en entrar en nuestro espacio de trabajo espacio de trabajo comunitario Slack. Me encantaría saber cómo te ha ido con este tutorial y cómo funciona tu proyecto.

Compartir:

https://a.storyblok.com/f/270183/400x400/19c02db2d3/abdul-ajetunmobi.png
Abdul AjetunmobiVonage Antiguo miembro del equipo

Abdul es desarrollador de Vonage. Ha trabajado en productos de consumo como ingeniero de iOS. En su tiempo libre, le gusta andar en bicicleta, escuchar música y asesorar a aquellos que están comenzando su viaje en la tecnología.